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=e240dc585426b972dd93a42174ce99e24f4403c1;hb=0702c03a4c063b77af27ea492fafdd05c426bb62;hp=086bdb2b5d408de5fcc8109dba50eae6ea8ca452;hpb=eb67906ff85a83b2f71b823110e5c3d12da8bfc2;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 086bdb2b..e240dc58 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 @@ -15,6 +15,7 @@ import javax.vecmath.Vector3d; import org.simantics.g3d.math.MathTools; import org.simantics.g3d.property.annotations.GetPropertyValue; import org.simantics.g3d.scenegraph.G3DNode; +import org.simantics.g3d.scenegraph.base.ParentNode; import org.simantics.plant3d.scenegraph.IP3DNode; import org.simantics.plant3d.scenegraph.Nozzle; import org.simantics.plant3d.scenegraph.P3DRootNode; @@ -36,12 +37,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 +92,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 +148,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,12 +251,44 @@ 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); @@ -249,17 +299,18 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { 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); @@ -272,6 +323,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { component.setBranch0(previous != null ? previous.component : null); updateSubPoint(); } + return true; } private void convertVariableAngleToFixed(Direction direction) { @@ -280,9 +332,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { // 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); + if (dir == null || dirOut == null) + return; dir.negate(); - dirOut.normalize(); - dir.normalize(); double angle = dir.angle(dirOut); //super._setNext(null); if (direction == Direction.NEXT) @@ -297,13 +349,14 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { 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; } @@ -334,7 +387,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") @@ -354,7 +407,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { @GetPropertyValue(name="Rotation Angle",tabId="Debug",value="rotationAngle") public Double getRotationAngle() { - if (asFixedAngle()) + if (isRotate || asFixedAngle()) return rotationAngle; return null; } @@ -466,44 +519,48 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { if (turnAxis == null) { Vector3d dir = getPathLegDirection(Direction.NEXT); - if (dir.lengthSquared() > MathTools.NEAR_ZERO) - dir.normalize(); return getControlPointOrientationQuat(dir, angle); } else { Vector3d dir = getPathLegDirection(Direction.PREVIOUS); - dir.negate(); - if (dir.lengthSquared() > MathTools.NEAR_ZERO) - dir.normalize(); + if (dir != null) dir.negate(); 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); } } public static Quat4d getControlPointOrientationQuat(Vector3d dir, double angle) { - if (dir.lengthSquared() < MathTools.NEAR_ZERO) + if (dir == null || dir.lengthSquared() < MathTools.NEAR_ZERO) return MathTools.getIdentityQuat(); @@ -518,7 +575,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } public static Quat4d getControlPointOrientationQuat(Vector3d dir, Vector3d up, double angle) { - if (dir.lengthSquared() < MathTools.NEAR_ZERO) + if (dir == null || dir.lengthSquared() < MathTools.NEAR_ZERO) return MathTools.getIdentityQuat(); final Vector3d front = new Vector3d(1.0,0.0,0.0); @@ -560,8 +617,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { if (isDualSub()) throw new RuntimeException("Dual sub points cannot be inserted."); // size change control point cannot be inserted this way, because it ends PipeRun - if (isSizeChange()) - throw new RuntimeException("Size change points cannot be inserted."); +// if (isSizeChange()) +// throw new RuntimeException("Size change points cannot be inserted."); PipeRun piperun = previous.getPipeRun(); // and just to make sure that control point structure is not corrupted if (getPipeRun() != null) { @@ -577,7 +634,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()) { @@ -602,7 +659,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 @@ -620,7 +677,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); @@ -652,7 +709,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 @@ -662,7 +719,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) { @@ -672,7 +729,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 @@ -691,6 +748,14 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return dir; } + /** + * Returns direction vector. + * + * For directed control points, always returns outwards pointing vector. + * + * @param direction + * @return normalized vector, or null + */ public Vector3d getDirection(Direction direction) { if (isDirected()) return getDirectedControlPointDirection(); @@ -711,6 +776,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { Vector3d offset = new Vector3d(); MathTools.rotate(q2, v, offset); MathTools.rotate(q, offset, dir); + dir.normalize(); return dir; } } else { @@ -729,6 +795,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { Vector3d offset = new Vector3d(); MathTools.rotate(q2, v, offset); MathTools.rotate(q, offset, dir); + dir.normalize(); return dir; } } @@ -736,15 +803,27 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return null; } + /** + * Returns path leg direction of the control point. + * + * This method differs from getDirection by also returning inward pointing vectors for directed control points. + * + * @param direction + * @return + */ public Vector3d getPathLegDirection(Direction direction) { if (direction == Direction.NEXT) { 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()); + if (v.lengthSquared() > MathTools.NEAR_ZERO) + v.normalize(); + else + return null; return v; } else { if (previous == null) { @@ -762,12 +841,20 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } Vector3d v = new Vector3d(); v.sub(pcp.getWorldPosition(),previous.getWorldPosition()); + if (v.lengthSquared() > MathTools.NEAR_ZERO) + v.normalize(); + else + return null; return v; } else if (isDirected()) { return getDirectedControlPointDirection(); } else if (isEnd()) { Vector3d v = new Vector3d(); v.sub(getWorldPosition(),previous.getWorldPosition()); + if (v.lengthSquared() > MathTools.NEAR_ZERO) + v.normalize(); + else + return null; return v; } else if (isTurn() && asFixedAngle() && !_getReversed()) { return getDirection(Direction.NEXT); @@ -782,6 +869,10 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { pcp = getParentPoint(); Vector3d v = new Vector3d(); v.sub(previous.getWorldPosition(),pcp.getWorldPosition()); + if (v.lengthSquared() > MathTools.NEAR_ZERO) + v.normalize(); + else + return null; return v; } else { if (next == null) { @@ -796,10 +887,14 @@ 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()); + if (v.lengthSquared() > MathTools.NEAR_ZERO) + v.normalize(); + else + return null; return v; } else if (isDirected()) { Vector3d v = getDirectedControlPointDirection(); @@ -808,6 +903,10 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } else if (isEnd()) { Vector3d v = new Vector3d(); v.sub(getWorldPosition(),next.getWorldPosition()); + if (v.lengthSquared() > MathTools.NEAR_ZERO) + v.normalize(); + else + return null; return v; } else if (isTurn() && asFixedAngle() && _getReversed()) { return getDirection(Direction.PREVIOUS); @@ -821,11 +920,10 @@ 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); + Vector3d dir = sub.getInlineDir(); - dir.normalize(); dir.scale(length * 0.5); p1.set(pos); p2.set(pos2); @@ -834,17 +932,19 @@ 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); - dir1.normalize(); - Vector3d dir2 = sub.getPathLegDirection(Direction.NEXT); - dir2.normalize(); + Vector3d dir1; + Vector3d dir2; if (isInline()) { - dir1.scale(length * 0.5); + dir2 = getInlineDir(); dir2.scale(length * 0.5); + dir1 = new Vector3d(dir2); + dir1.negate(); } else { + dir1 = getPathLegDirection(Direction.PREVIOUS); + dir2 = sub.getPathLegDirection(Direction.NEXT); dir1.scale(length); dir2.scale(length); } @@ -854,22 +954,34 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { p2.add(dir2); } + /** + * Get both path leg directions, with (0,0,0) if no connection exists. The returned vectors are not normalized. + * + * @param v1 Set to the direction towards the previous control point on output + * @param v2 Set to the direction towards the next control point on output + */ 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(); Vector3d dir2 = sub.getPathLegDirection(Direction.NEXT); - dir2.normalize(); - v1.set(dir1); - v2.set(dir2); + + if (dir1 != null) + v1.set(dir1); + else + v1.set(0,0,0); + + if (dir2 != null) + v2.set(dir2); + else + v2.set(0,0,0); } public void getInlineControlPointEnds(Tuple3d p1, Tuple3d p2, Vector3d dir) { assert (isInline()); Vector3d pos = getWorldPosition(); - dir.set(getPathLegDirection(Direction.NEXT)); + dir.set(getInlineDir()); dir.normalize(); dir.scale(length * 0.5); p1.set(pos); @@ -883,7 +995,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { Vector3d pos = getWorldPosition(); center.set(pos); - dir.set(getPathLegDirection(Direction.NEXT)); + dir.set(getInlineDir()); dir.normalize(); dir.scale(length * 0.5); p1.set(pos); @@ -892,6 +1004,22 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { p2.add(dir); } + public Vector3d getInlineDir() { + Vector3d dir = getPathLegDirection(Direction.NEXT); + if (dir == null) { + dir = getPathLegDirection(Direction.PREVIOUS); + if (dir != null) { + // Use reverse direction + dir.scale(-1.0); + } else { + // Control point is not connected at all, use current orientation + dir = new Vector3d(1,0,0); + MathTools.rotate(getWorldOrientation(), dir, dir); + } + } + return dir; + } + public double getInlineLength() { if (type == PointType.TURN) return length; @@ -900,22 +1028,27 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return 0; } + /** + * Return the position indicated by the argument. If the indicated direction is not connected, the + * control point's wolrd position is returned instead. + * + * @param type A selector for the position to be returned + * @return The selected position + */ public Vector3d getRealPosition(PositionType type) { Vector3d pos = getWorldPosition(); switch (type) { case NEXT: { - Vector3d dir = getPathLegDirection(Direction.NEXT); + Vector3d dir = getInlineDir(); double length = getInlineLength(); - dir.normalize(); dir.scale(length); pos.add(dir); break; } case PREVIOUS: { - Vector3d dir = getPathLegDirection(Direction.PREVIOUS); + Vector3d dir = getInlineDir(); double length = getInlineLength(); - dir.normalize(); - dir.scale(length); + dir.scale(-length); pos.add(dir); break; } @@ -1010,21 +1143,30 @@ 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()) { @@ -1037,44 +1179,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()) { @@ -1086,6 +1235,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"); } @@ -1095,15 +1254,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) { @@ -1137,36 +1298,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"); } @@ -1181,12 +1348,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; } /** @@ -1231,6 +1401,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); @@ -1267,76 +1439,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(); } @@ -1392,6 +1543,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public void setOrientation(Quat4d orientation) { if (MathTools.equals(orientation, getOrientation())) return; + if (getPipelineComponent() != null && (getPipelineComponent() instanceof Nozzle)) + System.out.println(); super.setOrientation(orientation); if (getParentPoint() == null && component != null) component._setWorldOrientation(getWorldOrientation()); @@ -1413,20 +1566,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()); }