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=796b5de99a5e5f6f289b382add6fed414074cab1;hb=6f4226494d2b90e24563763ed2805fcca13de11d;hp=eae8ec33220aacc91b27873cf86e9eef4d7110a9;hpb=b35befd422dd71c2358bcc3b198f38d52ac0b966;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 eae8ec33..796b5de9 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; @@ -43,6 +44,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { private boolean isSizeChange = false; // changes size of the pipe. The next control point / component is on different PipeRun 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) @@ -145,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. @@ -324,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) @@ -341,6 +349,7 @@ 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); } } @@ -521,26 +530,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); } } @@ -604,8 +621,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) { @@ -735,6 +752,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(); @@ -755,6 +780,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 { @@ -773,6 +799,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; } } @@ -780,6 +807,14 @@ 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) { @@ -789,6 +824,10 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } 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) { @@ -806,12 +845,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); @@ -826,6 +873,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) { @@ -844,6 +895,10 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } 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(); @@ -852,6 +907,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); @@ -882,9 +941,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition(); Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS); - dir1.normalize(); Vector3d dir2 = sub.getPathLegDirection(Direction.NEXT); - dir2.normalize(); if (isInline()) { dir1.scale(length * 0.5); dir2.scale(length * 0.5); @@ -902,9 +959,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { 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); } @@ -1065,17 +1120,19 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public void _remove(boolean renconnect) { - if (component == null && next == null && previous == null) - return; - if (DEBUG) System.out.println(this + " Remove " + renconnect); + 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()) { @@ -1088,8 +1145,10 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { PipeControlPoint currentNext = next; if (currentNext == null && currentPrev == null) { removeComponent(); - pipeRun.remChild(this); - checkRemove(pipeRun); + if (pipeRun != null) { + pipeRun.remChild(this); + checkRemove(pipeRun); + } return; } if (currentNext != null && currentPrev != null) { @@ -1208,7 +1267,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } else if (currentNext != null) { if (currentNext.isDualInline()) { PipeControlPoint sccp = currentNext; - PipeControlPoint ocp = getDualSub(); + PipeControlPoint ocp = currentNext.getDualSub(); if (ocp == null) { throw new RuntimeException("Removing PipeControlPoint " + this+ " structure damaged, no offset control point"); } @@ -1255,12 +1314,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; } /** @@ -1305,6 +1367,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); @@ -1351,6 +1415,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } private boolean checkRemove(PipeRun pipeRun) { + if (pipeRun == null) + return false; Collection points = pipeRun.getControlPoints(); if (points.size() == 0) { pipeRun.remove(); @@ -1443,6 +1509,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());