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=cd4f407b22b6f65e3e80a91c2bc4cc5fae2df9a6;hb=d005c67f1706391f2eb9dfd6cfd9489a4a7ec60d;hp=b67562459016b3dddcb1ba730a99a1a5bb016beb;hpb=5c3ab621af42b395803bfab9e6b72244dc2db633;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 b6756245..cd4f407b 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 @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Objects; import javax.vecmath.AxisAngle4d; import javax.vecmath.Matrix3d; @@ -15,6 +16,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.INode; import org.simantics.plant3d.scenegraph.IP3DNode; import org.simantics.plant3d.scenegraph.Nozzle; import org.simantics.plant3d.scenegraph.P3DRootNode; @@ -378,9 +380,10 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } public void setLength(double l) { - if (Double.isInfinite(l) || Double.isNaN(l)) { + if (this.length == l) + return; + if (Double.isInfinite(l) || Double.isNaN(l)) return; - } if (Math.abs(this.length-l) < MathTools.NEAR_ZERO) return; this.length = l; @@ -428,6 +431,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } if (this.turnAngle != null && Math.abs(this.turnAngle-turnAngle) < MathTools.NEAR_ZERO) return; + if (Objects.equals(this.turnAngle, turnAngle)) + return; this.turnAngle = turnAngle; firePropertyChanged("turnAngle"); } @@ -445,6 +450,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } if (this.offset != null && Math.abs(this.offset-offset) < MathTools.NEAR_ZERO) return; + if (Objects.equals(this.offset, offset)) + return; this.offset = offset; firePropertyChanged("offset"); } @@ -455,11 +462,15 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } if (this.rotationAngle != null && Math.abs(this.rotationAngle-rotationAngle) < MathTools.NEAR_ZERO) return; + if (Objects.equals(this.rotationAngle, rotationAngle)) + return; this.rotationAngle = rotationAngle; firePropertyChanged("rotationAngle"); } public void setReversed(Boolean reversed) { + if (this.reversed == reversed) + return; this.reversed = reversed; firePropertyChanged("reversed"); } @@ -514,14 +525,42 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return type.name(); } - public Quat4d getControlPointOrientationQuat(double angle) { + public Vector3d getPathLegEndpointVector() { + PipeControlPoint a = findPreviousEnd(); + PipeControlPoint b = findNextEnd(); + + if (a == null || b == null) { + return getPathLegDirection(); + } + + Vector3d p1 = a.getWorldPosition(); + Vector3d p2 = b.getWorldPosition(); + p2.sub(p1); + double l = p2.length(); + if (l != 0.0) { + p2.scale(1.0 / l); + return p2; + } + else { + return getPathLegDirection(); + } + } + public Vector3d getPathLegDirection() { if (turnAxis == null) { - Vector3d dir = getPathLegDirection(Direction.NEXT); - return getControlPointOrientationQuat(dir, angle); + return getPathLegDirection(Direction.NEXT); } else { Vector3d dir = getPathLegDirection(Direction.PREVIOUS); if (dir != null) dir.negate(); + return dir; + } + } + + public Quat4d getControlPointOrientationQuat(double angle) { + Vector3d dir = getPathLegDirection(); + if (turnAxis == null) { + return getControlPointOrientationQuat(dir, angle); + } else { return getControlPointOrientationQuat(dir, turnAxis, angle); } } @@ -545,34 +584,37 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } public Quat4d getControlPointOrientationQuat(double angle, boolean reversed) { - - if (turnAxis == null) { - Vector3d dir = getPathLegDirection(Direction.NEXT); - return getControlPointOrientationQuat(dir, angle, reversed); - } else { - Vector3d dir = getPathLegDirection(Direction.PREVIOUS); - dir.negate(); - return getControlPointOrientationQuat(dir, angle, reversed); - } + Vector3d dir = getPathLegDirection(); + return getControlPointOrientationQuat(dir, angle, reversed); } - - - public static Quat4d getControlPointOrientationQuat(Vector3d dir, double angle) { + public Quat4d getControlPointOrientationQuat(Vector3d dir, double angle) { if (dir == null || dir.lengthSquared() < MathTools.NEAR_ZERO) return MathTools.getIdentityQuat(); - - Vector3d up = new Vector3d(0.0, 1.0, 0.0); - double a = up.angle(dir); + final P3DRootNode root = getRoot(); + Vector3d up = root != null ? new Vector3d(root.getUpVector()) : new Vector3d(0.0, 1.0, 0.0); + final Vector3d legDir = getPathLegEndpointVector(); + double a = up.angle(legDir); if (a < 0.1 || (Math.PI - a) < 0.1) { - up.set(1.0, 0.0, 0.0); + // Rotate components + up.set(up.getY(), up.getZ(), up.getX()); } - + + // Project up vector into a normal of the leg direction before applying to 'dir' + MathTools.mad(up, legDir, -legDir.dot(up)/legDir.lengthSquared()); + up.normalize(); return getControlPointOrientationQuat(dir, up, angle); } + public P3DRootNode getRoot() { + INode n = getParent(); + while (n != null && !(n instanceof P3DRootNode)) + n = n.getParent(); + return (P3DRootNode) n; + } + public static Quat4d getControlPointOrientationQuat(Vector3d dir, Vector3d up, double angle) { if (dir == null || dir.lengthSquared() < MathTools.NEAR_ZERO) return MathTools.getIdentityQuat(); @@ -583,7 +625,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { Vector3d right = new Vector3d(); - + + up = new Vector3d(up); right.cross(dir, up); up.cross(right, dir); right.normalize(); @@ -707,9 +750,6 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { if (pcp.isDualSub()) { pcp.getParentPoint().setNext(this); } - if (isDualInline()) { - getDualSub().setPrevious(this); - } } else { // if direction is previous, user must have given sizechange if (pcp.isDualSub()) @@ -748,9 +788,15 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } /** - * Returns direction vector. + * Returns direction vector pointing towards an adjacent component for + * directed control points or turn control points with one open end. * - * For directed control points, always returns outwards pointing vector. + * Always returns an outwards pointing vector. + * + * For any other type of component, the return value is null. + * + * For turn components this only return a non-null value for the unconnected + * end of the component. * * @param direction * @return normalized vector, or null @@ -794,6 +840,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { Vector3d offset = new Vector3d(); MathTools.rotate(q2, v, offset); MathTools.rotate(q, offset, dir); + dir.negate(); dir.normalize(); return dir; } @@ -812,107 +859,70 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { */ public Vector3d getPathLegDirection(Direction direction) { if (direction == Direction.NEXT) { - if (next != null) { - PipeControlPoint pcp = this; - if (pcp.isDualInline()) { - 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) { - if (!isDirected()) - throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + this); - return getDirectedControlPointDirection(); + return getPathLegDirectionNext(); + } else { + return getPathLegDirectionPrevious(); + } + } - } else { - 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()) { - pcp = pcp.getParentPoint(); - } - 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); - } - throw new RuntimeException("Missing implementation " + this); - } - } + public Vector3d getPathLegDirectionPrevious() { + if (previous != null) { + PipeControlPoint pcp = this; + if (isDualSub()) + 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 (isDirected()) { + Vector3d v = getDirectedControlPointDirection(); + v.negate(); + return v; + } else if (next == null) { + throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + this); + } else if (isVariableAngle() && !asFixedAngle()) { + throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + this); + } else if (isInline() || isEnd()) { + Vector3d v = getPathLegDirectionNext(); + if (v != null) v.negate(); + return v; + } else if (isTurn() && asFixedAngle() && _getReversed()) { + return getDirection(Direction.PREVIOUS); } else { - if (previous != null) { - PipeControlPoint pcp = this; - if (isDualSub()) - 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) { - if (!isDirected()) - throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + this); - Vector3d v = getDirectedControlPointDirection(); - v.negate(); - return v; - } else { - 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()) { - 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(); - v.negate(); - return v; - } 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); - } - throw new RuntimeException("Missing implementation " + this); - } + throw new RuntimeException("Missing implementation " + this); + } + } + + public Vector3d getPathLegDirectionNext() { + if (next != null) { + PipeControlPoint pcp = this; + if (pcp.isDualInline()) { + 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 (isDirected()) { + return getDirectedControlPointDirection(); + } else if (previous == null) { + throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + this); + } else if (isVariableAngle() && !asFixedAngle()) { + throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + this); + } else if (isInline() || isEnd()) { + Vector3d v = getPathLegDirectionPrevious(); + if (v != null) v.negate(); + return v; + } else if (isTurn() && asFixedAngle() && !_getReversed()) { + return getDirection(Direction.NEXT); + } else { + throw new RuntimeException("Missing implementation " + this); } } @@ -1212,9 +1222,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { if (link) { if (currentPrev.isDirected() && currentNext.isDirected()) link = false; - else if (this.isDualInline()) { - link = false; - } else if (this.isDualSub()) { + else if (this.isDualSub()) { throw new RuntimeException("_remove() is called for parent point, somehow got to child point. " + this); } } @@ -1407,6 +1415,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { PipeRun previousRun = previous.getPipeRun(); nextPipeRun.setPipeDiameter(previousRun.getPipeDiameter()); + nextPipeRun.setPipeThickness(previousRun.getPipeThickness()); nextPipeRun.setTurnRadiusArray(previousRun.getTurnRadiusArray()); PipelineComponent n = next.getPipelineComponent(); @@ -1572,7 +1581,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { component._setWorldPosition(getWorldPosition()); updateSubPoint(); } - + private void updateSubPoint() { if (isOffset()) { if (next == null && previous == null) { @@ -1609,6 +1618,21 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { updateSubPoint(); } + public void orientToDirection(Vector3d dir) { + Double angleO = getRotationAngle(); + double angle = 0.0; + if (angleO != null) + angle = angleO; + boolean reversed = _getReversed(); + Quat4d q = null; + if (dir != null) { + q = getControlPointOrientationQuat(dir, angle, reversed); + } else { + q = getControlPointOrientationQuat(angle, reversed); + } + setWorldOrientation(q); + } + @Override public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode());