X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.plant3d%2Fsrc%2Forg%2Fsimantics%2Fplant3d%2Fscenegraph%2Fcontrolpoint%2FPipeControlPoint.java;h=c5d780c36b8d5f2dc3b4d0abf5642410509614f3;hb=a899aac9dd52296206f302a20a8e7bae2501cf2c;hp=8219c1d686d146ba60c982658ab419e07b0d375b;hpb=a1e1faa6915445e786f482170576b9c9d0f5d982;p=simantics%2F3d.git diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java index 8219c1d6..c5d780c3 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java @@ -36,12 +36,15 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { private PointType type; private boolean isFixed = true; // In-line: fixed-length Turn: fixed-angle + private boolean isMod = false; // Can user modify fixed value manually private boolean isRotate = false; // rotates around path leg axis. private boolean isReverse = false; // definition direction can be swapped private boolean isDeletable = true; // can be removed by rules private boolean isSizeChange = false; // changes size of the pipe. The next control point / component is on different PipeRun - private boolean isSub = false; // child point + private boolean isSub = false; // child point for offset / size change + private boolean disposed = false; + public PipeControlPoint(PipelineComponent component) { this.component = component; if (component.getPipeRun() != null) @@ -88,6 +91,15 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public void setFixed(boolean fixed) { this.isFixed = fixed; } + + @GetPropertyValue(name="Mod",tabId="Debug",value="mod") + public boolean isMod() { + return isMod; + } + + public void setMod(boolean isMod) { + this.isMod = isMod; + } @GetPropertyValue(name="Rotate",tabId="Debug",value="rotate") public boolean isRotate() { @@ -135,6 +147,11 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public boolean isInline() { return type == PointType.INLINE; } + + public boolean asPathLegEnd() { + // Ends and Turns are path leg ends by default, but also unconnected inline are path leg ends. + return isPathLegEnd() || getNext() == null || getPrevious() == null; + } /** * True for end components, if control point defines absolute position direction, which rules cannot modify. @@ -233,32 +250,70 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } public void setNext(PipeControlPoint next) { + if (isSub) { + getParentPoint().setNext(next); + return; + } + if (next != null && next.isDualSub()) + next = next.parent; + if (_setNext(next)) { + for (PipeControlPoint pcp : children) { + if (pcp.isSub) + pcp._setNext(next); + } + updateSubPoint(); + } + } + + public void setPrevious(PipeControlPoint prev) { + if (isSub) { + getParentPoint().setPrevious(prev); + return; + } + if (prev != null && prev.isDualInline()) + prev = prev.children.get(0); + if (_setPrevious(prev)) { + for (PipeControlPoint pcp : children) { + if (pcp.isSub) + pcp._setPrevious(prev); + } + updateSubPoint(); + } + } + + protected boolean _setNext(PipeControlPoint next) { if (isEnd() && previous != null && next != null) throw new RuntimeException("End control points are allowed to have only one connection"); if (next == this) throw new RuntimeException("Cannot connect to self"); if (this.next == next) - return; + return false; if (DEBUG) System.out.println(this + " next " + next); + if (next == null && isVariableAngle() && previous != null && !isRemoved()) { + convertVariableAngleToFixed(Direction.NEXT); + } this.next = next; if (component != null) { if (parent == null || isSub) component.setNext(next != null ? next.component : null); else component.setBranch0(next != null ? next.component : null); - updateSubPoint(); + } - + return true; } - public void setPrevious(PipeControlPoint previous) { + protected boolean _setPrevious(PipeControlPoint previous) { if (isEnd() && next != null && previous != null) throw new RuntimeException("End control points are allowed to have only one connection"); if (previous == this) throw new RuntimeException("Cannot connect to self"); if (this.previous == previous) - return; + return false; if (DEBUG) System.out.println(this + " previous " + previous); + if (previous == null && isVariableAngle() && next != null && !isRemoved()) { + convertVariableAngleToFixed(Direction.PREVIOUS); + } this.previous = previous; if (component != null) { if (parent == null || isSub) @@ -267,13 +322,40 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { component.setBranch0(previous != null ? previous.component : null); updateSubPoint(); } - + return true; + } + + private void convertVariableAngleToFixed(Direction direction) { + // We are removing reference, which transforms variable angle to fixed angle. + // Since fixed angle is defined differently, we need to calculate fixed angle parameters based on current data + // We need to calculate turnAngle and rotationAngle + Vector3d dirOut = getPathLegDirection(direction == Direction.NEXT ? Direction.NEXT : Direction.PREVIOUS); + Vector3d dir = getPathLegDirection(direction == Direction.NEXT ? Direction.PREVIOUS : Direction.NEXT); + dir.negate(); + dirOut.normalize(); + dir.normalize(); + double angle = dir.angle(dirOut); + //super._setNext(null); + if (direction == Direction.NEXT) + next = null; + else + previous = null; + setRotationAngle(0.0); + setReversed(direction == Direction.NEXT ? false : true); + Vector3d dirOutN = getPathLegDirection(direction == Direction.NEXT ? Direction.NEXT : Direction.PREVIOUS); + dirOutN.normalize(); + AxisAngle4d aa = new AxisAngle4d(); + if (MathTools.createRotation(dirOutN, dirOut, dir, aa)) { + setRotationAngle(aa.angle); + setTurnAngle(angle); + if (DEBUG) System.out.println("convertToFixed " + dir + " " + dirOut + " " +dirOutN + " " +angle + " "+ aa.angle); + } } public PipeControlPoint parent; public List children = new ArrayList(); - public List getSubPoint() { + public List getChildPoints() { return children; } @@ -304,7 +386,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { this.length = l; firePropertyChanged("length"); if (isDualInline()) - getSubPoint().get(0).setLength(l); + getDualSub().setLength(l); } @GetPropertyValue(name="Turn Angle",tabId="Debug",value="turnAngle") @@ -324,7 +406,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { @GetPropertyValue(name="Rotation Angle",tabId="Debug",value="rotationAngle") public Double getRotationAngle() { - return rotationAngle; + if (isRotate || asFixedAngle()) + return rotationAngle; + return null; } @GetPropertyValue(name="Reversed",tabId="Debug",value="reversed") @@ -445,26 +529,34 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return getControlPointOrientationQuat(dir, turnAxis, angle); } } + + public Quat4d getControlPointOrientationQuat(Vector3d dir, double angle, boolean reversed) { + if (turnAxis == null) { + if (dir.lengthSquared() > MathTools.NEAR_ZERO) + dir.normalize(); + Quat4d q = getControlPointOrientationQuat(dir, angle); + if (reversed) { + Quat4d q2 = new Quat4d(); + q2.set(new AxisAngle4d(MathTools.Y_AXIS, Math.PI)); + q.mulInverse(q2); + } + return q; + } else { + if (dir.lengthSquared() > MathTools.NEAR_ZERO) + dir.normalize(); + return getControlPointOrientationQuat(dir, turnAxis, angle); + } + } public Quat4d getControlPointOrientationQuat(double angle, boolean reversed) { if (turnAxis == null) { Vector3d dir = getPathLegDirection(Direction.NEXT); - if (dir.lengthSquared() > MathTools.NEAR_ZERO) - dir.normalize(); - Quat4d q = getControlPointOrientationQuat(dir, angle); - if (reversed) { - Quat4d q2 = new Quat4d(); - q2.set(new AxisAngle4d(MathTools.Y_AXIS, Math.PI)); - q.mulInverse(q2); - } - return q; + return getControlPointOrientationQuat(dir, angle, reversed); } else { Vector3d dir = getPathLegDirection(Direction.PREVIOUS); dir.negate(); - if (dir.lengthSquared() > MathTools.NEAR_ZERO) - dir.normalize(); - return getControlPointOrientationQuat(dir, turnAxis, angle); + return getControlPointOrientationQuat(dir, angle, reversed); } } @@ -545,7 +637,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { PipeControlPoint offsetCP = null; if (isOffset()) { - offsetCP = getSubPoint().get(0); + offsetCP = getDualSub(); } if (previousNext != null && previousNext == next) { if (previous.isDualInline()) { @@ -570,7 +662,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } if (next.isDualInline()) { - next.getSubPoint().get(0).setPrevious(this); + next.getDualSub().setPrevious(this); } } else if (previousPrevious != null && previousPrevious == next) { // control point were given in reverse order @@ -588,7 +680,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { offsetCP.setPrevious(next); } if (previous.isDualInline()) { - previous.getSubPoint().get(0).setPrevious(this); + previous.getDualSub().setPrevious(this); } this.setPrevious(next); next.setNext(this); @@ -620,7 +712,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { pcp.getParentPoint().setNext(this); } if (isDualInline()) { - getSubPoint().get(0).setPrevious(this); + getDualSub().setPrevious(this); } } else { // if direction is previous, user must have given sizechange @@ -630,7 +722,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { // we must link pcp to newCP's OffsetPoint PipeControlPoint nocp = null; if (isDualInline()) { - nocp = getSubPoint().get(0); + nocp = getDualSub(); nocp.setNext(pcp); } if (nocp == null) { @@ -640,7 +732,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } this.setNext(pcp); if (pcp.isDualInline()) { - PipeControlPoint ocp = pcp.getSubPoint().get(0); + PipeControlPoint ocp = pcp.getDualSub(); if (nocp == null) ocp.setPrevious(this); else @@ -709,7 +801,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { if (next != null) { PipeControlPoint pcp = this; if (pcp.isDualInline()) { - pcp = pcp.getSubPoint().get(0); + pcp = pcp.getDualSub(); } Vector3d v = new Vector3d(); v.sub(next.getWorldPosition(),pcp.getWorldPosition()); @@ -764,7 +856,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { if (isInline()) { PipeControlPoint pcp = this; if (pcp.isDualInline()) { - pcp = pcp.getSubPoint().get(0); + pcp = pcp.getDualSub(); } Vector3d v = new Vector3d(); v.sub(pcp.getWorldPosition(),next.getWorldPosition()); @@ -789,7 +881,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public void getInlineControlPointEnds(Tuple3d p1, Tuple3d p2) { assert (isInline()); - PipeControlPoint sub = isAxial() ? this : getSubPoint().get(0); + PipeControlPoint sub = isAxial() ? this : getDualSub(); Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition(); Vector3d dir = sub.getPathLegDirection(Direction.NEXT); @@ -802,7 +894,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } public void getControlPointEnds(Tuple3d p1, Tuple3d p2) { - PipeControlPoint sub = isAxial() || isDirected() || isTurn() ? this : getSubPoint().get(0); + PipeControlPoint sub = isAxial() || isDirected() || isTurn() ? this : getChildPoints().get(0); Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition(); Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS); @@ -823,7 +915,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } public void getEndDirections(Tuple3d v1, Tuple3d v2) { - PipeControlPoint sub = isAxial() ? this : getSubPoint().get(0); + PipeControlPoint sub = isAxial() ? this : getDualSub(); Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS); dir1.normalize(); @@ -978,24 +1070,34 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public void _remove() { _remove(true); } + + + public PipeControlPoint getDualSub() { + if (isDualInline()) + return getChildPoints().get(0); + else + throw new IllegalStateException("Current control point is not dual inline"); + } + public void _remove(boolean renconnect) { - if (component == null && next == null && previous == null) - return; - if (DEBUG) System.out.println(this + " Remove " + renconnect); - if (isDualInline() || isDualSub()) { - removeDualPoint(); - return; - } + if (disposed) + return; + + if (DEBUG) System.out.println(this + " Remove " + renconnect); + if (getParentPoint() != null) { getParentPoint()._remove(renconnect); + return; } PipeRun pipeRun = getPipeRun(); - if (pipeRun == null) - return; +// PipeRUn removal has been changed, so pipeRun may be null. +// if (pipeRun == null) +// return; PipeControlPoint additionalRemove = null; if (!PipingRules.isEnabled()) { + component = null; setPrevious(null); setNext(null); } else { @@ -1004,44 +1106,51 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { PipeControlPoint currentNext = next; if (currentNext == null && currentPrev == null) { removeComponent(); - pipeRun.remChild(this); + if (pipeRun != null) { + pipeRun.remChild(this); + checkRemove(pipeRun); + } return; } if (currentNext != null && currentPrev != null) { boolean link = renconnect; if (currentNext.isBranchEnd()) { link = false; - // currentNext.setPrevious(null); - // currentNext.setNext(null); currentNext.remove(); currentNext = null; setNext(null); } if (currentPrev.isBranchEnd()) { link = false; - // currentPrev.setPrevious(null); - // currentPrev.setNext(null); currentPrev.remove(); currentPrev = null; setPrevious(null); } - if (link && currentPrev.isDirected() && currentNext.isDirected()) { - link = false; + if (link) { + if (currentPrev.isDirected() && currentNext.isDirected()) + link = false; + else if (this.isDualInline()) { + link = false; + } else if (this.isDualSub()) { + throw new RuntimeException("_remove() is called for parent point, somehow got to child point. " + this); + } } if (currentNext == null) { // Nothing to do } else if (currentNext.isDualInline()) { PipeControlPoint sccp = currentNext; - PipeControlPoint ocp = sccp.getSubPoint().get(0); + PipeControlPoint ocp = currentNext.getDualSub(); if (ocp == null) { throw new RuntimeException("Removing PipeControlPoint " + this+ " structure damaged, no offset control point"); } if (link) { sccp.setPrevious(currentPrev); - ocp.setPrevious(currentPrev); + //ocp.setPrevious(currentPrev); + assert(ocp.getPrevious() == currentPrev); } else { sccp.setPrevious(null); - ocp.setPrevious(null); + //ocp.setPrevious(null); + assert(ocp.getPrevious() == null); } setNext(null); } else if (currentNext.isDualSub()) { @@ -1053,6 +1162,16 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { currentNext.setPrevious(null); } setNext(null); + } else if (isDualInline()) { + if (currentNext.previous != getDualSub()) { + throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged"); + } + if (link) { + currentNext.setPrevious(currentPrev); + } else { + currentNext.setPrevious(null); + } + setNext(null); } else { throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged"); } @@ -1062,15 +1181,17 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, previous control point is size change control point"); } else if (currentPrev.isDualSub()) { PipeControlPoint ocp = currentPrev; - PipeControlPoint sccp = ocp.getParentPoint(); + PipeControlPoint sccp = currentPrev.getParentPoint(); if (sccp == null) throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, no size change control point"); if (link) { - ocp.setNext(currentNext); + //ocp.setNext(currentNext); sccp.setNext(currentNext); + assert(ocp.getNext() == currentNext); } else { - ocp.setNext(null); + //ocp.setNext(null); sccp.setNext(null); + assert(ocp.getNext() == null); } setPrevious(null); } else if (currentPrev.next == this) { @@ -1104,36 +1225,42 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } else { // FIXME : pipe run must be split into two parts, since the control point structure is no more continuous. } - } else if (next != null) { - if (next.isDualInline()) { - PipeControlPoint sccp = next; - PipeControlPoint ocp = sccp.getSubPoint().get(0); + } else if (currentNext != null) { + if (currentNext.isDualInline()) { + PipeControlPoint sccp = currentNext; + PipeControlPoint ocp = currentNext.getDualSub(); if (ocp == null) { throw new RuntimeException("Removing PipeControlPoint " + this+ " structure damaged, no offset control point"); } sccp.setPrevious(null); - ocp.setPrevious(null); - } else if (next.isDualSub()) { + assert(ocp.getPrevious() == null); + //ocp.setPrevious(null); + } else if (currentNext.isDualSub()) { throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, next control point is offset control point"); - } else if (next.previous == this) { - next.setPrevious(null); + } else if (currentNext.previous == this) { + currentNext.setPrevious(null); + } else if (isDualInline()) { + if (currentNext.previous != getDualSub()) { + throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged"); + } + currentNext.setPrevious(null); } else { throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged"); } setNext(null); } else { //(previous != null) - if(previous.isDualInline()) { + if(currentPrev.isDualInline()) { throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, previous control point is size change control point"); - } else if (previous.isDualSub()) { - PipeControlPoint ocp = previous; - PipeControlPoint sccp = ocp.getParentPoint(); + } else if (currentPrev.isDualSub()) { + PipeControlPoint ocp = currentPrev; + PipeControlPoint sccp = currentPrev.getParentPoint(); if (sccp == null) { throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, no size change control point"); } - ocp.setNext(null); sccp.setNext(null); - } else if (previous.next == this) { - previous.setNext(null); + assert(ocp.getNext() == null); + } else if (currentPrev.next == this) { + currentPrev.setNext(null); } else { throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged"); } @@ -1148,12 +1275,15 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } removeComponent(); - pipeRun.remChild(this); - checkRemove(pipeRun); - if (PipingRules.isEnabled() && pipeRun.getParent() != null && pipeRun.getControlPoints().size() > 0) - PipingRules.validate(pipeRun); + if (pipeRun != null) { + pipeRun.remChild(this); + checkRemove(pipeRun); + if (PipingRules.isEnabled() && pipeRun.getParent() != null && pipeRun.getControlPoints().size() > 0) + PipingRules.validate(pipeRun); + } if (additionalRemove != null) additionalRemove.remove(); + disposed = true; } /** @@ -1198,6 +1328,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { PipelineComponent n = next.getPipelineComponent(); while (n != null) { + if (n.getPipeRun() != previousRun) + break; if (! (n instanceof Nozzle)) { n.deattach(); nextPipeRun.addChild(n); @@ -1234,76 +1366,55 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { if (getPipelineComponent() == null) return true; // already removed if (getPipelineComponent().getType().equals("Plant3D.URIs.Builtin_BranchSplitComponent")) { - if (getSubPoint().get(0).getNext() == null && getSubPoint().get(0).getPrevious() == null) { + if (getChildPoints().get(0).getNext() == null && getChildPoints().get(0).getPrevious() == null) { remove(); return true; } } - return false; + return checkRemove(getPipeRun()); } } - private void checkRemove(PipeRun pipeRun) { + private boolean checkRemove(PipeRun pipeRun) { + if (pipeRun == null) + return false; Collection points = pipeRun.getControlPoints(); if (points.size() == 0) { pipeRun.remove(); + return true; } else if (points.size() == 1) { PipeControlPoint pcp = points.iterator().next(); - if (pcp.isDeletable()) - pcp._remove(); - } - } - - private void removeDualPoint() { - if (previous != null) - previous.setNext(null); - if (next != null) - next.setPrevious(null); - PipeControlPoint ocp; - PipeControlPoint sccp; - if (isDualInline()) { - sccp = this; - ocp = getSubPoint().get(0); - } else { - ocp = this; - sccp = getParentPoint(); + if (pcp.isDeletable() && pcp.getNext() == null && pcp.getPrevious() == null) { + pcp._remove(); // This call will recursively call also this method... + return true; + } + } else if (points.size() == 2) { + } - PipeRun p1 = ocp.getPipeRun(); - PipeRun p2 = sccp.getPipeRun(); - - ocp.removeComponent(); - sccp.removeComponent(); - - if (p1 != null) - p1.remChild(ocp); - if (p2 != null) - p2.remChild(sccp); - - // TODO : now we assume that this is size change, and we do - if (ocp.next != null) - ocp.next.setPrevious(null); - if (ocp.previous != null) - ocp.previous.setNext(null); - if (sccp.next != null) - sccp.next.setPrevious(null); - if (sccp.previous != null) - sccp.previous.setNext(null); - ocp.setNext(null); - ocp.setPrevious(null); - sccp.setNext(null); - sccp.setPrevious(null); - - if (p1 != null) - checkRemove(p1); - if (p2 != null) - checkRemove(p2); + return false; } private void removeSubPoints() { for (PipeControlPoint p : children) { - // TODO : this may affect delete routine, since classification of the point changes. p.parent = null; - p._remove(); + p.component = null; + //p._remove(); + PipeControlPoint currentNext = p.getNext(); + PipeControlPoint currentPrev = p.getPrevious(); + p._setNext(null); + p._setPrevious(null); + PipeRun run = p.getPipeRun(); + if (run != null) { + run.remChild(p); + checkRemove(run); + } + if (currentNext != null) + if (!currentNext.checkRemove()) + PipingRules.requestUpdate(currentNext); + if (currentPrev != null) + if (!currentPrev.checkRemove()) + PipingRules.requestUpdate(currentPrev); + } children.clear(); } @@ -1311,6 +1422,10 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { private void removeParentPoint() { throw new RuntimeException("Child points cannot be removed directly"); } + + public boolean isRemoved() { + return component == null; + } private void removeComponent() { if (component == null) @@ -1376,20 +1491,20 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { private void updateSubPoint() { if (isOffset()) { if (next == null && previous == null) { - for (PipeControlPoint sub : getSubPoint()) { + for (PipeControlPoint sub : getChildPoints()) { sub.setWorldPosition(getWorldPosition()); sub.setWorldOrientation(getWorldOrientation()); } return; } - for (PipeControlPoint sub : getSubPoint()) { + for (PipeControlPoint sub : getChildPoints()) { Vector3d wp = getWorldPosition(); wp.add(getSizeChangeOffsetVector()); sub.setWorldPosition(wp); sub.setWorldOrientation(getWorldOrientation()); } } else { - for (PipeControlPoint sub : getSubPoint()) { + for (PipeControlPoint sub : getChildPoints()) { sub.setWorldPosition(getWorldPosition()); sub.setWorldOrientation(getWorldOrientation()); }