]> gerrit.simantics Code Review - simantics/3d.git/commitdiff
SCL function for connecting pipeline components 31/3131/1
authorMarko Luukkainen <marko.luukkainen@semantum.fi>
Wed, 21 Aug 2019 07:46:28 +0000 (10:46 +0300)
committerMarko Luukkainen <marko.luukkainen@semantum.fi>
Wed, 21 Aug 2019 07:46:28 +0000 (10:46 +0300)
gitlab #28

Change-Id: I8ab03b0593d62824feb2a2b994a13376c6654d15

org.simantics.plant3d/scl/Plant3d/Utils/ComponentUtils.scl
org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java
org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java
org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java

index c3ef6365677dcd22fd347564c7f63edc47cd97b6..24b2e42c19c750654d0b9e015464eade386a71c7 100644 (file)
@@ -2,6 +2,7 @@ import "Plant3d/Scenegraph/PipelineComponent"
 import "Plant3d/Scenegraph/Equipment"
 import "Plant3d/Scenegraph/Nozzle"
 import "Plant3d/Scenegraph/P3DRootNode"
+import "G3D/Math/Vector3d"
 import "./P3DUtil"
 
 importJava "org.simantics.plant3d.utils.ComponentUtils" where
@@ -21,6 +22,12 @@ importJava "org.simantics.plant3d.utils.ComponentUtils" where
    @JavaName addComponent
    addComponent :: P3DRootNode -> PipelineComponent -> InsertInstruction -> <Proc> PipelineComponent
    
+   @JavaName connect
+   connect :: PipelineComponent -> PipelineComponent -> <Proc> Boolean
+   
+   @JavaName connect
+   connect2 :: PipelineComponent -> PipelineComponent -> PositionType -> Vector3d -> <Proc> Boolean
+   
 importJava "org.simantics.plant3d.utils.ComponentUtils$InsertInstruction" where
    data InsertInstruction
    
index c922f38f54a5a64eab9e5612d508605fa8c0f569..be82d85e3cd808eadd93be549d79724ac32cb94b 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.plant3d.actions;
 
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
+import java.awt.event.MouseWheelEvent;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -303,7 +304,7 @@ public class RoutePipeAction extends vtkSwtAction {
                        if (startComponent instanceof InlineComponent) {
                                direction = startComponent.getControlPoint().getPathLegDirection(reversed ? Direction.PREVIOUS : Direction.NEXT);
                                lock = LockType.CUSTOM;
-                               if (startComponent.getType().equals(Plant3D.URIs.Builtin_Straight)) {
+                               if (((InlineComponent) startComponent).isVariableLength()) {
                                        startWithTurn = true;
                                        direction = null;
                                        lock = LockType.NONE;
@@ -491,6 +492,14 @@ public class RoutePipeAction extends vtkSwtAction {
                return true;
        }
        
+       @Override
+       public boolean mouseWheelMoved(MouseWheelEvent e) {
+           if (useDefault) {
+            getDefaultAction().mouseWheelMoved(e);
+        }
+        return true;
+       }
+       
        @Override
        public boolean mouseClicked(MouseEvent e) {
                if (useDefault) {
@@ -563,7 +572,7 @@ public class RoutePipeAction extends vtkSwtAction {
                                }
                                try {
                                        Vector3d pos = new Vector3d(t);
-                                       InlineComponent branchSplit = createBranchSplit((InlineComponent)startComponent, pos);
+                                       InlineComponent branchSplit = ComponentUtils.createBranchSplit((InlineComponent)startComponent, pos);
                                        PipeControlPoint branchSplitCP = branchSplit.getControlPoint();
                                        reversed = false;
                                        PipeRun newRun = new PipeRun();
@@ -586,24 +595,13 @@ public class RoutePipeAction extends vtkSwtAction {
                return true;
        }
        
-       private InlineComponent createBranchSplit(InlineComponent component, Vector3d pos) throws Exception{
-               InlineComponent branchSplit = ComponentUtils.createBranchSplit(root);
-               String branchName = component.getPipeRun().getUniqueName("Branch");
-               branchSplit.setName(branchName);
-               component.getPipeRun().addChild(branchSplit);
-               PipeControlPoint branchSplitCP = branchSplit.getControlPoint();
-               branchSplitCP.setWorldPosition(pos);
-               PipingRules.splitVariableLengthComponent(branchSplit, component, false);
-               return branchSplit;
-       }
-       
        @Override
        public boolean mouseMoved(MouseEvent e) {
                if (useDefault) {
                        getDefaultAction().mouseMoved(e);
                        return true;
                }
-               step = ((e.getModifiers() & MouseEvent.CTRL_DOWN_MASK) > 0);
+               step = ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0);
                update(e.getX(), e.getY());
                return true;
        }
@@ -699,7 +697,7 @@ public class RoutePipeAction extends vtkSwtAction {
                                  }
                          } else {  
                                  if (hoverObject instanceof InlineComponent && ((InlineComponent)hoverObject).isVariableLength() && (endType = endingLockToStraight(hoverObject,mu)) != null) {
-                                         endTo = (InlineComponent)hoverObject;;
+                                         endTo = (InlineComponent)hoverObject;
                                  } else if (hoverObject instanceof Nozzle && endingLockToNozzle(hoverObject)) {
                                          endTo = (Nozzle)hoverObject;
                                  } else if ((hoverObject instanceof PipelineComponent) &&  ((endPort = endingLockToComponent(hoverObject)) != null)) {
@@ -809,6 +807,23 @@ public class RoutePipeAction extends vtkSwtAction {
                    s += detector.getSnapString();
 
                }
+               //System.out.println(previousPosition + " -> " + currentPosition);
+//             double dist = MathTools.distance(previousPosition, currentPosition);
+//             if (dist < pipeRun.getTurnRadius()) {
+//                 s += "Too close";
+//                 Vector3d v = new Vector3d(currentPosition);
+//                 v.sub(previousPosition);
+//                 double vl = v.length();
+//                 if (vl > MathTools.NEAR_ZERO) {
+//                     v.scale(1.0/vl);
+//                 } else {
+//                     
+//                     return;
+//                 }
+//                 v.scale(pipeRun.getTurnRadius());
+//                 v.add(previousPosition);
+//                 currentPosition.set(v);
+//             }
                
                updateCurrentPoint();
                s += currentPosition.toString();
@@ -963,8 +978,8 @@ public class RoutePipeAction extends vtkSwtAction {
            
            private PositionType endingLockToStraight(INode straightNode, double mu[]) {
                InlineComponent s = (InlineComponent)straightNode;
-               Point3d sStart = new Point3d();//G3DTools.getPoint(s.getHasControlPoint().getPreviousPoint().getLocalPosition());
-               Point3d sEnd = new Point3d(); //G3DTools.getPoint(s.getHasControlPoint().getNextPoint().getLocalPosition());
+               Point3d sStart = new Point3d();
+               Point3d sEnd = new Point3d(); 
                s.getControlPoint().getInlineControlPointEnds(sStart, sEnd);  
                Vector3d sDir = new Vector3d(sEnd);
                sDir.sub(sStart);
@@ -979,7 +994,7 @@ public class RoutePipeAction extends vtkSwtAction {
                routePoint.sub(branchPoint);
                // startPoint of branch must be between pipe ends
                // TODO : take account sizes of elbows (or other components)
-               // branch point must be between pipe ends and intersection points must be quite close to each othert
+               // branch point must be between pipe ends and intersection points must be quite close to each other
                if (mu[0] > 0.0 && mu[0] < 1.0 && routePoint.lengthSquared() < BRANCH_SNAP_DISTANCE) {
                    currentPosition.set(branchPoint);
                    
@@ -1113,80 +1128,7 @@ public class RoutePipeAction extends vtkSwtAction {
                state = ToolState.NOT_ACTIVE;
                 
                if (endTo != null) {
-                       PipeControlPoint endCP = endTo.getControlPoint();
-                       if (endType == null || endType == PositionType.NEXT || endType == PositionType.PREVIOUS) {
-                               
-                               PipelineComponent current = getLast();
-                               PipeControlPoint currentCP = current.getControlPoint();
-                               
-                               boolean requiresReverse = false;
-                               if (!reversed && endCP.getPrevious() != null) {
-                                       requiresReverse = true;
-                               } else if (reversed && endCP.getNext() != null) {
-                                       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();
-                               }
-                               
-                       } else if (endType == PositionType.SPLIT) {
-                               InlineComponent branchSplit = createBranchSplit((InlineComponent)endTo, currentPosition);
-                                       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());
-                                       
-                                       PipelineComponent current = getLast();
-                               PipeControlPoint currentCP = current.getControlPoint();
-                               
-                               
-                               if(!reversed) {
-                                       pcp.setPrevious(currentCP);
-                                       currentCP.setNext(pcp);
-                               } else {
-                                       pcp.setNext(currentCP);
-                                       currentCP.setPrevious(pcp);
-                               }
-                                       
-                       }
-                       PipingRules.positionUpdate(endCP);
+                   ComponentUtils.connect(getLast(), endTo, endType, currentPosition);
                }
                panel.useDefaultAction();
            }
index 8e3e6bbdc1c926d28270e3900f7d8648a7f01cf3..660558652c47c03c1897b7aa1a53761e6795a206 100644 (file)
@@ -1189,9 +1189,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode {
                }
                if (br0 != null) {
                    if (br0.getNext() == component)
-                       prev.setNext(null);
+                       br0.setNext(null);
                    else if (br0.getPrevious() == component)
-                prev.setPrevious(null);
+                       br0.setPrevious(null);
                    else if (br0.getBranch0() == component)
                        br0.setBranch0(null);
                }
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;
+    }
 }