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=eec074a68b88693812f7c8f686a08036ea72a548;hpb=8a0cd33ffd13d79465f8a7b54ae19945599a99bf;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 eec074a6..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; @@ -518,14 +519,10 @@ 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); } } @@ -563,7 +560,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { 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(); @@ -578,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); @@ -620,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) { @@ -925,9 +922,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { 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); @@ -939,12 +935,16 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { PipeControlPoint sub = isAxial() || isDirected() || isTurn() ? this : getChildPoints().get(0); Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition(); - Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS); - Vector3d dir2 = sub.getPathLegDirection(Direction.NEXT); + 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); } @@ -954,20 +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 : getDualSub(); Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS); Vector3d dir2 = sub.getPathLegDirection(Direction.NEXT); - 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); @@ -981,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); @@ -990,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; @@ -998,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; }