]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java
PipeCOntrolPoint setNext/setPrev/remove improved
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / scenegraph / controlpoint / PipeControlPoint.java
index 086bdb2b5d408de5fcc8109dba50eae6ea8ca452..491a273331a36ec8a0392122c92dc8833c6bbfb6 100644 (file)
@@ -40,7 +40,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
        private boolean isReverse = false;     // definition direction can be swapped
        private boolean isDeletable = true;    // can be removed by rules
        private boolean isSizeChange = false;  // changes size of the pipe. The next control point / component is on different PipeRun
-       private boolean isSub = false;         // child point
+       private boolean isSub = false;         // child point for offset / size change
 
        public PipeControlPoint(PipelineComponent component) {
                this.component = component;
@@ -233,12 +233,44 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
        }
 
        public void setNext(PipeControlPoint next) {
+           if (isSub) {
+               getParentPoint().setNext(next);
+               return;
+           }
+           if (next != null && next.isDualSub())
+               next = next.parent;
+           if (_setNext(next)) {
+               for (PipeControlPoint pcp : children) {
+                if (pcp.isSub)
+                    pcp._setNext(next);
+            }
+               updateSubPoint();
+           }
+       }
+       
+       public void setPrevious(PipeControlPoint prev) {
+        if (isSub) {
+            getParentPoint().setPrevious(prev);
+            return;
+        }
+        if (prev != null && prev.isDualInline())
+            prev = prev.children.get(0);
+        if (_setPrevious(prev)) {
+            for (PipeControlPoint pcp : children) {
+                if (pcp.isSub)
+                    pcp._setPrevious(prev);
+            }
+            updateSubPoint();
+        }
+    }
+       
+       protected boolean _setNext(PipeControlPoint next) {
                if (isEnd() && previous != null && next != null)
                        throw new RuntimeException("End control points are allowed to have only one connection");
                if (next == this)
                        throw new RuntimeException("Cannot connect to self");
                if (this.next == next)
-                       return;
+                       return false;
                if (DEBUG) System.out.println(this + " next " + next);
                if (next == null && isVariableAngle() && previous != null && !isRemoved()) {
                    convertVariableAngleToFixed(Direction.NEXT);
@@ -249,17 +281,18 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                component.setNext(next != null ? next.component : null);
                        else
                                component.setBranch0(next != null ? next.component : null);
-                       updateSubPoint();
+                       
                }
+               return true;
        }
 
-       public void setPrevious(PipeControlPoint previous) {
+       protected boolean _setPrevious(PipeControlPoint previous) {
                if (isEnd() && next != null && previous != null)
                        throw new RuntimeException("End control points are allowed to have only one connection");
                if (previous == this)
                        throw new RuntimeException("Cannot connect to self");
                if (this.previous == previous)
-                       return;
+                       return false;
                if (DEBUG) System.out.println(this + " previous " + previous);
                if (previous == null && isVariableAngle() && next != null && !isRemoved()) {
             convertVariableAngleToFixed(Direction.PREVIOUS);
@@ -272,6 +305,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                component.setBranch0(previous != null ? previous.component : null);
                        updateSubPoint();
                }
+               return true;
        }
        
        private void convertVariableAngleToFixed(Direction direction) {
@@ -303,7 +337,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
        public PipeControlPoint parent;
        public List<PipeControlPoint> children = new ArrayList<PipeControlPoint>();
 
-       public List<PipeControlPoint> getSubPoint() {
+       public List<PipeControlPoint> getChildPoints() {
                return children;
        }
 
@@ -334,7 +368,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                this.length = l;
                firePropertyChanged("length");
                if (isDualInline())
-                       getSubPoint().get(0).setLength(l);
+                   getDualSub().setLength(l);
        }
 
        @GetPropertyValue(name="Turn Angle",tabId="Debug",value="turnAngle")
@@ -577,7 +611,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
 
                PipeControlPoint offsetCP = null;
                if (isOffset()) {
-                       offsetCP = getSubPoint().get(0);
+                       offsetCP = getDualSub();
                }
                if (previousNext != null && previousNext == next) {
                        if (previous.isDualInline()) {
@@ -602,7 +636,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                        }
 
                        if (next.isDualInline()) {
-                               next.getSubPoint().get(0).setPrevious(this);
+                               next.getDualSub().setPrevious(this);
                        }
                } else if (previousPrevious != null && previousPrevious == next) {
                        // control point were given in reverse order 
@@ -620,7 +654,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                offsetCP.setPrevious(next);
                        }
                        if (previous.isDualInline()) {
-                               previous.getSubPoint().get(0).setPrevious(this);
+                               previous.getDualSub().setPrevious(this);
                        }
                        this.setPrevious(next);
                        next.setNext(this);
@@ -652,7 +686,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                pcp.getParentPoint().setNext(this);
                        }
                        if (isDualInline()) {
-                               getSubPoint().get(0).setPrevious(this);
+                           getDualSub().setPrevious(this);
                        }
                } else {
                        // if direction is previous, user must have given sizechange
@@ -662,7 +696,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                        // we must link pcp to newCP's OffsetPoint
                        PipeControlPoint nocp = null;
                        if (isDualInline()) {
-                               nocp = getSubPoint().get(0);
+                               nocp = getDualSub();
                                nocp.setNext(pcp);
                        }
                        if (nocp == null) {
@@ -672,7 +706,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                        }
                        this.setNext(pcp);
                        if (pcp.isDualInline()) {
-                               PipeControlPoint ocp = pcp.getSubPoint().get(0);
+                               PipeControlPoint ocp = pcp.getDualSub();
                                if (nocp == null)
                                        ocp.setPrevious(this);
                                else
@@ -741,7 +775,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                        if (next != null) {
                                PipeControlPoint pcp = this;
                                if (pcp.isDualInline()) {
-                                       pcp = pcp.getSubPoint().get(0);
+                                       pcp = pcp.getDualSub();
                                }
                                Vector3d v = new Vector3d();
                                v.sub(next.getWorldPosition(),pcp.getWorldPosition());
@@ -796,7 +830,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                        if (isInline()) {
                                                PipeControlPoint pcp = this;
                                                if (pcp.isDualInline()) {
-                                                       pcp = pcp.getSubPoint().get(0);
+                                                       pcp = pcp.getDualSub();
                                                }
                                                Vector3d v = new Vector3d();
                                                v.sub(pcp.getWorldPosition(),next.getWorldPosition());
@@ -821,7 +855,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
        public void getInlineControlPointEnds(Tuple3d p1, Tuple3d p2) {
                assert (isInline());
 
-               PipeControlPoint sub = isAxial() ? this : getSubPoint().get(0);
+               PipeControlPoint sub = isAxial() ? this : getDualSub();
                Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition();
                Vector3d dir = sub.getPathLegDirection(Direction.NEXT);
                
@@ -834,7 +868,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
        }
 
        public void getControlPointEnds(Tuple3d p1, Tuple3d p2) {
-               PipeControlPoint sub = isAxial() || isDirected() || isTurn() ? this : getSubPoint().get(0);
+               PipeControlPoint sub = isAxial() || isDirected() || isTurn() ? this : getChildPoints().get(0);
                Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition();
                
                Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS);
@@ -855,7 +889,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
        }
 
        public void getEndDirections(Tuple3d v1, Tuple3d v2) {
-               PipeControlPoint sub = isAxial() ? this : getSubPoint().get(0);
+               PipeControlPoint sub = isAxial() ? this : getDualSub();
                
                Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS);
                dir1.normalize();
@@ -1010,17 +1044,24 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
        public void _remove() {
            _remove(true);
        }
+       
+       
+       public PipeControlPoint getDualSub() {
+           if (isDualInline())
+               return getChildPoints().get(0);
+           else
+               throw new IllegalStateException("Current control point is not dual inline");
+       }
+       
 
        public void _remove(boolean renconnect) {
                if (component == null && next == null && previous == null)
                        return;
                if (DEBUG) System.out.println(this + " Remove " + renconnect);
-               if (isDualInline() || isDualSub()) {
-                       removeDualPoint();
-                       return;
-               }
+
                if (getParentPoint() != null) {
                    getParentPoint()._remove(renconnect);
+                   return;
                }
                PipeRun pipeRun = getPipeRun();
                if (pipeRun == null)
@@ -1044,37 +1085,41 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                boolean link = renconnect;
                                if (currentNext.isBranchEnd()) {
                                        link = false;
-                                       //                                      currentNext.setPrevious(null);
-                                       //                                      currentNext.setNext(null);
                                        currentNext.remove();
                                        currentNext = null;
                                        setNext(null);
                                }
                                if (currentPrev.isBranchEnd()) {
                                        link = false;
-                                       //                                      currentPrev.setPrevious(null);
-                                       //                                      currentPrev.setNext(null);
                                        currentPrev.remove();
                                        currentPrev = null;
                                        setPrevious(null);
                                }
-                               if (link && currentPrev.isDirected() && currentNext.isDirected()) {
-                                       link = false;
+                               if (link) {
+                                   if (currentPrev.isDirected() && currentNext.isDirected())
+                                       link = false;
+                                   else if (this.isDualInline()) {
+                                       link = false;
+                                   } else if (this.isDualSub()) {
+                                       throw new RuntimeException("_remove() is called for parent point, somehow got to child point. " + this);
+                                   }
                                }
                                if (currentNext == null) {
                                        // Nothing to do
                                } else if (currentNext.isDualInline()) {
                                        PipeControlPoint sccp = currentNext;
-                                       PipeControlPoint ocp = sccp.getSubPoint().get(0);
+                                       PipeControlPoint ocp = currentNext.getDualSub();
                                        if (ocp == null) {
                                                throw new RuntimeException("Removing PipeControlPoint " + this+ " structure damaged, no offset control point");
                                        }
                                        if (link) {
                                                sccp.setPrevious(currentPrev);
-                                               ocp.setPrevious(currentPrev);
+                                               //ocp.setPrevious(currentPrev);
+                                               assert(ocp.getPrevious() == currentPrev);
                                        } else {
                                                sccp.setPrevious(null);
-                                               ocp.setPrevious(null);
+                                               //ocp.setPrevious(null);
+                                               assert(ocp.getPrevious() == null);
                                        }
                                        setNext(null);
                                } else if (currentNext.isDualSub()) {
@@ -1086,6 +1131,16 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                                currentNext.setPrevious(null);
                                        }
                                        setNext(null);
+                               } else if (isDualInline()) {
+                                   if (currentNext.previous != getDualSub()) {
+                                       throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
+                                   }
+                                   if (link) {
+                        currentNext.setPrevious(currentPrev);
+                    } else {
+                        currentNext.setPrevious(null);
+                    }
+                    setNext(null);
                                } else {
                                        throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
                                }
@@ -1095,15 +1150,17 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                        throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, previous control point is size change control point");
                                } else if (currentPrev.isDualSub()) {
                                        PipeControlPoint ocp = currentPrev;
-                                       PipeControlPoint sccp = ocp.getParentPoint();
+                                       PipeControlPoint sccp = currentPrev.getParentPoint();
                                        if (sccp == null)
                                                throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, no size change control point");
                                        if (link) {
-                                               ocp.setNext(currentNext);
+                                               //ocp.setNext(currentNext);
                                                sccp.setNext(currentNext);
+                                               assert(ocp.getNext() == currentNext);
                                        } else {
-                                               ocp.setNext(null);
+                                               //ocp.setNext(null);
                                                sccp.setNext(null);
+                                               assert(ocp.getNext() == null);
                                        }
                                        setPrevious(null);
                                } else if (currentPrev.next == this) {
@@ -1137,36 +1194,42 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                                } else {
                                        // FIXME : pipe run must be split into two parts, since the control point structure is no more continuous. 
                                }
-                       } else if (next != null) {
-                               if (next.isDualInline()) {
-                                       PipeControlPoint sccp = next;
-                                       PipeControlPoint ocp = sccp.getSubPoint().get(0);
+                       } else if (currentNext != null) {
+                               if (currentNext.isDualInline()) {
+                                       PipeControlPoint sccp = currentNext;
+                                       PipeControlPoint ocp = getDualSub();
                                        if (ocp == null) {
                                                throw new RuntimeException("Removing PipeControlPoint " + this+ " structure damaged, no offset control point");
                                        }
                                        sccp.setPrevious(null);
-                                       ocp.setPrevious(null);
-                               } else if (next.isDualSub()) {
+                                       assert(ocp.getPrevious() == null);
+                                       //ocp.setPrevious(null);
+                               } else if (currentNext.isDualSub()) {
                                        throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, next control point is offset control point");
-                               } else if (next.previous == this) {
-                                       next.setPrevious(null);
+                               } else if (currentNext.previous == this) {
+                                   currentNext.setPrevious(null);
+                               }  else if (isDualInline()) {
+                    if (currentNext.previous != getDualSub()) {
+                        throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
+                    }
+                    currentNext.setPrevious(null);
                                } else {
                                        throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
                                }
                                setNext(null);
                        } else {  //(previous != null)
-                               if(previous.isDualInline()) {
+                               if(currentPrev.isDualInline()) {
                                        throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, previous control point is size change control point");
-                               } else if (previous.isDualSub()) {
-                                       PipeControlPoint ocp = previous;
-                                       PipeControlPoint sccp = ocp.getParentPoint();
+                               } else if (currentPrev.isDualSub()) {
+                                       PipeControlPoint ocp = currentPrev;
+                                       PipeControlPoint sccp = currentPrev.getParentPoint();
                                        if (sccp == null) {
                                                throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, no size change control point");
                                        }
-                                       ocp.setNext(null);
                                        sccp.setNext(null);
-                               } else if (previous.next == this) {
-                                       previous.setNext(null);
+                                       assert(ocp.getNext() == null);
+                               } else if (currentPrev.next == this) {
+                                   currentPrev.setNext(null);
                                } else {
                                        throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
                                }
@@ -1267,76 +1330,51 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                if (getPipelineComponent() == null)
                    return true; // already removed
            if (getPipelineComponent().getType().equals("Plant3D.URIs.Builtin_BranchSplitComponent")) {
-               if (getSubPoint().get(0).getNext() == null && getSubPoint().get(0).getPrevious() == null) {
+               if (getChildPoints().get(0).getNext() == null && getChildPoints().get(0).getPrevious() == null) {
                        remove();
                        return true;
                }
            }
-            return false;
+           return checkRemove(getPipeRun());
            }
     }
 
-       private void checkRemove(PipeRun pipeRun) {
+       private boolean checkRemove(PipeRun pipeRun) {
                Collection<PipeControlPoint> points = pipeRun.getControlPoints();
                if (points.size() == 0) {
                        pipeRun.remove();
+                       return true;
                } else if (points.size() == 1) {
                        PipeControlPoint pcp = points.iterator().next();
-                       if (pcp.isDeletable())
-                               pcp._remove();
-               }
-       }
-
-       private void removeDualPoint() {
-               if (previous != null)
-                       previous.setNext(null);
-               if (next != null)
-                       next.setPrevious(null);
-               PipeControlPoint ocp;
-               PipeControlPoint sccp;
-               if (isDualInline()) {
-                       sccp = this;
-                       ocp = getSubPoint().get(0);
-               } else {
-                       ocp = this;
-                       sccp = getParentPoint();
+                       if (pcp.isDeletable() && pcp.getNext() == null && pcp.getPrevious() == null) {
+                               pcp._remove(); // This call will recursively call also this method...
+                               return true;
+                       }
                }
-               PipeRun p1 = ocp.getPipeRun();
-               PipeRun p2 = sccp.getPipeRun();
-
-               ocp.removeComponent();
-               sccp.removeComponent();
-
-               if (p1 != null)
-                       p1.remChild(ocp);
-               if (p2 != null)
-                       p2.remChild(sccp);
-
-               // TODO : now we assume that this is size change, and we do
-               if (ocp.next != null)
-                       ocp.next.setPrevious(null);
-               if (ocp.previous != null)
-                       ocp.previous.setNext(null);
-               if (sccp.next != null)
-                       sccp.next.setPrevious(null);
-               if (sccp.previous != null)
-                       sccp.previous.setNext(null);
-               ocp.setNext(null);
-               ocp.setPrevious(null);
-               sccp.setNext(null);
-               sccp.setPrevious(null);
-
-               if (p1 != null)
-                       checkRemove(p1);
-               if (p2 != null)
-                       checkRemove(p2);
+               return false;
        }
 
        private void removeSubPoints() {
                for (PipeControlPoint p : children) {
-                       // TODO : this may affect delete routine, since classification of the point changes.
                        p.parent = null;
-                       p._remove();
+                       p.component = null;
+                       //p._remove();
+                       PipeControlPoint currentNext = p.getNext();
+                       PipeControlPoint currentPrev = p.getPrevious();
+                       p._setNext(null);
+                       p._setPrevious(null);
+                       PipeRun run = p.getPipeRun();
+                       if (run != null) {
+                           run.remChild(p);
+                           checkRemove(run);
+                       }
+                       if (currentNext != null)
+                if (!currentNext.checkRemove())
+                    PipingRules.requestUpdate(currentNext);
+            if (currentPrev != null)
+                if (!currentPrev.checkRemove())
+                    PipingRules.requestUpdate(currentPrev);
+            
                }
                children.clear();
        }
@@ -1413,20 +1451,20 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
        private void updateSubPoint() {
                if (isOffset()) {
                        if (next == null && previous == null) {
-                               for (PipeControlPoint sub : getSubPoint()) {
+                               for (PipeControlPoint sub : getChildPoints()) {
                                        sub.setWorldPosition(getWorldPosition());
                                        sub.setWorldOrientation(getWorldOrientation());
                                }
                                return;
                        }
-                       for (PipeControlPoint sub : getSubPoint()) {
+                       for (PipeControlPoint sub : getChildPoints()) {
                                Vector3d wp = getWorldPosition();
                                wp.add(getSizeChangeOffsetVector());
                                sub.setWorldPosition(wp);
                                sub.setWorldOrientation(getWorldOrientation());
                        }
                } else {
-                       for (PipeControlPoint sub : getSubPoint()) {
+                       for (PipeControlPoint sub : getChildPoints()) {
                                sub.setWorldPosition(getWorldPosition());
                                sub.setWorldOrientation(getWorldOrientation());
                        }