]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java
Tag user modifiable length
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / scenegraph / PipelineComponent.java
index 6ddd7a09fc9ba3d68c83fd8bb6c6534d84485619..61e48585336fb7749ba30c021fd42f549f40a027 100644 (file)
@@ -1,20 +1,28 @@
 package org.simantics.plant3d.scenegraph;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import javax.vecmath.Quat4d;
 import javax.vecmath.Tuple3d;
 import javax.vecmath.Vector3d;
 
 import org.simantics.g3d.math.MathTools;
+import org.simantics.g3d.property.annotations.CompoundGetPropertyValue;
+import org.simantics.g3d.property.annotations.CompoundSetPropertyValue;
 import org.simantics.g3d.property.annotations.GetPropertyValue;
 import org.simantics.g3d.property.annotations.PropertyContributor;
+import org.simantics.objmap.graph.annotations.CompoundRelatedGetValue;
+import org.simantics.objmap.graph.annotations.CompoundRelatedSetValue;
 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;
 
 /**
@@ -24,6 +32,8 @@ import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
  */
 @PropertyContributor
 public abstract class PipelineComponent extends GeometryNode {
+    
+    private static boolean DEBUG = false;
 
        
        private PipeRun pipeRun;
@@ -68,9 +78,16 @@ public abstract class PipelineComponent extends GeometryNode {
                        return;
                this.alternativePipeRun = pipeRun;
                if (getControlPoint().isDualInline()) {
-                       PipeControlPoint sub = getControlPoint().getSubPoint().get(0);
-                       if (sub.getParent() != this.alternativePipeRun)
-                               this.alternativePipeRun.addChild(sub);
+                       PipeControlPoint sub = getControlPoint().getDualSub();
+                       if (sub.getParent() != this.alternativePipeRun) {
+                           if (this.alternativePipeRun != null) {
+                              this.alternativePipeRun.addChild(sub);
+                           } else if (sub.getPipeRun() != null) {
+                               // FIXME : how to handle child point without proper run?
+                               sub.getPipeRun().remChild(sub);
+                           }
+                       }
+                               
                }
                firePropertyChanged(Plant3D.URIs.HasAlternativePipeRun);
        }
@@ -81,6 +98,44 @@ public abstract class PipelineComponent extends GeometryNode {
                super.updateParameters();
        }
        
+       @Override
+    @CompoundRelatedGetValue(objRelation=Plant3D.URIs.hasParameter,objType=Plant3D.URIs.Parameter,valRelation=Plant3D.URIs.hasParameterValue)
+    public Map<String, Object> getParameterMap() {
+        return super.getParameterMap();
+    }
+       
+    @Override
+    @CompoundRelatedSetValue(Plant3D.URIs.hasParameter)
+    public void setParameterMap(Map<String, Object> parameters) {
+        super.setParameterMap(parameters);
+    }
+    
+    @CompoundGetPropertyValue(name="Parameters",tabId="Parameters",value="parameters")
+    public Map<String,Object> getParameterMapUI() {
+        // TODO : how to filter parameters that are calculated by geometry provider?
+        Map<String,Object> map = new HashMap<String, Object>(getParameterMap());
+        map.remove("radius");
+        map.remove("radius2");
+        map.remove("offset");
+        return map;
+    }
+    
+    @CompoundSetPropertyValue(value="parameters")
+    public void setParameterMapUI(Map<String, Object> parameters) { 
+        Map<String, Object> curr = getParameterMap();
+        for (Entry<String, Object> entry : curr.entrySet()) {
+            if (!parameters.containsKey(entry.getKey()))
+                parameters.put(entry.getKey(), entry.getValue());
+        }
+        setParameterMap(parameters);
+    }
+    
+    public void setParameter(String name, Object value) {
+        Map<String, Object> parameters = new HashMap<>(getParameterMap());
+        parameters.put(name, value);
+        setParameterMap(parameters);
+    }
+       
        public abstract void setType(String typeURI) throws Exception;
        
        @RelatedGetObj(Plant3D.URIs.HasNext)
@@ -91,16 +146,20 @@ public abstract class PipelineComponent extends GeometryNode {
        @RelatedSetObj(Plant3D.URIs.HasNext)
        public void setNext(PipelineComponent comp) {
                if (next == comp)
-                       return;
+                   return;
                if (this.next != null)
-                       this.next._removeRef(this);
-               this.next = comp;
-               this.syncnext = false;
-               syncNext();
-               firePropertyChanged(Plant3D.URIs.HasNext);
-               if (comp != null)
-                       comp.sync();
-//             System.out.println(this + " next " + comp);
+                   this.next._removeRef(this);
+        _setNext(comp);
+        this.syncnext = false;
+        if (DEBUG) System.out.println(this + " next " + comp);
+        syncNext();
+        firePropertyChanged(Plant3D.URIs.HasNext);
+        if (comp != null)
+            comp.sync();
+       }
+       
+       protected void _setNext(PipelineComponent comp) {
+           this.next = comp;
        }
        
        
@@ -115,14 +174,19 @@ public abstract class PipelineComponent extends GeometryNode {
                        return;
                if (this.previous != null)
                        this.previous._removeRef(this);
-               this.previous = comp;
+               _setPrevious(comp);
                this.syncprev = false;
+               if (DEBUG) System.out.println(this + " prev " + comp);
                syncPrevious();
                firePropertyChanged(Plant3D.URIs.HasPrevious);
                if (comp != null)
                        comp.sync();
-//             System.out.println(this + " prev " + comp);
        }
+       
+       protected void _setPrevious(PipelineComponent comp) {
+        this.previous = comp;
+    }
+       
        private PipelineComponent branch0;
        
        @RelatedGetObj(Plant3D.URIs.HasBranch0)
@@ -138,11 +202,11 @@ public abstract class PipelineComponent extends GeometryNode {
                        this.branch0._removeRef(this);
                this.branch0 = comp;
                this.syncbr0 = false;
+               if (DEBUG) System.out.println(this + " br0 " + comp);
                syncBranch0();
                firePropertyChanged(Plant3D.URIs.HasBranch0);
                if (comp != null)
                        comp.sync();
-//             System.out.println(this + " next " + comp);
        }
 
        @GetPropertyValue(name="Previous",tabId="Debug",value=Plant3D.URIs.HasPrevious)
@@ -170,8 +234,8 @@ public abstract class PipelineComponent extends GeometryNode {
        
        private PipeControlPoint getBranchPoint() {
                PipeControlPoint branchPoint;
-               if (getControlPoint().getSubPoint().size() > 0) {
-                       branchPoint = getControlPoint().getSubPoint().get(0);
+               if (getControlPoint().getChildPoints().size() > 0) {
+                       branchPoint = getControlPoint().getChildPoints().get(0);
                } else {
                        if (branch0.getPipeRun() == null)
                                return null;
@@ -192,27 +256,27 @@ public abstract class PipelineComponent extends GeometryNode {
                if (pcp.getNext() != nextPCP) {
                        pcp.setNext(nextPCP);
                }
-               if (pcp.isDualInline()) {
-                       PipeControlPoint sub = pcp.getSubPoint().get(0);
-                       if (sub.getNext() != nextPCP)
-                               sub.setNext(nextPCP);
-               }
+//             if (pcp.isDualInline()) {
+//                     PipeControlPoint sub = pcp.getChildPoints().get(0);
+//                     if (sub.getNext() != nextPCP)
+//                             sub.setNext(nextPCP);
+//             }
                return true;
        }
        
        private boolean  _connectPrev(PipeControlPoint pcp, PipeControlPoint prevPCP) {
                if (prevPCP == null)
                        return false;
-               if (prevPCP.isDualInline())
-                       prevPCP = prevPCP.getSubPoint().get(0);
+//             if (prevPCP.isDualInline())
+//                     prevPCP = prevPCP.getChildPoints().get(0);
                if (pcp.getPrevious() != prevPCP) {
                        pcp.setPrevious(prevPCP);
                }
-               if (pcp.isDualInline()) {
-                       PipeControlPoint sub = pcp.getSubPoint().get(0);
-                       if (sub.getPrevious() != prevPCP)
-                               sub.setPrevious(prevPCP);
-               }
+//             if (pcp.isDualInline()) {
+//                     PipeControlPoint sub = pcp.getChildPoints().get(0);
+//                     if (sub.getPrevious() != prevPCP)
+//                             sub.setPrevious(prevPCP);
+//             }
                return true;
        }
        
@@ -220,16 +284,22 @@ public abstract class PipelineComponent extends GeometryNode {
        // Control point structure is left into illegal state.
        private void _removeRef(PipelineComponent comp) {
                if (next == comp) {
-                       next = null;
+                       _setNext(null);
                        syncnext = false;
+                       if (DEBUG) System.out.println(this + " remove next " + comp);
+                       firePropertyChanged(Plant3D.URIs.HasNext);
                        syncNext();
                } else if (previous == comp) {
-                       previous = null;
+                       _setPrevious(null);
                        syncprev = false;
+                       if (DEBUG) System.out.println(this + " remove prev " + comp);
+                       firePropertyChanged(Plant3D.URIs.HasPrevious);
                        syncPrevious();
                } else if (branch0 == comp) {
                        branch0 = null;
                        syncbr0 = false;
+                       if (DEBUG) System.out.println(this + " remove br0 " + comp);
+                       firePropertyChanged(Plant3D.URIs.HasBranch0);
                        syncBranch0();
                }
        }
@@ -344,9 +414,9 @@ public abstract class PipelineComponent extends GeometryNode {
                                        return false;
                                }
                                
-                       } else if (getControlPoint().getSubPoint().size() > 0) { // TODO : this may cause problems? (Removes branch point, before branch has been set?)
-                               getControlPoint().getSubPoint().get(0).remove();
-                               getControlPoint().children.clear();
+                       } else if (getControlPoint().getChildPoints().size() > 0) { // TODO : this may cause problems? (Removes branch point, before branch has been set?)
+                               //getControlPoint().getSubPoint().get(0).remove();
+                               //getControlPoint().children.clear();
                                return true;
                        }
                } else {
@@ -371,7 +441,7 @@ public abstract class PipelineComponent extends GeometryNode {
        }
        
        public Map<String,Object> updateParameterMap() {
-               return Collections.EMPTY_MAP;
+               return Collections.emptyMap();
        }
        
        public abstract String getType();
@@ -379,6 +449,7 @@ public abstract class PipelineComponent extends GeometryNode {
        
        @Override
        public void remove() {
+           if (DEBUG) System.out.println(this + " remove");
                PipeControlPoint pcp = getControlPoint();
                // Second check is needed, when remove process is initiated from control point.
                if (pcp != null && pcp.getPipelineComponent() != null) {
@@ -386,6 +457,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() {
@@ -407,12 +487,7 @@ public abstract class PipelineComponent extends GeometryNode {
                super.setOrientation(orientation);
                if (getControlPoint() != null) {
                        getControlPoint()._setWorldOrientation(getWorldOrientation());
-                       try {
-                               PipingRules.requestUpdate(getControlPoint());
-                       } catch (Exception e) {
-                               // TODO Auto-generated catch block
-                               e.printStackTrace();
-                       }       
+                       PipingRules.requestUpdate(getControlPoint());
                }
        }
        
@@ -423,12 +498,7 @@ public abstract class PipelineComponent extends GeometryNode {
                super.setPosition(position);
                if (getControlPoint() != null) {
                        getControlPoint()._setWorldPosition(getWorldPosition());
-                       try {
-                               PipingRules.requestUpdate(getControlPoint());
-                       } catch (Exception e) {
-                               // TODO Auto-generated catch block
-                               e.printStackTrace();
-                       }
+                       PipingRules.requestUpdate(getControlPoint());
                }
        }
        
@@ -454,7 +524,7 @@ public abstract class PipelineComponent extends GeometryNode {
                        case END:
                                return null;
                        case TURN: {
-                               double r = getPipeRun().getTurnRadius();
+                               double r = ((TurnComponent)this).getTurnRadius();
                                double a = pcp.getTurnAngle();
                                return a*r;
                        }
@@ -463,8 +533,138 @@ public abstract class PipelineComponent extends GeometryNode {
                }
        }
        
+       /**
+        * Returns diameter of the pipe
+        * @return
+        */
+       public Double getDiameter() {
+           return getPipeRun().getPipeDiameter();
+       }
+       
+       /**
+        * Returns secondary diameter of the pipe for size change components
+        * @return
+        */
+       public Double getDiameter2() {
+           if (getAlternativePipeRun() == null)
+               return null;
+           return getAlternativePipeRun().getPipeDiameter();
+       }
+       
        public void getEnds(Tuple3d p1, Tuple3d p2) {
                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 = ((TurnComponent)this).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 = ((TurnComponent)this).getTurnRadius();
+                       double a = pcp.getTurnAngle();
+                       return r * a * Math.PI * pipeRadius * pipeRadius;
+               }
+               default:
+                       throw new IllegalStateException("No centroid defined");
+               }
+       }
 }