]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java
Support for fixed turn components
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / scenegraph / controlpoint / PipeControlPoint.java
index b14b298bcf26d0060ea91ec09521f740fc596b45..22c58ddb160be1a1f43303b34e63d1dd3614bc17 100644 (file)
@@ -32,6 +32,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
        private Type type;
        private boolean fixed = true;
        private boolean rotate = false;
+       private boolean reverse = false;
        private boolean deletable = true;
        private boolean sub = false;
        
@@ -88,11 +89,19 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                return rotate;
        }
        
-       
        public void setRotate(boolean rotate) {
                this.rotate = rotate;
        }
        
+       @GetPropertyValue(name="Reverse",tabId="Debug",value="reverse")
+       public boolean isReverse() {
+               return reverse;
+       }
+       
+       public void setReverse(boolean reverse) {
+               this.reverse = reverse;
+       }
+       
        public void setSub(boolean sub) {
                this.sub = sub;
        }
@@ -230,6 +239,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
 
        private Double offset;
        private Double rotationAngle;
+       private Boolean reversed;
        
        @GetPropertyValue(name="Length",tabId="Debug",value="length")
        public double getLength() {
@@ -268,6 +278,17 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                return rotationAngle;
        }
        
+       @GetPropertyValue(name="Reversed",tabId="Debug",value="reversed")
+       public Boolean getReversed() {
+               return reversed;
+       }
+       
+       public boolean _getReversed() {
+           if (reversed == null)
+               return false;
+        return reversed;
+    }
+       
        public void setTurnAngle(Double turnAngle) {
                if (Double.isInfinite(turnAngle) || Double.isNaN(turnAngle)) {
                        return;
@@ -303,6 +324,11 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                firePropertyChanged("rotationAngle");
        }
        
+       public void setReversed(Boolean reversed) {
+               this.reversed = reversed;
+               firePropertyChanged("reversed");
+       }
+       
        public Vector3d getSizeChangeOffsetVector(Vector3d dir) {
                Quat4d q;
                if (rotationAngle == null)
@@ -353,7 +379,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                return type.name();
        }
        
-        public Quat4d getControlPointOrientationQuat(double angle) {
+       public Quat4d getControlPointOrientationQuat(double angle) {
                 
                 if (turnAxis == null) {
                         Vector3d dir = getPathLegDirection(Direction.NEXT);
@@ -367,11 +393,33 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                 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;
+                } else {
+                        Vector3d dir = getPathLegDirection(Direction.PREVIOUS);
+                        dir.negate();
+                        if (dir.lengthSquared() > MathTools.NEAR_ZERO)
+                                dir.normalize();
+                        return getControlPointOrientationQuat(dir, turnAxis, angle);
+                }
+       }
         
        
        
-        public static Quat4d getControlPointOrientationQuat(Vector3d dir, double angle) {
+       public static Quat4d getControlPointOrientationQuat(Vector3d dir, double angle) {
                        if (dir.lengthSquared() < MathTools.NEAR_ZERO)
                                return MathTools.getIdentityQuat();
                
@@ -424,28 +472,59 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                        return q1;
            }
        
-       public Vector3d getDirection() {
-               return getDirectedControlPointDirection();
+       public Vector3d getDirection(Direction direction) {
+           if (isDirected())
+               return getDirectedControlPointDirection();
+           if (isTurn() && isFixed()) {
+               if (direction == Direction.NEXT) {
+                   if (previous != null) {
+                   PipeControlPoint pcp = this;
+                    Vector3d dir = new Vector3d();
+                    dir.sub(pcp.getWorldPosition(),previous.getWorldPosition());
+                    if (dir.lengthSquared() > MathTools.NEAR_ZERO)
+                         dir.normalize();
+                    Quat4d q = getControlPointOrientationQuat(dir, pcp.getRotationAngle() != null ? pcp.getRotationAngle() : 0.0);
+                    AxisAngle4d aa = new AxisAngle4d(MathTools.Y_AXIS,pcp.getTurnAngle() == null ? 0.0 : pcp.getTurnAngle());
+                    Quat4d q2 = MathTools.getQuat(aa);
+                    Vector3d v = new Vector3d(1.,0.,0.);
+                    Vector3d offset = new Vector3d();
+                    MathTools.rotate(q2, v, offset);
+                    MathTools.rotate(q, offset, dir);
+                    return dir;
+                   }
+               } else {
+                   if (next != null) {
+                   PipeControlPoint pcp = this;
+                    Vector3d dir = new Vector3d();
+                    dir.sub(next.getWorldPosition(),pcp.getWorldPosition());
+                    if (dir.lengthSquared() > MathTools.NEAR_ZERO)
+                         dir.normalize();
+                    Quat4d q = getControlPointOrientationQuat(dir, pcp.getRotationAngle() != null ? pcp.getRotationAngle() : 0.0);
+                    AxisAngle4d aa = new AxisAngle4d(MathTools.Y_AXIS,pcp.getTurnAngle() == null ? 0.0 : pcp.getTurnAngle());
+                    Quat4d q2 = MathTools.getQuat(aa);
+                    Vector3d v = new Vector3d(1.,0.,0.);
+                    Vector3d offset = new Vector3d();
+                    MathTools.rotate(q2, v, offset);
+                    MathTools.rotate(q, offset, dir);
+                    return dir;
+                   }
+               }
+           }
+           return null;
        }
        
-       
-       
-       
-       
-
-       
        public void insert(PipeControlPoint previous, PipeControlPoint next) {
                // inserting an offsetpoint is error, 
                if (isDualSub())
-                       throw new RuntimeException();
+                       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();
+                       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) {
                        if (piperun != getPipeRun() || piperun != next.getPipeRun())
-                               throw new RuntimeException();
+                               throw new RuntimeException("All controls points must be located on the same pipe run");
                } else {
                        piperun.addChild(this);
                }
@@ -581,14 +660,14 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                v.sub(next.getWorldPosition(),pcp.getWorldPosition());
                                return v;
                        } else {
-                               if (isVariableAngle())
-                                       throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
                                if (previous == null) {
                                        if (!isDirected())
                                                throw new RuntimeException("Cannot calculate path leg direction for unconnected control point");
                                        return getDirectedControlPointDirection();
                                        
                                } else {
+                                   if (isVariableAngle())
+                           throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
                                        if (isInline()) {
                                                PipeControlPoint pcp = this;
                                                if (pcp.isDualSub()) {
@@ -603,6 +682,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                                Vector3d v = new Vector3d();
                                                v.sub(getWorldPosition(),previous.getWorldPosition());
                                                return v;
+                                       } else if (isTurn() && isFixed() && !_getReversed()) {
+                                          return getDirection(Direction.NEXT);
                                        }
                                        throw new RuntimeException("Missing implementation");
                                }
@@ -616,8 +697,6 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                v.sub(previous.getWorldPosition(),pcp.getWorldPosition());
                                return v;
                        } else {
-                               if (isVariableAngle())
-                                       throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
                                if (next == null)  {
                                        if (!isDirected())
                                                throw new RuntimeException("Cannot calculate path leg direction for unconnected control point");
@@ -625,7 +704,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                        v.negate();
                                        return v;
                                } else {
-                                       if (isInline()) {
+                                   if (isVariableAngle())
+                           throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
+                       if (isInline()) {
                                                PipeControlPoint pcp = this;
                                                if (pcp.isDualInline()) {
                                                        pcp = pcp.getSubPoint().get(0);
@@ -641,7 +722,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                                Vector3d v = new Vector3d();
                                                v.sub(getWorldPosition(),next.getWorldPosition());
                                                return v;
-                                       }
+                                       } else if (isTurn() && isFixed() && _getReversed()) {
+                                           return getDirection(Direction.PREVIOUS);
+                    }
                                        throw new RuntimeException("Missing implementation");
                                }
                        }