X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.plant3d%2Fsrc%2Forg%2Fsimantics%2Fplant3d%2Factions%2FRoutePipeAction.java;h=389f3be5de60484f4370dbf3aafe3a14cc9fa746;hb=96b67feb92c117c72fb823b6fff5f89afa7ee631;hp=24b6a14bdfcef66fd5c1df8876fa6c14ac2fe0ff;hpb=53d55c24c779745f188bdb18d32f71d20acb61b2;p=simantics%2F3d.git diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java b/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java index 24b6a14b..389f3be5 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java @@ -13,20 +13,27 @@ import javax.vecmath.Point3d; import javax.vecmath.Tuple3d; import javax.vecmath.Vector3d; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Label; +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.toolbar.ToolComposite; 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; @@ -47,34 +54,39 @@ import vtk.vtkTextActor; public class RoutePipeAction extends vtkSwtAction { enum LockType { - X, Y, Z, XY, YZ, XZ, NONE, CUSTOM + X, Y, Z, XY, XZ, YZ, NONE, CUSTOM }; LockType lock = LockType.NONE; + boolean lockForced; private double BRANCH_SNAP_DISTANCE = 0.05; private double NOZZLE_SNAP_DISTANCE = 0.05; + private static double BRANCH_DOT_PRODUCT = 0.95; // dot product value used for prevent branch creation + private static double ALIGN_DOT_PRODUCT = 0.99; // dot product for creating turn when connecting pipes private double istep = 10.0; 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 nodeMap; + private NodeMap 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 +98,26 @@ public class RoutePipeAction extends vtkSwtAction { private Set allowed = new HashSet(); + protected ToolComposite toolComposite; + protected Combo axisCombo; + protected Button cameraButton; - public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root) { + public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root, ToolComposite toolComposite) { + this(panel,root, toolComposite, true); + } + + public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root, ToolComposite toolComposite, 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); + this.toolComposite = toolComposite; } public void setComponent(PipelineComponent component) { @@ -104,24 +127,74 @@ 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().isFixedLength()) allowed.add(PositionType.SPLIT); setEnabled(allowed.size() > 0); } - public void deattach() { - deactivate(); - startComponent = null; - nodeMap.commit("Route pipe"); - deattachUI(); - super.deattach(); - panel.refresh(); - } + protected void createTools(ToolComposite toolComposite) { + Label label = new Label(toolComposite, SWT.READ_ONLY); + label.setText("Route direction:"); + axisCombo = new Combo(toolComposite, SWT.READ_ONLY); + axisCombo.add("X"); + axisCombo.add("Y"); + axisCombo.add("Z"); + axisCombo.add("XY"); + axisCombo.add("XZ"); + axisCombo.add("YZ"); + axisCombo.add("None"); + axisCombo.add("Custom"); + axisCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + Combo c = (Combo)e.getSource(); + setLockType(LockType.values()[c.getSelectionIndex()],false); + panel.getComponent().setFocus(); + + } + }); + axisCombo.select(lock.ordinal()); + cameraButton = new Button(toolComposite, SWT.TOGGLE); + cameraButton.setText("Camera"); + cameraButton.setSelection(useDefault); + cameraButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setUseDefault(((Button)e.getSource()).getSelection()); + panel.getComponent().setFocus(); + } + }); + Button close = new Button(toolComposite, SWT.PUSH); + close.setText("Close"); + close.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + panel.useDefaultAction(); + }; + }); + toolComposite.relayout(); + } + + public void deattach() { + deactivate(); + if (toolComposite != null) { + toolComposite.clear(); + axisCombo = null; + cameraButton = null; + } + + startComponent = null; + + deattachUI(); + super.deattach(); + panel.refresh(); + } public void attach() { if (startComponent == null) return; - + if (toolComposite != null) { + createTools(toolComposite); + } super.attach(); ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() { public void run() { @@ -152,6 +225,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,13 +235,13 @@ public class RoutePipeAction extends vtkSwtAction { panel.unlock(); } - private List added = new ArrayList(); + protected List added = new ArrayList(); @Override public boolean keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) panel.useDefaultAction(); - if (lock != LockType.CUSTOM) { + if (lock != LockType.CUSTOM || !lockForced) { if ((e.getModifiersEx() & KeyEvent.SHIFT_DOWN_MASK) > 0) { if (e.getKeyCode() == KeyEvent.VK_X) { if (lock != LockType.XY && lock != LockType.XZ) { @@ -214,20 +289,30 @@ public class RoutePipeAction extends vtkSwtAction { else setLockType(LockType.NONE, false); } + if (e.getKeyCode() == KeyEvent.VK_L && direction != null) { + if (lock != LockType.CUSTOM) + setLockType(LockType.CUSTOM, false); + else + setLockType(LockType.NONE, false); + } } } if (e.getKeyCode() == KeyEvent.VK_C) { - useDefault = !useDefault; - System.out.println("UseDefault " + useDefault); + setUseDefault(!useDefault); } - - - update(); return true; } + private void setUseDefault(boolean b) { + useDefault = b; + if (useDefault) + setInfoText("Rotating camera"); + if (cameraButton != null) + cameraButton.setSelection(useDefault); + } + private void update() { panel.refresh(); @@ -251,7 +336,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,9 +372,9 @@ 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); + start = start.getDualSub(); else if (reversed && start.isDualSub()) start = start.parent; @@ -300,14 +385,17 @@ public class RoutePipeAction extends vtkSwtAction { if (startComponent instanceof Nozzle) { direction = startComponent.getControlPoint().getDirectedControlPointDirection(); lock = LockType.CUSTOM; + lockForced = true; } else if (startComponent instanceof PipelineComponent){ if (startComponent instanceof InlineComponent) { direction = startComponent.getControlPoint().getPathLegDirection(reversed ? Direction.PREVIOUS : Direction.NEXT); lock = LockType.CUSTOM; + lockForced = true; if (((InlineComponent) startComponent).isVariableLength()) { startWithTurn = true; direction = null; lock = LockType.NONE; + lockForced = false; } Vector3d v = new Vector3d(); if (!reversed) { @@ -316,12 +404,14 @@ public class RoutePipeAction extends vtkSwtAction { start.getControlPointEnds(previousPosition,v); } } else if (startComponent instanceof TurnComponent) { - if (start.isFixed()) { + if (start.asFixedAngle()) { direction = startComponent.getControlPoint().getPathLegDirection(reversed ? Direction.PREVIOUS : Direction.NEXT); lock = LockType.CUSTOM; + lockForced = start.isFixedAngle(); } else { direction = null; lock = LockType.NONE; + lockForced = false; } } else if (startComponent instanceof EndComponent) { throw new Exception("Not supported"); @@ -361,9 +451,10 @@ public class RoutePipeAction extends vtkSwtAction { translateAxisGizmo.attach(panel); setPreviousPosition(previousPosition); updateCurrentPoint(); + updateWidget(); } - private void setPreviousPosition(Vector3d v) { + protected void setPreviousPosition(Vector3d v) { previousPosition = new Vector3d(v); if (translateAxisGizmo.isAttached()) translateAxisGizmo.setPosition(previousPosition); @@ -407,6 +498,7 @@ public class RoutePipeAction extends vtkSwtAction { translateAxisGizmo.attach(panel); setPreviousPosition(previousPosition); updateCurrentPoint(); + updateWidget(); } private void activateSplit(PipeControlPoint start) throws Exception{ @@ -418,11 +510,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,13 +543,15 @@ public class RoutePipeAction extends vtkSwtAction { startRemovable = false; detector.clearConstraintHighlights(); state = ToolState.NOT_ACTIVE; - setEnabled(false); - + setEnabled(false); } private void setLockType(LockType type, boolean force) { - if (force || lock != LockType.CUSTOM) { + if (type == LockType.CUSTOM && (direction == null || added.size() > 0)) { + // nothing to do.. + } else if (force || (lock != LockType.CUSTOM || !lockForced || added.size() > 0) ) { + lock = type; switch (lock) { @@ -473,7 +579,16 @@ public class RoutePipeAction extends vtkSwtAction { break; } + } + updateWidget(); + } + + private void updateWidget() { + if (axisCombo != null) { + axisCombo.select(lock.ordinal()); + axisCombo.setEnabled(!lockForced || lock != LockType.CUSTOM); + } } @Override @@ -520,7 +635,7 @@ public class RoutePipeAction extends vtkSwtAction { addPoint(); } } else { - throw new RuntimeException("kjf"); + throw new RuntimeException("RoutePipeAction initialization has failed, no added components found"); // // user was selecting position of branch // lastPoint.set(startPoint); // controlPoints.add(new Point3d(startPoint)); @@ -529,7 +644,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 +710,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 +775,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 +799,14 @@ public class RoutePipeAction extends vtkSwtAction { - INode hoverObject = null; + List 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,13 +831,15 @@ 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 { updateRoute(o,d); } } else { - if (hoverObject instanceof InlineComponent && ((InlineComponent)hoverObject).isVariableLength() && (endType = endingLockToStraight(hoverObject,mu)) != null) { + if (hoverObject instanceof InlineComponent && ((InlineComponent)hoverObject).isVariableLength() && (endType = endingLockToStraight(hoverObject,mu, new Point3d(currentPosition))) != null) { endTo = (InlineComponent)hoverObject; } else if (hoverObject instanceof Nozzle && endingLockToNozzle(hoverObject)) { endTo = (Nozzle)hoverObject; @@ -716,7 +859,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); @@ -774,6 +917,7 @@ public class RoutePipeAction extends vtkSwtAction { return true; } + @SuppressWarnings("unused") private Vector3d getLockDir() { switch (lock) { case CUSTOM: @@ -784,11 +928,12 @@ public class RoutePipeAction extends vtkSwtAction { return new Vector3d(0,1,0); case Z: return new Vector3d(0,0,1); + default: + return null; } - 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,28 +1020,32 @@ 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(); Point3d sEnd = new Point3d(); s.getEnds(sStart, sEnd); //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)); if (p != null) { currentPosition = new Vector3d(p); // snapping is detected, check if snapped point can create branch with straight - PositionType t = endingLockToStraight(s, mu); + PositionType t = endingLockToStraight(s, mu, currentPipePoint); 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,71 +1061,104 @@ 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); - connectPrev = true; - } - else if (mu[0] > 1.0) { - currentPosition.set(sEnd); - connectNext = true; - } - boolean connect = false; - if (connectPrev) { - PipeControlPoint pcp = s.getControlPoint(); - if (pcp.getPrevious() == null) - connect = true; - } else if (connectNext) { - PipeControlPoint pcp = s.getControlPoint(); - if (pcp.getNext() == null) - connect = true; - } - - updateCurrentPoint(); - - if (connect) - info += "Connect pipes :"; - else - info += "Make 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; - } - - } - return PositionType.SPLIT; - + return endingToStraight(mu, s, sStart, sEnd, currentPipePoint); + } + + private PositionType endingToStraight(double mu[], InlineComponent s, Point3d sStart, Point3d sEnd , Point3d currentPipePoint) { + String info = ""; + + boolean connectPrev = false; + boolean connectNext = false; + boolean branch = false; + if (mu[0] < 0.1) { + connectPrev = true; + } + else if (mu[0] > 0.9) { + connectNext = true; + } + + + if (connectPrev) { + PipeControlPoint pcp = s.getControlPoint(); + if (pcp.getPrevious() != null) + connectPrev = false; + } else if (connectNext) { + PipeControlPoint pcp = s.getControlPoint(); + 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 > BRANCH_DOT_PRODUCT || dot < -BRANCH_DOT_PRODUCT) { + // pipes are almost in the same direction, creating a branch is not feasible. + branch = false; + } else { + branch = true; + } + } + + + if (connectNext || connectPrev) + info += "Connect pipes :"; + else if (branch) + info += "Create a Branch :"; + + setInfoText(info + currentPosition + " " + Math.max(0.0, Math.min(mu[0], 1.0))); + if (connectNext) { + currentPosition.set(sEnd); + updateCurrentPoint(); + return PositionType.NEXT; + } else if (connectPrev){ + currentPosition.set(sStart); + updateCurrentPoint(); + return PositionType.PREVIOUS; + } else if (branch && allowBranches) { + return PositionType.SPLIT; + } else { + currentPosition.set(currentPipePoint); + updateCurrentPoint(); + return null; + } } private PipeControlPoint endingToComponent(INode componentNode, Vector3d o, Vector3d d) { PipelineComponent component = (PipelineComponent)componentNode; PipeControlPoint pcp = component.getControlPoint(); + PipeControlPoint connect = null; if (component instanceof EndComponent) { if (pcp.getNext() != null || pcp.getPrevious() != null) return null; - return pcp; + connect = pcp; } else if (component instanceof TurnComponent) { if (pcp.getNext() == null || pcp.getPrevious() == null) - return pcp; - return null; + connect = pcp; + else + return null; } else if (component instanceof InlineComponent) { // TODO : scan all empty pcps of the component and select closest one. if (pcp.getNext() == null || pcp.getPrevious() == null) - return pcp; - return null; + connect = pcp; + else + return null; + } + if (connect != null) { + currentPosition.set(connect.getWorldPosition()); + updateCurrentPoint(); + setInfoText("Connect to " + component.getName()); + return connect; } - return null; } - private PositionType endingLockToStraight(INode straightNode, double mu[]) { + private PositionType endingLockToStraight(INode straightNode, double mu[], Point3d currentPipePoint) { +// if (!allowBranches) { +// updateCurrentPoint(); +// return null; +// } InlineComponent s = (InlineComponent)straightNode; Point3d sStart = new Point3d(); Point3d sEnd = new Point3d(); @@ -995,15 +1177,21 @@ public class RoutePipeAction extends vtkSwtAction { // 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 other - if (mu[0] > 0.0 && mu[0] < 1.0 && routePoint.lengthSquared() < BRANCH_SNAP_DISTANCE) { - currentPosition.set(branchPoint); - - updateCurrentPoint(); - - setInfoText("Make branch (l) :" + currentPosition + " " + Math.max(0.0, Math.min(mu[0], 1.0)) + " " + routePoint.lengthSquared()); - return PositionType.SPLIT; - } - return null; + + if (routePoint.lengthSquared() > BRANCH_SNAP_DISTANCE) + return null; + + return endingToStraight(mu, s, sStart, sEnd, currentPipePoint); + +// if (mu[0] > 0.0 && mu[0] < 1.0 && routePoint.lengthSquared() < BRANCH_SNAP_DISTANCE) { +// currentPosition.set(branchPoint); +// +// updateCurrentPoint(); +// +// setInfoText("Create a branch (l) :" + currentPosition + " " + Math.max(0.0, Math.min(mu[0], 1.0)) + " " + routePoint.lengthSquared()); +// return PositionType.SPLIT; +// } +// return null; } private boolean endingLockToNozzle(INode nozzleNode) { @@ -1031,40 +1219,64 @@ public class RoutePipeAction extends vtkSwtAction { return null; } - private void addPoint() throws Exception { - InlineComponent previous = (InlineComponent)getLast(); - PipeControlPoint previousCP = previous.getControlPoint(); - TurnComponent turn = ComponentUtils.createTurn(root); - InlineComponent straight = ComponentUtils.createStraight(root); - PipeControlPoint turnCP = turn.getControlPoint(); - PipeControlPoint straightCP = straight.getControlPoint(); - straight.setName(pipeRun.getUniqueName("Pipe")); - turn.setName(pipeRun.getUniqueName("Elbow")); - pipeRun.addChild(turn); - pipeRun.addChild(straight); - added.add(turn); - added.add(straight); - - turnCP.setDeletable(false); // mark turnCP nonDeletable so that PipingRules won't delete it immediately. - - if (!reversed) { - previousCP.setNext(turnCP); - turnCP.setPrevious(previousCP); - turnCP.setNext(straightCP); - straightCP.setPrevious(turnCP); - } else { - previousCP.setPrevious(turnCP); - turnCP.setNext(previousCP); - turnCP.setPrevious(straightCP); - straightCP.setNext(turnCP); - } - - turnCP.setWorldPosition(currentPosition); - turnCP.setTurnAngle(0.0); - turnCP.setLength(0.0); - straightCP.setWorldPosition(currentPosition); - straightCP.setLength(0.0); - + protected void addTurn() throws Exception{ + InlineComponent previous = (InlineComponent)getLast(); + PipeControlPoint previousCP = previous.getControlPoint(); + TurnComponent turn = ComponentUtils.createTurn(root); + PipeControlPoint turnCP = turn.getControlPoint(); + turn.setName(pipeRun.getUniqueName("Elbow")); + pipeRun.addChild(turn); + added.add(turn); + turnCP.setDeletable(false); // mark turnCP nonDeletable so that PipingRules won't delete it immediately. + if (!reversed) { + previousCP.setNext(turnCP); + turnCP.setPrevious(previousCP); + } else { + previousCP.setPrevious(turnCP); + turnCP.setNext(previousCP); + } + + turnCP.setWorldPosition(currentPosition); + turnCP.setTurnAngle(0.0); + turnCP.setLength(0.0); + + } + + protected void addStraight() throws Exception{ + TurnComponent turn = (TurnComponent)getLast(); + PipeControlPoint turnCP = turn.getControlPoint(); + + InlineComponent straight = ComponentUtils.createStraight(root); + + PipeControlPoint straightCP = straight.getControlPoint(); + straight.setName(pipeRun.getUniqueName("Pipe")); + + + pipeRun.addChild(straight); + + added.add(straight); + + + + if (!reversed) { + turnCP.setNext(straightCP); + straightCP.setPrevious(turnCP); + } else { + turnCP.setPrevious(straightCP); + straightCP.setNext(turnCP); + } + + turnCP.setWorldPosition(currentPosition); + turnCP.setTurnAngle(0.0); + turnCP.setLength(0.0); + straightCP.setWorldPosition(currentPosition); + straightCP.setLength(0.0); + + } + + protected void addPoint() throws Exception { + addTurn(); + addStraight(); setPreviousPosition(currentPosition); updateCurrentPoint(); @@ -1075,7 +1287,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,10 +1340,22 @@ public class RoutePipeAction extends vtkSwtAction { } - private void endPiping() throws Exception { + protected void endPiping() throws Exception { state = ToolState.NOT_ACTIVE; if (endTo != null) { + if (endType == PositionType.NEXT || endType == PositionType.PREVIOUS && endTo instanceof InlineComponent) { + Vector3d dir = endTo.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 < ALIGN_DOT_PRODUCT && dot> -ALIGN_DOT_PRODUCT) { + addTurn(); + } + + } ComponentUtils.connect(getLast(), endTo, endType, currentPosition); } panel.useDefaultAction();