]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java
SCL function for connecting pipeline components
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / utils / ComponentUtils.java
index 4a4888090aff7a0dd08756d35b6ba8e4607bdd02..cc19260b41bf719ddda3df07a7460f3c4b62f8ee 100644 (file)
@@ -5,6 +5,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.vecmath.Point3d;
 import javax.vecmath.Vector3d;
 
 import org.simantics.Simantics;
@@ -13,6 +14,7 @@ import org.simantics.db.Resource;
 import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.g3d.math.MathTools;
 import org.simantics.g3d.scenegraph.GeometryProvider;
 import org.simantics.layer0.Layer0;
 import org.simantics.plant3d.ontology.Plant3D;
@@ -25,11 +27,9 @@ import org.simantics.plant3d.scenegraph.PipeRun;
 import org.simantics.plant3d.scenegraph.PipelineComponent;
 import org.simantics.plant3d.scenegraph.TurnComponent;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
-import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Direction;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
-import org.simantics.plant3d.utils.Item.Type;
-import org.simantics.utils.ui.ExceptionUtils;
+import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
 
 public class ComponentUtils {
 
@@ -474,4 +474,148 @@ public class ComponentUtils {
               
            return newComponent;
        }
+       public static boolean connect(PipelineComponent current, PipelineComponent endTo) throws Exception {
+           return connect(current, endTo, null, null);
+       }
+       
+       /**
+        * Connects component to another component
+        * @param current
+        * @param endTo
+        * @param endType
+        * @param position
+        * @return
+        * @throws Exception
+        */
+       public static boolean connect(PipelineComponent current, PipelineComponent endTo, PositionType endType, Vector3d position) throws Exception{
+           PipeControlPoint endCP = endTo.getControlPoint();
+           boolean reversed;
+           if (current.getNext() == null)
+               reversed = false;
+           else if (current.getPrevious() == null)
+               reversed = true;
+           else
+               return false;
+           
+           PipeRun pipeRun = current.getPipeRun();
+           P3DRootNode root = (P3DRootNode)current.getRootNode();
+           PipeControlPoint currentCP = current.getControlPoint();
+           
+        if (endType == null || endType == PositionType.NEXT || endType == PositionType.PREVIOUS) {
+            
+            
+            
+            boolean requiresReverse = false;
+            if (!reversed && endCP.getPrevious() != null) {
+                if (endCP.getNext() != null)
+                    return false;
+                requiresReverse = true;
+            } else if (reversed && endCP.getNext() != null) {
+                if (endCP.getPrevious() != null)
+                    return false;
+                requiresReverse = true;
+            }
+            PipeRun other = endCP.getPipeRun();
+            boolean mergeRuns = pipeRun.equalSpecs(other);
+            
+            if (requiresReverse) {
+                // Pipe line must be traversible with next/previous relations without direction change.
+                // Now the component, where we are connecting the created pipeline is defined in different order.
+                PipingRules.reverse(other);
+                
+            }
+            if (mergeRuns) {
+                // Runs have compatible specs and must be merged
+                if (pipeRun != other) // FIXME: temporary workaround.
+                    PipingRules.merge(pipeRun, other);
+                if (!reversed) {
+                    currentCP.setNext(endCP);
+                    endCP.setPrevious(currentCP);
+                } else {
+                    currentCP.setPrevious(endCP);
+                    endCP.setNext(currentCP);
+                }
+            } else {
+                // Runs do not have compatible specs, and a reducer must be attached in between.
+                InlineComponent reducer = ComponentUtils.createReducer(root);
+                PipeControlPoint pcp = reducer.getControlPoint();
+                PipeControlPoint ocp = pcp.getSubPoint().get(0);
+                
+                Vector3d endPos = endCP.getWorldPosition();
+                Vector3d currentPos = currentCP.getWorldPosition();
+                Vector3d v = new Vector3d(endPos);
+                v.sub(currentPos);
+                v.scale(0.5);
+                v.add(currentPos);
+                
+                PipingRules.addSizeChange(reversed, pipeRun, other, reducer, currentCP, endCP);
+                
+                pcp.setWorldPosition(v);
+                reducer.updateParameters();
+            }
+            PipingRules.positionUpdate(endCP);
+            return true;
+            
+        } else if (endType == PositionType.SPLIT) {
+            InlineComponent branchSplit = createBranchSplit((InlineComponent)endTo, position);
+            if (branchSplit == null)
+                return false;
+            PipeControlPoint branchSplitCP = branchSplit.getControlPoint();
+            PipeControlPoint pcp = new PipeControlPoint(branchSplit,pipeRun);
+            branchSplitCP.children.add(pcp);
+            pcp.parent = branchSplitCP;
+            pcp.setWorldOrientation(branchSplitCP.getWorldOrientation());
+            pcp.setWorldPosition(branchSplitCP.getWorldPosition());
+                        
+            
+            if(!reversed) {
+                pcp.setPrevious(currentCP);
+                currentCP.setNext(pcp);
+            } else {
+                pcp.setNext(currentCP);
+                currentCP.setPrevious(pcp);
+            }
+            PipingRules.positionUpdate(endCP);
+            return true;
+        }
+        return false;
+       }
+       
+       public static InlineComponent createBranchSplit(InlineComponent component, Vector3d pos) throws Exception{
+           if (!component.isVariableLength())
+               return null;
+           PipeRun pipeRun = component.getPipeRun();
+           Vector3d sStart = new Vector3d();
+           Vector3d sEnd = new Vector3d();
+           component.getControlPoint().getInlineControlPointEnds(sStart, sEnd);
+           
+           if (MathTools.distance(sStart, sEnd) < (pipeRun.getPipeDiameter()*0.5))
+               return null;
+           
+        
+        Vector3d p = MathTools.closestPointOnEdge(new Vector3d(pos), sStart, sEnd);
+        if (p == sStart) {
+            Vector3d v = new Vector3d(sEnd);
+            v.sub(sStart);
+            v.normalize();
+            v.scale(component.getPipeRun().getPipeDiameter()*0.5);
+            p.add(v);
+        } else if (p == sEnd) {
+            Vector3d v = new Vector3d(sStart);
+            v.sub(sEnd);
+            v.normalize();
+            v.scale(component.getPipeRun().getPipeDiameter()*0.5);
+            p.add(v);
+        }
+           
+           P3DRootNode root = (P3DRootNode)component.getRootNode();
+        InlineComponent branchSplit = ComponentUtils.createBranchSplit(root);
+        String branchName = component.getPipeRun().getUniqueName("Branch");
+        branchSplit.setName(branchName);
+        component.getPipeRun().addChild(branchSplit);
+        PipeControlPoint branchSplitCP = branchSplit.getControlPoint();
+        branchSplitCP.setWorldPosition(p);
+        PipingRules.splitVariableLengthComponent(branchSplit, component, false);
+        return branchSplit;
+    }
 }