]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java
Use INode instead of IG3DNode in selections
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / actions / RoutePipeAction.java
index 24b6a14bdfcef66fd5c1df8876fa6c14ac2fe0ff..0f82184bbda8ed287be0c2a0fee8e9c3067cf788 100644 (file)
@@ -13,20 +13,20 @@ import javax.vecmath.Point3d;
 import javax.vecmath.Tuple3d;
 import javax.vecmath.Vector3d;
 
+import org.simantics.db.Resource;
 import org.simantics.g3d.math.MathTools;
 import org.simantics.g3d.math.Ray;
 import org.simantics.g3d.scenegraph.NodeMap;
 import org.simantics.g3d.scenegraph.base.INode;
 import org.simantics.g3d.tools.ConstraintDetector;
-import org.simantics.g3d.tools.DummyConstraintDetector;
 import org.simantics.g3d.vtk.gizmo.TranslateAxisGizmo;
 import org.simantics.g3d.vtk.swt.InteractiveVtkComposite;
 import org.simantics.g3d.vtk.swt.vtkSwtAction;
 import org.simantics.g3d.vtk.utils.vtkUtil;
 import org.simantics.plant3d.Activator;
+import org.simantics.plant3d.gizmo.ConstraintPointGizmo;
 import org.simantics.plant3d.gizmo.SplitPointSelectionGizmo;
 import org.simantics.plant3d.gizmo.TerminalSelectionGizmo;
-import org.simantics.plant3d.ontology.Plant3D;
 import org.simantics.plant3d.scenegraph.EndComponent;
 import org.simantics.plant3d.scenegraph.InlineComponent;
 import org.simantics.plant3d.scenegraph.Nozzle;
@@ -58,23 +58,25 @@ public class RoutePipeAction extends vtkSwtAction {
        private int decimals = 2;
 
        private P3DRootNode root;
-       private PipelineComponent startComponent;
-       private PipeRun pipeRun;
+       protected PipelineComponent startComponent;
+       protected PipeRun pipeRun;
+       private boolean allowBranches;
 
-       private TranslateAxisGizmo translateAxisGizmo = new TranslateAxisGizmo();
+       protected TranslateAxisGizmo translateAxisGizmo = new TranslateAxisGizmo();
        private SplitPointSelectionGizmo splitPointSelectionGizmo;
+       private ConstraintPointGizmo constraintPointGizmo;
        private TerminalSelectionGizmo terminalSelectionGizmo;
-       private NodeMap<vtkProp,INode> nodeMap;
+       private NodeMap<Resource,vtkProp,INode> nodeMap;
        
-       private enum ToolState{NOT_ACTIVE, INITIALIZING, SELECTING_POSITION, SELECTING_SPLIT, ROUTING};
-       private ToolState state = ToolState.NOT_ACTIVE;
+       protected enum ToolState{NOT_ACTIVE, INITIALIZING, SELECTING_POSITION, SELECTING_SPLIT, ROUTING};
+       protected ToolState state = ToolState.NOT_ACTIVE;
        
-       private ConstraintDetector detector = new DummyConstraintDetector();
+       private ConstraintDetector detector;// = new DummyConstraintDetector();
        
-       private boolean useDefault = false;
-       private Vector3d direction = null;
-       private Vector3d previousPosition = null;
-       private Vector3d currentPosition = null;
+       protected boolean useDefault = false;
+       protected Vector3d direction = null;
+       protected Vector3d previousPosition = null;
+       protected Vector3d currentPosition = null;
        
        boolean step = false;
        
@@ -86,15 +88,21 @@ public class RoutePipeAction extends vtkSwtAction {
        
        private Set<PositionType> allowed = new HashSet<PositionType>();
        
-       
        public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root) {
+           this(panel,root, true);
+       }
+       
+       public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root, boolean allowBranches) {
                super(panel);
                this.root = root;
+               this.allowBranches = allowBranches;
                setText("Route Pipe");
                setImageDescriptor(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Straight.png"));
                nodeMap = root.getNodeMap();
                splitPointSelectionGizmo = new SplitPointSelectionGizmo(panel);
                terminalSelectionGizmo = new TerminalSelectionGizmo(panel);
+               constraintPointGizmo = new ConstraintPointGizmo(panel);
+               detector = new org.simantics.g3d.vtk.swt.ConstraintDetector(panel);
        }
        
        public void setComponent(PipelineComponent component) {
@@ -104,7 +112,7 @@ public class RoutePipeAction extends vtkSwtAction {
                        allowed.add(PositionType.NEXT);
                if (this.startComponent.getPrevious() == null && !(this.startComponent instanceof Nozzle))
                        allowed.add(PositionType.PREVIOUS);
-               if (this.startComponent instanceof InlineComponent && !this.startComponent.getControlPoint().isFixed())
+               if (allowBranches && this.startComponent instanceof InlineComponent && !this.startComponent.getControlPoint().isFixed())
                        allowed.add(PositionType.SPLIT);
                setEnabled(allowed.size() > 0);
        }
@@ -112,7 +120,7 @@ public class RoutePipeAction extends vtkSwtAction {
        public void deattach() {
                deactivate();
                startComponent = null;
-               nodeMap.commit("Route pipe");
+               
                deattachUI();
                super.deattach();
                panel.refresh();
@@ -152,6 +160,8 @@ public class RoutePipeAction extends vtkSwtAction {
                        splitPointSelectionGizmo.deattach();
                if (terminalSelectionGizmo.isAttached())
                        terminalSelectionGizmo.deattach();
+               if (constraintPointGizmo.isAttached())
+                   constraintPointGizmo.deattach();
                if (infoActor != null) {
                        panel.getRenderer().RemoveActor(infoActor);
                        infoActor.Delete();
@@ -160,7 +170,7 @@ public class RoutePipeAction extends vtkSwtAction {
                panel.unlock();
        }
        
-       private List<PipelineComponent> added = new ArrayList<PipelineComponent>();
+       protected List<PipelineComponent> added = new ArrayList<PipelineComponent>();
        
        @Override
        public boolean keyPressed(KeyEvent e) {
@@ -251,7 +261,7 @@ public class RoutePipeAction extends vtkSwtAction {
        
        boolean startRemovable = false;
        
-       private void activate() throws Exception {
+       protected void activate() throws Exception {
                state = ToolState.INITIALIZING;
                added.clear();
                
@@ -287,7 +297,7 @@ public class RoutePipeAction extends vtkSwtAction {
        
        
        
-       private void activateNextPrev(PipeControlPoint start) throws Exception{
+       protected void activateNextPrev(PipeControlPoint start) throws Exception{
                if (!reversed && start.isDualInline())
                        start = start.getSubPoint().get(0);
                else if (reversed && start.isDualSub())
@@ -363,7 +373,7 @@ public class RoutePipeAction extends vtkSwtAction {
                updateCurrentPoint();
        }
        
-       private void setPreviousPosition(Vector3d v) {
+       protected void setPreviousPosition(Vector3d v) {
                previousPosition = new Vector3d(v);
                if (translateAxisGizmo.isAttached())
                        translateAxisGizmo.setPosition(previousPosition);
@@ -418,11 +428,23 @@ public class RoutePipeAction extends vtkSwtAction {
                state = ToolState.SELECTING_SPLIT;
        }
        public void deactivate() {
-               for (PipelineComponent component : added) {
-                       component.getControlPoint().setDeletable(true);
-               }
+           if (added.size() > 0) {
+           for (PipelineComponent component : added) {
+                       component.getControlPoint().setDeletable(true);
+               }
+               
+            for (PipelineComponent comp : added) {
+                PipingRules.requestUpdate(comp.getControlPoint());
+            }
+            try {
+                PipingRules.update();
+                nodeMap.commit("Route pipe");
+            } catch (Exception e) {
+                ExceptionUtils.logAndShowError(e);
+            }
+            added.clear();        
+        }
                
-               added.clear();
                startComponent.getControlPoint().setDeletable(startRemovable);
 
                direction = null;
@@ -439,8 +461,7 @@ public class RoutePipeAction extends vtkSwtAction {
                startRemovable = false;
                detector.clearConstraintHighlights();
                state = ToolState.NOT_ACTIVE;
-               setEnabled(false);
-               
+               setEnabled(false);              
 
        }
        
@@ -520,7 +541,7 @@ public class RoutePipeAction extends vtkSwtAction {
                                                                addPoint();
                                                        }
                                                } else {
-                                                       throw new RuntimeException("kjf");
+                                                       throw new RuntimeException("RoutePipeAction initlialization has been failed, no added components found");
                //                      // user was selecting position of branch
                //                    lastPoint.set(startPoint);
                //                    controlPoints.add(new Point3d(startPoint));
@@ -529,7 +550,7 @@ public class RoutePipeAction extends vtkSwtAction {
                //                    selectionLine = null;
                                                }
                                        } else if (e.getButton() ==MouseEvent.BUTTON2){
-               //                detector.updateConstraintReference();
+                                           updateConstraints();
                                        } else if (e.getButton() == MouseEvent.BUTTON3){      
                                                endPiping();
                                        }
@@ -595,6 +616,39 @@ public class RoutePipeAction extends vtkSwtAction {
                return true;
        }
        
+       private void updateConstraints() {
+           detector.clearConstraints();
+           constraintPointGizmo.clearPositions();
+           if (hoverObject == null) {
+               if (constraintPointGizmo.isAttached())
+                   constraintPointGizmo.deattach();
+               return;
+           }
+           if (hoverObject instanceof Nozzle) {
+            Nozzle n = (Nozzle)hoverObject;
+            detector.addContraintPoint(new Point3d(n.getWorldPosition()));
+           } else if (hoverObject instanceof InlineComponent) {
+               InlineComponent c = (InlineComponent)hoverObject;
+               Point3d p1 = new Point3d();
+               Point3d p2 = new Point3d();
+               c.getEnds(p1, p2);
+               detector.addContraintPoint(p1);
+               detector.addContraintPoint(p2);
+               detector.addContraintPoint(new Point3d(c.getWorldPosition()));
+           } else if (hoverObject instanceof TurnComponent) {
+               TurnComponent n = (TurnComponent)hoverObject;
+            detector.addContraintPoint(new Point3d(n.getWorldPosition()));
+           }
+           if (detector.getConstraintPoints().size() > 0) {
+               for (Point3d p : detector.getConstraintPoints()) {
+                   constraintPointGizmo.addPosition(new Vector3d(p));
+               }
+               if (constraintPointGizmo.isAttached())
+                   constraintPointGizmo.deattach();
+               constraintPointGizmo.attach(panel);
+           }
+       }
+       
        @Override
        public boolean mouseMoved(MouseEvent e) {
                if (useDefault) {
@@ -627,18 +681,9 @@ public class RoutePipeAction extends vtkSwtAction {
                return nodes;
        }
        
+       INode hoverObject = null;
 
-
-       private void updateRouting(double x, double y) {
-//             if(input.keyPressed(KeyEvent.VK_ESCAPE)) {
-//                     controlPoints.clear();
-//                     end();
-//                     return;
-//             }
-//             if (input.keyPressed(KeyEvent.VK_C)) {
-//                     useCamera = !useCamera;
-//                     cameraAction.setChecked(useCamera);
-//             }
+       protected void updateRouting(double x, double y) {
                if (useDefault) {
                        //panel.getDefaultAction().update();
                        return;
@@ -660,12 +705,14 @@ public class RoutePipeAction extends vtkSwtAction {
                
                
                
-               INode hoverObject = null;
+               
                
                List<INode> hover = isOverNode((int)x,(int)y);
                if (hover.size() > 0) {
                        hoverObject = hover.get(0);
-               } 
+               } else {
+                   hoverObject = null;
+               }
 //             System.out.println(hoverObject + " " + getLast());
                if (hoverObject != null) {
                        if (hoverObject.equals(getLast()) ) {
@@ -690,6 +737,8 @@ public class RoutePipeAction extends vtkSwtAction {
                                } else if (hoverObject instanceof InlineComponent && ((InlineComponent)hoverObject).isVariableLength()) {
                                        endTo = (InlineComponent)hoverObject;
                                        endType = endingToStraight(endTo,mu,o,d);     
+                                       if (endType == null)
+                                           endTo = null;
                                } else if (hoverObject instanceof PipelineComponent && (endPort = endingToComponent(hoverObject,o,d)) != null) {
                                        endTo = (PipelineComponent)hoverObject;
                                } else {
@@ -716,7 +765,7 @@ public class RoutePipeAction extends vtkSwtAction {
                panel.refresh();
        }
        
-       private boolean updateCurrentPoint(Vector3d o, Vector3d d) {
+       protected boolean updateCurrentPoint(Vector3d o, Vector3d d) {
 
                Vector3d point = new Vector3d(this.previousPosition);
                
@@ -788,7 +837,7 @@ public class RoutePipeAction extends vtkSwtAction {
                return null;
        }
        
-       private void updateRoute(Vector3d o, Vector3d d) {
+       protected void updateRoute(Vector3d o, Vector3d d) {
                detector.clearConstraintHighlights();
                Point3d previousPipePoint = new Point3d(previousPosition);
                String s = "";
@@ -875,6 +924,10 @@ public class RoutePipeAction extends vtkSwtAction {
        }
        
        private PositionType endingToStraight(INode straightNode, double mu[], Vector3d o, Vector3d d) {
+           if (!allowBranches) {
+               updateCurrentPoint();
+            return null;
+           }
                InlineComponent s = (InlineComponent)straightNode;
                String info = "";
                Point3d sStart = new Point3d();
@@ -883,6 +936,7 @@ public class RoutePipeAction extends vtkSwtAction {
                //detector.clearConstraintHighlights();
                
                Point3d previousPipePoint = new Point3d(previousPosition);
+               Point3d currentPipePoint = new Point3d(currentPosition);
                //String st = "";
                if (lock == LockType.NONE) {
                        Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint));
@@ -893,10 +947,9 @@ public class RoutePipeAction extends vtkSwtAction {
                                if (t != null)
                                        return t;
                                // if not, we'll have to remove highlight that was added when snapped point was detected
-                               detector.clearConstraintHighlights();
-                       } 
+                               detector.clearConstraintHighlights();   
+                       }
                        
-
                        Vector3d sDir = new Vector3d(sEnd);
                        sDir.sub(sStart);
                        MathTools.intersectStraightStraight(sStart, sDir, o, d, currentPosition, new Point3d(), mu);
@@ -912,46 +965,63 @@ public class RoutePipeAction extends vtkSwtAction {
                // branch point must lie between straight's ends. If connection point is exactly
                // on straight end user may want to connect pipes to each other
                // TODO : take account sizes of inline components)
-               // TODO : actually make connection if its detected
+               
                boolean connectPrev = false;
                boolean connectNext = false;
-               
-               if (mu[0] < 0.0) {
-                       currentPosition.set(sStart);
+               boolean branch = false;
+               if (mu[0] < 0.1) {
                        connectPrev = true;
                }
-               else if (mu[0] > 1.0) {
-                       currentPosition.set(sEnd);
+               else if (mu[0] > 0.9) {
                        connectNext = true;
                }
-               boolean connect = false;
+
+                 
                if (connectPrev) {
                        PipeControlPoint pcp = s.getControlPoint();
-                       if (pcp.getPrevious() == null)
-                               connect = true;
+                       if (pcp.getPrevious() != null)
+                               connectPrev = false;
                } else if (connectNext) {
                        PipeControlPoint pcp = s.getControlPoint();
-                       if (pcp.getNext() == null)
-                               connect = true;
+                       if (pcp.getNext() != null)
+                               connectNext = false;
+               } else {
+                   Vector3d dir = s.getControlPoint().getPathLegDirection(Direction.NEXT);
+                   Vector3d currDir = getLast().getControlPoint().getPathLegDirection(Direction.NEXT);
+                   dir.normalize();
+                   currDir.normalize();
+                   double dot = dir.dot(currDir);
+                   System.out.println(dot + " " + currDir + " " + dir);
+                   if (dot > 0.95 || dot < -0.95) {
+                       // pipes are almost in the same direction, creating a branch is not feasible.
+                       branch = false;
+                   } else {
+                       branch = true;
+                   }
                }
                
-               updateCurrentPoint();
-               
-               if (connect)
+                       
+               if (connectNext || connectPrev)
                        info += "Connect pipes :";
-               else
-                       info += "Make Branch :";
+               else if (branch)
+                       info += "Create a Branch :";
                
                setInfoText(info + currentPosition + " " + Math.max(0.0, Math.min(mu[0], 1.0)));
-               if (connect) {
-                       if (connectNext) {
-                               return PositionType.NEXT;
-                       } else {
-                               return PositionType.PREVIOUS;
-                       }
-                               
+               if (connectNext) {
+                   currentPosition.set(sEnd);
+                   updateCurrentPoint();
+                       return PositionType.NEXT;
+               } else if (connectPrev){
+                   currentPosition.set(sStart);
+                   updateCurrentPoint();
+                       return PositionType.PREVIOUS;
+               } else if (branch) {
+                   return PositionType.SPLIT;
+               } else {
+                   currentPosition.set(currentPipePoint);
+                   updateCurrentPoint();
+                   return null;
                }
-               return PositionType.SPLIT;
                        
        }
        
@@ -977,6 +1047,10 @@ public class RoutePipeAction extends vtkSwtAction {
        }
        
        private PositionType endingLockToStraight(INode straightNode, double mu[]) {
+           if (!allowBranches) {
+            updateCurrentPoint();
+            return null;
+        }
                InlineComponent s = (InlineComponent)straightNode;
                Point3d sStart = new Point3d();
                Point3d sEnd = new Point3d(); 
@@ -1000,7 +1074,7 @@ public class RoutePipeAction extends vtkSwtAction {
                        
                        updateCurrentPoint();
                        
-                       setInfoText("Make branch (l) :" + currentPosition + " " + Math.max(0.0, Math.min(mu[0], 1.0)) + " " + routePoint.lengthSquared());
+                       setInfoText("Create a branch (l) :" + currentPosition + " " + Math.max(0.0, Math.min(mu[0], 1.0)) + " " + routePoint.lengthSquared());
                        return PositionType.SPLIT;
                }
                return null;
@@ -1031,7 +1105,7 @@ public class RoutePipeAction extends vtkSwtAction {
                return null;
        }
        
-       private void addPoint() throws Exception {
+       protected void addPoint() throws Exception {
                InlineComponent previous = (InlineComponent)getLast();
                PipeControlPoint previousCP = previous.getControlPoint();
                TurnComponent turn = ComponentUtils.createTurn(root);
@@ -1075,7 +1149,7 @@ public class RoutePipeAction extends vtkSwtAction {
        /**
         * Updates tool graphics for current point 
         */
-       private void updateCurrentPoint() {
+       protected void updateCurrentPoint() {
                InlineComponent straight = (InlineComponent)added.get(added.size()-1);
                // TODO: the inline length is from previous update step.
                double l;
@@ -1128,7 +1202,7 @@ public class RoutePipeAction extends vtkSwtAction {
                
        }
        
-       private void endPiping() throws Exception {
+       protected void endPiping() throws Exception {
                state = ToolState.NOT_ACTIVE;
                
                if (endTo != null) {