]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java
Remove/Split action removes pipeline components without reconnecting
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / scenegraph / PipelineComponent.java
index 631894b485d0f86bcf10024f0823b228dcddf19d..3f393364e3ccf456cc9ab63b53b8c01927ee6278 100644 (file)
@@ -14,7 +14,9 @@ import org.simantics.objmap.graph.annotations.RelatedGetObj;
 import org.simantics.objmap.graph.annotations.RelatedSetObj;
 import org.simantics.plant3d.ontology.Plant3D;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Direction;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PointType;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
 
 /**
@@ -32,8 +34,8 @@ public abstract class PipelineComponent extends GeometryNode {
        private PipelineComponent previous;
        
        public PipeRun getPipeRun() {
-        return pipeRun;
-    }
+               return pipeRun;
+       }
        
        /**
         * Sets the pipe run.
@@ -93,7 +95,7 @@ public abstract class PipelineComponent extends GeometryNode {
                if (next == comp)
                        return;
                if (this.next != null)
-                   this.next._removeRef(this);
+                       this.next._removeRef(this);
                this.next = comp;
                this.syncnext = false;
                syncNext();
@@ -114,7 +116,7 @@ public abstract class PipelineComponent extends GeometryNode {
                if (previous == comp)
                        return;
                if (this.previous != null)
-                   this.previous._removeRef(this);
+                       this.previous._removeRef(this);
                this.previous = comp;
                this.syncprev = false;
                syncPrevious();
@@ -135,7 +137,7 @@ public abstract class PipelineComponent extends GeometryNode {
                if (branch0 == comp)
                        return;
                if (this.branch0 != null)
-                   this.branch0._removeRef(this);
+                       this.branch0._removeRef(this);
                this.branch0 = comp;
                this.syncbr0 = false;
                syncBranch0();
@@ -146,25 +148,25 @@ public abstract class PipelineComponent extends GeometryNode {
        }
 
        @GetPropertyValue(name="Previous",tabId="Debug",value=Plant3D.URIs.HasPrevious)
-    public String getPreviousDebug() {
-        if (previous == null)
-            return null;
-        return previous.getName();
-    }
-    
-    @GetPropertyValue(name="Next",tabId="Debug",value=Plant3D.URIs.HasNext)
-    public String getNextDebug() {
-        if (next == null)
-            return null;
-        return next.getName();
-    }
-    
+       public String getPreviousDebug() {
+               if (previous == null)
+                       return null;
+               return previous.getName();
+       }
+       
+       @GetPropertyValue(name="Next",tabId="Debug",value=Plant3D.URIs.HasNext)
+       public String getNextDebug() {
+               if (next == null)
+                       return null;
+               return next.getName();
+       }
+       
        @GetPropertyValue(name="Branch0",tabId="Debug",value=Plant3D.URIs.HasBranch0)
-    public String getBR0Debug() {
-        if (branch0 == null)
-            return null;
-        return branch0.getName();
-    }
+       public String getBR0Debug() {
+               if (branch0 == null)
+                       return null;
+               return branch0.getName();
+       }
 
        
        
@@ -219,33 +221,33 @@ public abstract class PipelineComponent extends GeometryNode {
        // When link to a component is removed, also link to the other direction must be removed at the same time, or
        // Control point structure is left into illegal state.
        private void _removeRef(PipelineComponent comp) {
-           if (next == comp) {
-               next = null;
-               syncnext = false;
-            syncNext();
-           } else if (previous == comp) {
-               previous = null;
-               syncprev = false;
-            syncPrevious();
-           } else if (branch0 == comp) {
-               branch0 = null;
-               syncbr0 = false;
-               syncBranch0();
-           }
+               if (next == comp) {
+                       next = null;
+                       syncnext = false;
+                       syncNext();
+               } else if (previous == comp) {
+                       previous = null;
+                       syncprev = false;
+                       syncPrevious();
+               } else if (branch0 == comp) {
+                       branch0 = null;
+                       syncbr0 = false;
+                       syncBranch0();
+               }
        }
        
        boolean syncnext = false;
-    private void syncNext() {
-        if (syncnext)
-            return;
-        syncnext = _syncNext();
-    }
+       private void syncNext() {
+               if (syncnext)
+                       return;
+               syncnext = _syncNext();
+       }
        
        
        private boolean _syncNext() {
-           PipeControlPoint pcp = getControlPoint();
+               PipeControlPoint pcp = getControlPoint();
                if (pcp != null) {
-                   
+                       
                        if (next != null ) {
                                if (next.getControlPoint() != null) {
                                        
@@ -257,15 +259,15 @@ public abstract class PipelineComponent extends GeometryNode {
                                        } else if (br0) {
                                                return _connectNext(pcp, next.getBranchPoint());
                                        } else {
-                                           return false;
+                                               return false;
                                        }
                                } else {
                                        return false;
                                }
                                
                        } else if (pcp.getNext() != null) {
-                           pcp.setNext(null);
-                           return true;
+                               pcp.setNext(null);
+                               return true;
                        }
                } else {
                        return false;
@@ -274,14 +276,14 @@ public abstract class PipelineComponent extends GeometryNode {
        }
        
        boolean syncprev = false;
-    private void syncPrevious() {
-        if (syncprev)
-            return;
-        syncprev = _syncPrevious();
-    }
+       private void syncPrevious() {
+               if (syncprev)
+                       return;
+               syncprev = _syncPrevious();
+       }
        
        private boolean _syncPrevious() {
-           PipeControlPoint pcp = getControlPoint();
+               PipeControlPoint pcp = getControlPoint();
                if (pcp != null) {
                        if (previous != null ) {
                                if (previous.getControlPoint() != null) {
@@ -294,15 +296,15 @@ public abstract class PipelineComponent extends GeometryNode {
                                        } else if (br0) {
                                                return _connectPrev(pcp, previous.getBranchPoint());
                                        } else {
-                                           return false;
+                                               return false;
                                        }
                                } else {
                                        return false;
                                }
                                
                        } else if (pcp.getPrevious() != null) {
-                           pcp.setPrevious(null);
-                           return true;
+                               pcp.setPrevious(null);
+                               return true;
                        }
                } else {
                        return false;
@@ -312,9 +314,9 @@ public abstract class PipelineComponent extends GeometryNode {
        
        boolean syncbr0 = false;
        private void syncBranch0() {
-           if (syncbr0)
-               return;
-           syncbr0 = _syncBranch0();
+               if (syncbr0)
+                       return;
+               syncbr0 = _syncBranch0();
        }
        
        private boolean _syncBranch0() {
@@ -327,7 +329,7 @@ public abstract class PipelineComponent extends GeometryNode {
                                if (branch0.getControlPoint() != null) {
                                        PipeControlPoint branchPoint = getBranchPoint();
                                        if (branchPoint == null)
-                                           return false;
+                                               return false;
                                        PipeControlPoint pcp = branch0.getControlPoint();
                                        // TODO, relying that the other direction is connected.
                                        boolean next = branch0.getPrevious() == this; // this --> branch0
@@ -337,7 +339,7 @@ public abstract class PipelineComponent extends GeometryNode {
                                        } else if (prev){
                                                _connectPrev(branchPoint, pcp); 
                                        } else {
-                                           return false;
+                                               return false;
                                        }
                                        
                                } else {
@@ -386,6 +388,15 @@ public abstract class PipelineComponent extends GeometryNode {
                }
                super.remove();
        }
+       
+       public void removeAndSplit() {
+           PipeControlPoint pcp = getControlPoint();
+        // Second check is needed, when remove process is initiated from control point.
+        if (pcp != null && pcp.getPipelineComponent() != null) {
+            pcp.removeAndSplit();
+        }
+        super.remove();
+       }
 
        @Override
        protected double[] getColor() {
@@ -458,8 +469,8 @@ public abstract class PipelineComponent extends GeometryNode {
                                double a = pcp.getTurnAngle();
                                return a*r;
                        }
-                        default:
-                                return null;
+                       default:
+                               return null;
                }
        }
        
@@ -467,4 +478,116 @@ public abstract class PipelineComponent extends GeometryNode {
                getControlPoint().getControlPointEnds(p1, p2);
        }
        
+       public void getEndDirections(Tuple3d v1, Tuple3d v2) {
+               getControlPoint().getEndDirections(v1, v2);
+       }
+       
+       public void getCentroid(Tuple3d p) {
+               PipeControlPoint pcp = getControlPoint(); 
+               if (pcp == null)
+                       throw new IllegalStateException("No centroid defined");
+               
+               switch (pcp.getType()) {
+               case INLINE:
+               case END:
+                       // Just return the world location
+                       if (!pcp.isSizeChange()) {
+                               p.set(pcp.getWorldPosition());
+                               return;
+                       }
+                       
+                       // Calculate center of mass for the frustum
+                       double r1 = getPipeRun().getPipeDiameter();
+                       double r2 = getAlternativePipeRun().getPipeDiameter();
+                       
+                       Vector3d p1 = new Vector3d(), p2 = new Vector3d();
+                       pcp.getInlineControlPointEnds(p1, p2);
+                       
+                       // Squared sum of radii
+                       double r12 = r1 + r2;
+                       r12 *= r12;
+                       
+                       // The larger of the radii form the base of a frustum
+                       double rmax = Math.max(r1, r2);
+                       
+                       // Relative distance from the base of the frustum
+                       double h = (r12 + 2*rmax*rmax) / (4 * (r12 - r1*r2));
+                       
+                       // Relative distance from p1 to p2
+                       if (r1 < r2)
+                               h = 1 - h;
+                       
+                       p2.sub(p1);
+                       p1.scaleAdd(h, p2);
+                       
+                       p.set(p1);
+                       return;
+               case TURN: {
+                       Vector3d loc = pcp.getRealPosition(PositionType.PREVIOUS);
+                       
+                       double r = getPipeRun().getTurnRadius();
+                       double a = pcp.getTurnAngle();
+                       double pipeRadius = pcp.getPipeRun().getPipeDiameter() / 2;
+                       
+                       // Unit vector in inlet flow direction
+                       Vector3d inletDir = pcp.getPathLegDirection(Direction.PREVIOUS);
+                       inletDir.scale(-1.0);
+                       inletDir.normalize();
+                       
+                       // Normal to both inletDir and turn axis in world coordinates
+                       Vector3d outletDir = pcp.getPathLegDirection(Direction.NEXT);
+                       Vector3d normal = new Vector3d(inletDir);
+                       normal.scaleAdd(-inletDir.dot(outletDir), outletDir);
+                       normal.normalize();
+                       
+                       // Location of turn axis
+                       Vector3d center = new Vector3d(normal);
+                       center.scaleAdd(r, loc);
+                       
+                       // Add vector components from axis to centroid
+                       double c = r + pipeRadius * pipeRadius / (4 * r);
+                       double c1 = c * Math.sin(a) / a;
+                       double c2 = c * (1 - Math.cos(a)) / a;
+                       normal.scale(-c1);
+                       inletDir.scale(c2);
+                       center.add(normal);
+                       center.add(inletDir);
+               
+                       // Return value
+                       p.set(center);
+                       return;
+               }
+               default:
+                       throw new IllegalStateException("No centroid defined");
+               }
+       }
+       
+       public double getVolume() {
+               PipeControlPoint pcp = getControlPoint(); 
+               if (pcp == null)
+                       throw new IllegalStateException("No centroid defined");
+               
+               double pipeRadius = getPipeRun().getPipeDiameter() / 2;
+               
+               switch (pcp.getType()) {
+               case INLINE:
+               case END:
+                       if (!pcp.isSizeChange()) {
+                               // Just return the cylinder volume
+                               return pcp.getLength() * Math.PI * pipeRadius * pipeRadius;
+                       }
+                       
+                       // Calculate center of mass for the frustum
+                       double r1 = pipeRadius;
+                       double r2 = getAlternativePipeRun().getPipeDiameter() / 2;
+                       return pcp.getLength() * Math.PI * (r1*r1 + r1*r2 + r2*r2) / 4;
+               case TURN: {
+                       double r = getPipeRun().getTurnRadius();
+                       double a = pcp.getTurnAngle();
+                       return r * a * Math.PI * pipeRadius * pipeRadius;
+               }
+               default:
+                       throw new IllegalStateException("No centroid defined");
+               }
+       }
 }