]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipingRules.java
Fix issues in offset calculations in directed path legs
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / scenegraph / controlpoint / PipingRules.java
index 8864ffd8cc8cda8fde18258fc756404d9a9066ec..e930b8d6d07094035a188933141c4519085c5382 100644 (file)
@@ -294,7 +294,7 @@ public class PipingRules {
                scp.setWorldPosition(pos);
                Vector3d dir = new Vector3d();
                dir.sub(pcp2.getWorldPosition(), pcp1.getWorldPosition());
-               updateControlPointOrientation(scp, dir);
+               scp.orientToDirection(dir);
                scp.setLength(length);
                validate(scp.getPipeRun());
                return scp;
@@ -381,10 +381,43 @@ public class PipingRules {
 
        }
 
+       /**
+        * Calculate offset based on a given fixed component direction.
+        * 
+        * The desired component direction is provided as an input to this method,
+        * unlike the direction vector that is calculated by calculateOffset.
+        * 
+        * The returned offset vector is always perpendicular to the given direction
+        * vector.
+        * 
+        * @param startPoint Start point of leg
+        * @param endPoint   End point of leg
+        * @param start      Starting component of leg
+        * @param list       Inline components between start and end
+        * @param end        Ending component of leg
+        * @param dir        Direction at which the offset is calculated
+        * @param offset     A vector object to receive the offset vector values
+        * @return True if offsets are present
+        */
        public static boolean calculateDirectedOffset(Vector3d startPoint, Vector3d endPoint, PipeControlPoint start, ArrayList<PipeControlPoint> list, PipeControlPoint end, Vector3d dir, Vector3d offset) {
                return calculateOffset(startPoint, endPoint, start, list, end, dir, offset, true);
        }
 
+       /**
+        * Calculate offset and direction vectors for a path leg so that the given chain
+        * of components starts and ends at the given coordinates
+        * 
+        * The returned direction and offset vectors are perpendicular to each other.
+        * 
+        * @param startPoint Start point of the leg
+        * @param endPoint   End point of the leg
+        * @param start      Starting component of the leg
+        * @param list       Inline components between start and end
+        * @param end        Ending component of the leg
+        * @param dir        A vector object to receive the component direction vector
+        * @param offset     A vector object to receive the offset vector
+        * @return True if offsets are present
+        */
        public static boolean calculateOffset(Vector3d startPoint, Vector3d endPoint, PipeControlPoint start, ArrayList<PipeControlPoint> list, PipeControlPoint end, Vector3d dir, Vector3d offset) {
                return calculateOffset(startPoint, endPoint, start, list, end, dir, offset, false);
        }
@@ -397,8 +430,11 @@ public class PipingRules {
                } else {
                        Vector3d sp = new Vector3d(startPoint);
                        Point3d ep = new Point3d(endPoint);
-                       dir.set(ep);
-                       dir.sub(sp);
+                       if (!directed) {
+                               dir.set(ep);
+                               dir.sub(sp);
+                       }
+                       
                        double l = dir.lengthSquared(); 
                        if (l > MathTools.NEAR_ZERO)
                                dir.scale(1.0/Math.sqrt(l));
@@ -761,7 +797,7 @@ public class PipingRules {
                    double curr = gapObj.d;
                    int d = 1;
                    while (d < gaps.size() && curr < -MIN_INLINE_LENGTH) {
-                       GapObj next = i+d >= 0 ? gaps.get(i+d) : null;
+                       GapObj next = i+d < gaps.size() ? gaps.get(i+d) : null;
                     GapObj prev = i-d >= 0 ? gaps.get(i-d) : null;
                        if (next != null && next.gap == Gap.SPACE) {
                            double move = Math.min(-curr, next.d);
@@ -1080,15 +1116,19 @@ public class PipingRules {
                
                Point3d otherPosition = new Point3d(dcpStart ? u.endPoint : u.startPoint);
                if (u.hasOffsets) {
-                       Vector3d dir = new Vector3d(), offset = new Vector3d();
+                       Vector3d dir = dcp.getDirection(dcpStart ? Direction.NEXT : Direction.PREVIOUS);
+                       if (!dcpStart)
+                               dir.negate();
+                       
+                       Vector3d offset = new Vector3d();
                        calculateDirectedOffset(u.startPoint, u.endPoint, u.start, u.list, u.end, dir, offset);
                        u.dir = dir;
                        u.offset = offset;
                        
                        if (dcpStart)
-                               otherPosition.add(offset);
-                       else
                                otherPosition.sub(offset);
+                       else
+                               otherPosition.add(offset);
                }
 
                double mu[] = new double[2];
@@ -1236,7 +1276,7 @@ public class PipingRules {
                Point3d position1 = new Point3d(u.startPoint);
                Point3d position2 = new Point3d(u.endPoint);
                
-               Vector3d dir = new Vector3d(), offset = new Vector3d();
+               Vector3d dir = u.start.getDirection(Direction.NEXT), offset = new Vector3d();
                calculateDirectedOffset(new Vector3d(position1), new Vector3d(position2), u.start, u.list, u.end, dir, offset);
                
                Point3d position1offset = new Point3d(position1);
@@ -1638,7 +1678,7 @@ public class PipingRules {
                        } else if (u.start.isEnd()) {
                                updateEndComponentControlPoint(u.start, u.dir);
                        } else if (u.start.isInline()) {
-                               updateControlPointOrientation(u.start, u.dir);
+                               u.start.orientToDirection(u.dir);
                        }
                        if (u.end.isTurn()) {
                                //updateTurnControlPointTurn(u.end, u.end.getPrevious(), u.end.getNext());
@@ -1647,7 +1687,7 @@ public class PipingRules {
                        } else if (u.end.isEnd()) {
                                updateEndComponentControlPoint(u.end, u.dir);
                        } else if (u.end.isInline()) {
-                               updateControlPointOrientation(u.end, u.dir);
+                               u.end.orientToDirection(u.dir);
                        }
 
                } else {
@@ -1776,7 +1816,7 @@ public class PipingRules {
                        System.out.println(" " + newInlinePoint);
 
                icp.setWorldPosition(newInlinePoint);
-               updateControlPointOrientation(icp, dir);
+               icp.orientToDirection(dir);
        }
 
        /**
@@ -1793,7 +1833,7 @@ public class PipingRules {
                        System.out.println("PipingRules.updateEndComponentControlPoint() " + ecp);
                
                if (!ecp.isFixed()) // prevent overriding nozzle orientations..
-                  updateControlPointOrientation(ecp, dir);
+                       ecp.orientToDirection(dir);
 
                for (PipeControlPoint pcp : ecp.getChildPoints()) {
                        // TODO update position
@@ -1801,21 +1841,6 @@ public class PipingRules {
                }
        }
 
-       private static void updateControlPointOrientation(PipeControlPoint pcp, Vector3d dir) {
-               Double angleO = pcp.getRotationAngle();
-               double angle = 0.0;
-               if (angleO != null)
-                       angle = angleO;
-               boolean reversed = pcp._getReversed();
-               Quat4d q = null;
-               if (dir != null) {
-                   q = pcp.getControlPointOrientationQuat(dir, angle, reversed);
-               } else {
-                   q = pcp.getControlPointOrientationQuat(angle, reversed);
-               }
-               pcp.setWorldOrientation(q);
-       }
-
        /**
         * Updates all branches when branch's position has been changed
         * 
@@ -1881,7 +1906,7 @@ public class PipingRules {
                                tcp.setTurnAxis(new Vector3d(MathTools.Y_AXIS));
                        }
                        
-                       updateControlPointOrientation(tcp,prev);
+                       tcp.orientToDirection(prev);
                        
                        if (DEBUG)
                                System.out.println("PipingTools.updateTurnControlPointTurn " + prev + " " + next + " " + turnAngle + " " + turnAxis);