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=8219c1d686d146ba60c982658ab419e07b0d375b;hb=a1e1faa6915445e786f482170576b9c9d0f5d982;hp=93186779e60d580aa31d23a95585ce4886ff9f7b;hpb=27fb679643fab3ef9aa46d04c5ced2ea82cf60c2;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 93186779..8219c1d6 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 @@ -16,6 +16,8 @@ import org.simantics.g3d.math.MathTools; import org.simantics.g3d.property.annotations.GetPropertyValue; import org.simantics.g3d.scenegraph.G3DNode; import org.simantics.plant3d.scenegraph.IP3DNode; +import org.simantics.plant3d.scenegraph.Nozzle; +import org.simantics.plant3d.scenegraph.P3DRootNode; import org.simantics.plant3d.scenegraph.PipeRun; import org.simantics.plant3d.scenegraph.PipelineComponent; @@ -33,12 +35,12 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { private PipelineComponent component; private PointType type; - private boolean isFixed = true; - private boolean isRotate = false; - private boolean isReverse = false; - private boolean isDeletable = true; - private boolean isSizeChange = false; - private boolean isSub = false; + private boolean isFixed = true; // In-line: fixed-length Turn: fixed-angle + 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 public PipeControlPoint(PipelineComponent component) { this.component = component; @@ -83,7 +85,6 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return isFixed; } - public void setFixed(boolean fixed) { this.isFixed = fixed; } @@ -135,10 +136,20 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return type == PointType.INLINE; } + /** + * True for end components, if control point defines absolute position direction, which rules cannot modify. + * This is typical for nozzles. + * @return + */ public boolean isDirected() { return isFixed && isEnd(); } + /** + * True for end components, if control is opposite to directed, and rules can modify position and orientation. + * This is typical for caps, and other end components. + * @return + */ public boolean isNonDirected() { return !isFixed && isEnd(); } @@ -146,10 +157,35 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public boolean isVariableLength() { return !isFixed && isInline(); } + + /** + * Fixed length in-line component is such that piping rules cannot modify the length. + * @return + */ + public boolean isFixedLength() { + return isFixed && isInline(); + } public boolean isVariableAngle() { return !isFixed && isTurn(); } + + /** + * Fixed angle turn component is such that piping rules cannot modify the angle. + * @return + */ + public boolean isFixedAngle() { + return isFixed && isTurn(); + } + + /** + * Does the turn behave like fixed angle? + * For variable angle turns, the turn angle is defined by connected components, and without them, we must handle the component as fixed angle. + * @return + */ + public boolean asFixedAngle() { + return isTurn() && (isFixed || next == null || previous == null); + } public boolean isBranchEnd() { return isDeletable && isEnd(); @@ -626,7 +662,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public Vector3d getDirection(Direction direction) { if (isDirected()) return getDirectedControlPointDirection(); - if (isTurn() && isFixed()) { + if (isTurn() && asFixedAngle()) { if (direction == Direction.NEXT) { if (previous != null) { PipeControlPoint pcp = this; @@ -681,12 +717,12 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } else { if (previous == null) { if (!isDirected()) - throw new RuntimeException("Cannot calculate path leg direction for unconnected control point"); + throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + this); return getDirectedControlPointDirection(); } else { - if (isVariableAngle()) - throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point"); + if (isVariableAngle() && !asFixedAngle()) + throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + this); if (isInline()) { PipeControlPoint pcp = this; if (pcp.isDualSub()) { @@ -701,10 +737,10 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { Vector3d v = new Vector3d(); v.sub(getWorldPosition(),previous.getWorldPosition()); return v; - } else if (isTurn() && isFixed() && !_getReversed()) { + } else if (isTurn() && asFixedAngle() && !_getReversed()) { return getDirection(Direction.NEXT); } - throw new RuntimeException("Missing implementation"); + throw new RuntimeException("Missing implementation " + this); } } } else { @@ -718,13 +754,13 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } else { if (next == null) { if (!isDirected()) - throw new RuntimeException("Cannot calculate path leg direction for unconnected control point"); + throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + this); Vector3d v = getDirectedControlPointDirection(); v.negate(); return v; } else { - if (isVariableAngle()) - throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point"); + if (isVariableAngle() && !asFixedAngle()) + throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + this); if (isInline()) { PipeControlPoint pcp = this; if (pcp.isDualInline()) { @@ -741,10 +777,10 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { Vector3d v = new Vector3d(); v.sub(getWorldPosition(),next.getWorldPosition()); return v; - } else if (isTurn() && isFixed() && _getReversed()) { + } else if (isTurn() && asFixedAngle() && _getReversed()) { return getDirection(Direction.PREVIOUS); } - throw new RuntimeException("Missing implementation"); + throw new RuntimeException("Missing implementation " + this); } } } @@ -766,7 +802,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } public void getControlPointEnds(Tuple3d p1, Tuple3d p2) { - PipeControlPoint sub = isAxial() ? this : getSubPoint().get(0); + PipeControlPoint sub = isAxial() || isDirected() || isTurn() ? this : getSubPoint().get(0); Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition(); Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS); @@ -938,14 +974,22 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } } } - + public void _remove() { + _remove(true); + } + + 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 (getParentPoint() != null) { + getParentPoint()._remove(renconnect); + } PipeRun pipeRun = getPipeRun(); if (pipeRun == null) return; @@ -964,7 +1008,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return; } if (currentNext != null && currentPrev != null) { - boolean link = true; + boolean link = renconnect; if (currentNext.isBranchEnd()) { link = false; // currentNext.setPrevious(null); @@ -1112,19 +1156,92 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { additionalRemove.remove(); } + /** + * Removes control point and attempts to reconnect next/prev + * + * If this point is size change (PipeRuns are different on both sides), then reconnection cannot be made. + */ public void remove() { PipeControlPoint currentPrev = previous; PipeControlPoint currentNext = next; _remove(); try { if (currentNext != null) - PipingRules.requestUpdate(currentNext); + if (!currentNext.checkRemove()) + PipingRules.requestUpdate(currentNext); if (currentPrev != null) - PipingRules.requestUpdate(currentPrev); + if (!currentPrev.checkRemove()) + PipingRules.requestUpdate(currentPrev); } catch (Exception e) { e.printStackTrace(); } } + + + /** + * Removes control point without attempting to reconnect next/prev. + * This usually leads to creation of another PipeRun for the control points after this point. + */ + public void removeAndSplit() { + PipeControlPoint currentPrev = previous; + PipeControlPoint currentNext = next; + + if (next != null && previous != null) { + P3DRootNode root = (P3DRootNode)getPipelineComponent().getRootNode(); + PipeRun nextPipeRun = new PipeRun(); + nextPipeRun.setName(root.getUniqueName("PipeRun")); + root.addChild(nextPipeRun); + + PipeRun previousRun = previous.getPipeRun(); + nextPipeRun.setPipeDiameter(previousRun.getPipeDiameter()); + nextPipeRun.setTurnRadiusArray(previousRun.getTurnRadiusArray()); + + PipelineComponent n = next.getPipelineComponent(); + while (n != null) { + if (! (n instanceof Nozzle)) { + n.deattach(); + nextPipeRun.addChild(n); + } else + n.setPipeRun(nextPipeRun); + n = n.getNext(); + } + } + _remove(false); + try { + if (currentNext != null) + if (!currentNext.checkRemove()) + PipingRules.requestUpdate(currentNext); + if (currentPrev != null) + if (!currentPrev.checkRemove()) + PipingRules.requestUpdate(currentPrev); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * This is called when adjacent control point is removed. + * + * This call should remove the give point, if the point cannot exist alone. + * At the moment there is one such case: branch. + * + * @return + */ + protected boolean checkRemove() { + if (getParentPoint() != null) { + return getParentPoint().checkRemove(); + } else { + 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) { + remove(); + return true; + } + } + return false; + } + } private void checkRemove(PipeRun pipeRun) { Collection points = pipeRun.getControlPoints();