X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.plant3d%2Fsrc%2Forg%2Fsimantics%2Fplant3d%2Factions%2FRoutePipeAction.java;h=dac9d2c11b004c428a5103116db1fd8c88eed920;hb=a1e1faa6915445e786f482170576b9c9d0f5d982;hp=c922f38f54a5a64eab9e5612d508605fa8c0f569;hpb=7512194aaad7f895f9a4e6b4085386fb99048c6f;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 c922f38f..dac9d2c1 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java @@ -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; @@ -12,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; @@ -57,43 +58,51 @@ 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 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; PipelineComponent endTo = null; - PositionType endType = null; - PipeControlPoint endPort = null; - - boolean reversed = false; - - private Set allowed = new HashSet(); - + PositionType endType = null; + PipeControlPoint endPort = null; + + boolean reversed = false; + + private Set allowed = new HashSet(); 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) { @@ -103,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().isFixedLength()) allowed.add(PositionType.SPLIT); setEnabled(allowed.size() > 0); } @@ -111,7 +120,7 @@ public class RoutePipeAction extends vtkSwtAction { public void deattach() { deactivate(); startComponent = null; - nodeMap.commit("Route pipe"); + deattachUI(); super.deattach(); panel.refresh(); @@ -151,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(); @@ -159,7 +170,7 @@ public class RoutePipeAction extends vtkSwtAction { panel.unlock(); } - private List added = new ArrayList(); + protected List added = new ArrayList(); @Override public boolean keyPressed(KeyEvent e) { @@ -233,24 +244,24 @@ public class RoutePipeAction extends vtkSwtAction { } private void update(double x, double y) { switch (state) { - case NOT_ACTIVE: - return; // TODO : throw Exception? - case INITIALIZING: - return; - case SELECTING_POSITION: - return; - case SELECTING_SPLIT: - return; - case ROUTING: - updateRouting(x,y); - break; - } - return; + case NOT_ACTIVE: + return; // TODO : throw Exception? + case INITIALIZING: + return; + case SELECTING_POSITION: + return; + case SELECTING_SPLIT: + return; + case ROUTING: + updateRouting(x,y); + break; + } + return; } boolean startRemovable = false; - private void activate() throws Exception { + protected void activate() throws Exception { state = ToolState.INITIALIZING; added.clear(); @@ -286,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()) @@ -303,7 +314,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; @@ -315,7 +326,7 @@ 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; } else { @@ -362,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); @@ -417,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; @@ -438,8 +461,7 @@ public class RoutePipeAction extends vtkSwtAction { startRemovable = false; detector.clearConstraintHighlights(); state = ToolState.NOT_ACTIVE; - setEnabled(false); - + setEnabled(false); } @@ -491,6 +513,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) { @@ -500,31 +530,31 @@ public class RoutePipeAction extends vtkSwtAction { if (state == ToolState.ROUTING) { try { if (e.getClickCount() == 1) { - if (e.getButton() == MouseEvent.BUTTON1) { - if (this.added.size() > 0) { - - setLockType(LockType.NONE,true); - if (endTo != null) { - - endPiping(); - } else { - addPoint(); - } - } else { - throw new RuntimeException("kjf"); + if (e.getButton() == MouseEvent.BUTTON1) { + if (this.added.size() > 0) { + + setLockType(LockType.NONE,true); + if (endTo != null) { + + endPiping(); + } else { + addPoint(); + } + } else { + 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)); // if (selectionLine != null) // selectionLine.removeFromParent(); // selectionLine = null; - } - } else if (e.getButton() ==MouseEvent.BUTTON2){ - // detector.updateConstraintReference(); - } else if (e.getButton() == MouseEvent.BUTTON3){ - endPiping(); - } - } + } + } else if (e.getButton() ==MouseEvent.BUTTON2){ + updateConstraints(); + } else if (e.getButton() == MouseEvent.BUTTON3){ + endPiping(); + } + } } catch(Exception err) { err.printStackTrace(); } @@ -563,7 +593,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,15 +616,37 @@ 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; + 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 @@ -603,7 +655,7 @@ public class RoutePipeAction extends vtkSwtAction { 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; } @@ -629,565 +681,533 @@ public class RoutePipeAction extends vtkSwtAction { return nodes; } - - - 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); -// } - if (useDefault) { - //panel.getDefaultAction().update(); - return; - } - - endTo = null; - endType = null; - endPort = null; + INode hoverObject = null; - Ray ray = vtkUtil.createMouseRay(panel.getRenderer(),x, y); - Vector3d o = new Vector3d(ray.pos); - Vector3d d = ray.dir; - - - if (!updateCurrentPoint(o, d)) - return; - //Point3d startPoint = new Point3d(); - double mu[] = new double[2]; - - - - INode hoverObject = null; - - List hover = isOverNode((int)x,(int)y); - if (hover.size() > 0) { - hoverObject = hover.get(0); - } + protected void updateRouting(double x, double y) { + if (useDefault) { + //panel.getDefaultAction().update(); + return; + } + + endTo = null; + endType = null; + endPort = null; + + Ray ray = vtkUtil.createMouseRay(panel.getRenderer(),x, y); + Vector3d o = new Vector3d(ray.pos); + Vector3d d = ray.dir; + + + if (!updateCurrentPoint(o, d)) + return; + //Point3d startPoint = new Point3d(); + double mu[] = new double[2]; + + + + + + 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()) ) { - boolean set = false; - for (int i = 1; i < hover.size(); i++) { - hoverObject = hover.get(i); - if (!getLast().equals(hoverObject)) { - set = true; - break; - } - } - if (!set) - hoverObject = null; - } - } + if (hoverObject != null) { + if (hoverObject.equals(getLast()) ) { + boolean set = false; + for (int i = 1; i < hover.size(); i++) { + hoverObject = hover.get(i); + if (!getLast().equals(hoverObject)) { + set = true; + break; + } + } + if (!set) + hoverObject = null; + } + } // System.out.println(hoverObject); - if (hoverObject != null) { - - if (lock == LockType.NONE) { - if (hoverObject instanceof Nozzle && endingToNozzle(hoverObject,o,d)) { - endTo = (Nozzle)hoverObject; - } else if (hoverObject instanceof InlineComponent && ((InlineComponent)hoverObject).isVariableLength()) { - endTo = (InlineComponent)hoverObject; - endType = endingToStraight(endTo,mu,o,d); - } 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) { - endTo = (InlineComponent)hoverObject;; - } else if (hoverObject instanceof Nozzle && endingLockToNozzle(hoverObject)) { - endTo = (Nozzle)hoverObject; - } else if ((hoverObject instanceof PipelineComponent) && ((endPort = endingLockToComponent(hoverObject)) != null)) { - endTo = (PipelineComponent)hoverObject; - } else { - updateRoute(o,d); - } - } - if (added.contains(endTo)) - endTo = null; - - } else { - updateRoute(o,d); - } - - panel.refresh(); - } - - private boolean updateCurrentPoint(Vector3d o, Vector3d d) { + if (hoverObject != null) { - Vector3d point = new Vector3d(this.previousPosition); - - switch(lock) { - case X: - MathTools.intersectStraightStraight(point, new Vector3d(1.0,0.0,0.0), o,d, currentPosition, new Vector3d()); - if (step) { - currentPosition.x = Math.round(istep * currentPosition.x) / istep; - BigDecimal bx = new BigDecimal(currentPosition.x); - bx.setScale(decimals, BigDecimal.ROUND_HALF_UP); - currentPosition.x = bx.doubleValue(); - } - break; - case Y: - MathTools.intersectStraightStraight(point, new Vector3d(0.0,1.0,0.0), o,d, currentPosition, new Vector3d()); - if (step) { - currentPosition.y = Math.round(istep * currentPosition.y) / istep; - BigDecimal bx = new BigDecimal(currentPosition.y); - bx.setScale(decimals, BigDecimal.ROUND_HALF_UP); - currentPosition.y = bx.doubleValue(); - } - break; - case Z: - MathTools.intersectStraightStraight(point, new Vector3d(0.0,0.0,1.0), o,d, currentPosition, new Vector3d()); - if (step) { - currentPosition.z = Math.round(istep * currentPosition.z) / istep; - BigDecimal bx = new BigDecimal(currentPosition.z); - bx.setScale(decimals, BigDecimal.ROUND_HALF_UP); - currentPosition.z = bx.doubleValue(); - }break; - case XY: - MathTools.intersectStraightPlane(o, d, point, new Vector3d(0.0,0.0,1.0), currentPosition); - break; - case XZ: - MathTools.intersectStraightPlane(o, d, point, new Vector3d(0.0,1.0,0.0), currentPosition); - break; - case YZ: - MathTools.intersectStraightPlane(o, d, point, new Vector3d(1.0,0.0,0.0), currentPosition); - break; - case NONE: - Vector3d normal = new Vector3d(panel.getRenderer().GetActiveCamera().GetDirectionOfProjection()); - normal.normalize(); - - MathTools.intersectStraightPlane(o, d, point, normal, currentPosition); - break; - case CUSTOM: - MathTools.intersectStraightStraight(point, new Vector3d(direction), o,d, currentPosition, new Vector3d()); - double dist = MathTools.distanceFromPlane(new Vector3d(currentPosition), direction, previousPosition); - if (dist < 0.0) - currentPosition.set(previousPosition); - break; - default: - return false; - } - return true; - } - - private Vector3d getLockDir() { - switch (lock) { - case CUSTOM: - return direction; - case X: - return new Vector3d(1,0,0); - case Y: - return new Vector3d(0,1,0); - case Z: - return new Vector3d(0,0,1); - } - return null; - } - - private void updateRoute(Vector3d o, Vector3d d) { - detector.clearConstraintHighlights(); - Point3d previousPipePoint = new Point3d(previousPosition); - String s = ""; - if (lock == LockType.NONE) { - Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint)); - if (p != null) - currentPosition = new Vector3d(p); - s += detector.getSnapString(); + if (lock == LockType.NONE) { + if (hoverObject instanceof Nozzle && endingToNozzle(hoverObject,o,d)) { + endTo = (Nozzle)hoverObject; + } 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) { + endTo = (InlineComponent)hoverObject; + } else if (hoverObject instanceof Nozzle && endingLockToNozzle(hoverObject)) { + endTo = (Nozzle)hoverObject; + } else if ((hoverObject instanceof PipelineComponent) && ((endPort = endingLockToComponent(hoverObject)) != null)) { + endTo = (PipelineComponent)hoverObject; + } else { + updateRoute(o,d); + } + } + if (added.contains(endTo)) + endTo = null; - } else { - Vector3d dir = new Vector3d(currentPosition); - dir.sub(previousPipePoint); - Point3d p = detector.getPointSnap(new Vector3d(previousPipePoint), dir); - if (p != null) - currentPosition = new Vector3d(p); - s += detector.getSnapString(); + } else { + updateRoute(o,d); + } + + panel.refresh(); + } + + protected boolean updateCurrentPoint(Vector3d o, Vector3d d) { - } - - updateCurrentPoint(); - s += currentPosition.toString(); - setInfoText(s); - } - - vtkTextActor infoActor; - - private void setInfoText(String text) { - //System.out.println(text); - if (infoActor == null) { - infoActor = new vtkTextActor(); - infoActor.GetTextProperty().SetColor(0.0, 0.0, 0.0); - infoActor.GetTextProperty().ShadowOff(); - infoActor.GetTextProperty().ItalicOff(); - infoActor.GetTextProperty().BoldOff(); - infoActor.GetTextProperty().SetFontSize(18); - infoActor.GetTextProperty().Delete(); - infoActor.GetProperty().SetColor(0.0, 0.0, 0.0); - infoActor.GetProperty().Delete(); + Vector3d point = new Vector3d(this.previousPosition); + + switch(lock) { + case X: + MathTools.intersectStraightStraight(point, new Vector3d(1.0,0.0,0.0), o,d, currentPosition, new Vector3d()); + if (step) { + currentPosition.x = Math.round(istep * currentPosition.x) / istep; + BigDecimal bx = new BigDecimal(currentPosition.x); + bx.setScale(decimals, BigDecimal.ROUND_HALF_UP); + currentPosition.x = bx.doubleValue(); + } + break; + case Y: + MathTools.intersectStraightStraight(point, new Vector3d(0.0,1.0,0.0), o,d, currentPosition, new Vector3d()); + if (step) { + currentPosition.y = Math.round(istep * currentPosition.y) / istep; + BigDecimal bx = new BigDecimal(currentPosition.y); + bx.setScale(decimals, BigDecimal.ROUND_HALF_UP); + currentPosition.y = bx.doubleValue(); + } + break; + case Z: + MathTools.intersectStraightStraight(point, new Vector3d(0.0,0.0,1.0), o,d, currentPosition, new Vector3d()); + if (step) { + currentPosition.z = Math.round(istep * currentPosition.z) / istep; + BigDecimal bx = new BigDecimal(currentPosition.z); + bx.setScale(decimals, BigDecimal.ROUND_HALF_UP); + currentPosition.z = bx.doubleValue(); + }break; + case XY: + MathTools.intersectStraightPlane(o, d, point, new Vector3d(0.0,0.0,1.0), currentPosition); + break; + case XZ: + MathTools.intersectStraightPlane(o, d, point, new Vector3d(0.0,1.0,0.0), currentPosition); + break; + case YZ: + MathTools.intersectStraightPlane(o, d, point, new Vector3d(1.0,0.0,0.0), currentPosition); + break; + case NONE: + Vector3d normal = new Vector3d(panel.getRenderer().GetActiveCamera().GetDirectionOfProjection()); + normal.normalize(); + + MathTools.intersectStraightPlane(o, d, point, normal, currentPosition); + break; + case CUSTOM: + MathTools.intersectStraightStraight(point, new Vector3d(direction), o,d, currentPosition, new Vector3d()); + double dist = MathTools.distanceFromPlane(new Vector3d(currentPosition), direction, previousPosition); + if (dist < 0.0) + currentPosition.set(previousPosition); + break; + default: + return false; + } + return true; + } + + private Vector3d getLockDir() { + switch (lock) { + case CUSTOM: + return direction; + case X: + return new Vector3d(1,0,0); + case Y: + return new Vector3d(0,1,0); + case Z: + return new Vector3d(0,0,1); + } + return null; + } + + protected void updateRoute(Vector3d o, Vector3d d) { + detector.clearConstraintHighlights(); + Point3d previousPipePoint = new Point3d(previousPosition); + String s = ""; + if (lock == LockType.NONE) { + Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint)); + if (p != null) + currentPosition = new Vector3d(p); + s += detector.getSnapString(); - - infoActor.SetPosition(10,10); - panel.getRenderer().AddActor(infoActor); - } - infoActor.SetInput(text); - } - - private boolean endingToNozzle(INode nozzleNode,Vector3d o, Vector3d d) { - Nozzle nozzle = (Nozzle)nozzleNode; - PipeControlPoint pcp =nozzle.getControlPoint(); - if (pcp != null && (pcp.getNext() != null || - pcp.getPrevious() != null)) - return false; // nozzle is already connected to pipe - currentPosition = pcp.getWorldPosition(); - Point3d previousPipePoint = new Point3d(previousPosition); - Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint)); - if (p != null) { - if (MathTools.distance(p, currentPosition) > NOZZLE_SNAP_DISTANCE) { - return false; - } - } - + } else { + Vector3d dir = new Vector3d(currentPosition); + dir.sub(previousPipePoint); + Point3d p = detector.getPointSnap(new Vector3d(previousPipePoint), dir); + if (p != null) + currentPosition = new Vector3d(p); + 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(); + setInfoText(s); + } + + vtkTextActor infoActor; + + private void setInfoText(String text) { + //System.out.println(text); + if (infoActor == null) { + infoActor = new vtkTextActor(); + infoActor.GetTextProperty().SetColor(0.0, 0.0, 0.0); + infoActor.GetTextProperty().ShadowOff(); + infoActor.GetTextProperty().ItalicOff(); + infoActor.GetTextProperty().BoldOff(); + infoActor.GetTextProperty().SetFontSize(18); + infoActor.GetTextProperty().Delete(); + infoActor.GetProperty().SetColor(0.0, 0.0, 0.0); + infoActor.GetProperty().Delete(); + + + infoActor.SetPosition(10,10); + panel.getRenderer().AddActor(infoActor); + } + infoActor.SetInput(text); + } + + private boolean endingToNozzle(INode nozzleNode,Vector3d o, Vector3d d) { + Nozzle nozzle = (Nozzle)nozzleNode; + PipeControlPoint pcp =nozzle.getControlPoint(); + if (pcp != null && (pcp.getNext() != null || + pcp.getPrevious() != null)) + return false; // nozzle is already connected to pipe + currentPosition = pcp.getWorldPosition(); + Point3d previousPipePoint = new Point3d(previousPosition); + Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint)); + if (p != null) { + if (MathTools.distance(p, currentPosition) > NOZZLE_SNAP_DISTANCE) { + return false; + } + } + + updateCurrentPoint(); + + setInfoText("Connect to nozzle " + currentPosition); + return true; + + } + + private PositionType endingToStraight(INode straightNode, double mu[], Vector3d o, Vector3d d) { + if (!allowBranches) { updateCurrentPoint(); - - setInfoText("Connect to nozzle " + currentPosition); - return true; - + return null; } - - private PositionType endingToStraight(INode straightNode, double mu[], Vector3d o, Vector3d d) { - 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); - //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); - if (t != null) - return t; - // if not, we'll have to remove highlight that was added when snapped point was detected - detector.clearConstraintHighlights(); - } - + 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); + if (t != null) + return t; + // if not, we'll have to remove highlight that was added when snapped point was detected + detector.clearConstraintHighlights(); + } + + Vector3d sDir = new Vector3d(sEnd); + sDir.sub(sStart); + MathTools.intersectStraightStraight(sStart, sDir, o, d, currentPosition, new Point3d(), mu); + - Vector3d sDir = new Vector3d(sEnd); - sDir.sub(sStart); - MathTools.intersectStraightStraight(sStart, sDir, o, d, currentPosition, new Point3d(), mu); - + } else { + throw new RuntimeException("Lock shouldn't be on"); - } else { - throw new RuntimeException("Lock shouldn't be on"); + } + + updateCurrentPoint(); + + // 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) + + boolean connectPrev = false; + boolean connectNext = false; + boolean branch = false; + if (mu[0] < 0.1) { + connectPrev = true; + } + else if (mu[0] > 0.9) { + connectNext = true; + } - } - - updateCurrentPoint(); - - // 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; - - } - - private PipeControlPoint endingToComponent(INode componentNode, Vector3d o, Vector3d d) { - PipelineComponent component = (PipelineComponent)componentNode; - PipeControlPoint pcp = component.getControlPoint(); - if (component instanceof EndComponent) { - if (pcp.getNext() != null || pcp.getPrevious() != null) - return null; - return pcp; - } else if (component instanceof TurnComponent) { - if (pcp.getNext() == null || pcp.getPrevious() == null) - return pcp; - 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; - } + + 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 > 0.95 || dot < -0.95) { + // 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) { + 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(); + if (component instanceof EndComponent) { + if (pcp.getNext() != null || pcp.getPrevious() != null) + return null; + return pcp; + } else if (component instanceof TurnComponent) { + if (pcp.getNext() == null || pcp.getPrevious() == null) + return pcp; + 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; + } - return null; - } - - 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()); - s.getControlPoint().getInlineControlPointEnds(sStart, sEnd); - Vector3d sDir = new Vector3d(sEnd); - sDir.sub(sStart); - Vector3d dir = new Vector3d(currentPosition); - Point3d prev = new Point3d(previousPosition); - dir.sub(prev); - // intersection point in pipe where branch would be inserted to - Vector3d branchPoint = new Vector3d(); - // intersection point in straight pipe that is currently routed - Vector3d routePoint = new Vector3d(); - MathTools.intersectStraightStraight(sStart, sDir, new Vector3d(prev), dir, branchPoint, routePoint, mu); - 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 - 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; - } - - private boolean endingLockToNozzle(INode nozzleNode) { - Nozzle nozzle = (Nozzle)nozzleNode; - Vector3d dir = new Vector3d(currentPosition); - Point3d prev = new Point3d(previousPosition); - dir.sub(prev); - Vector3d nozzleLoc = nozzle.getWorldPosition(); - double u[] = new double[1]; - Vector3d closest = MathTools.closestPointOnStraight(new Point3d(nozzleLoc), new Point3d(prev), new Vector3d(dir), u); - double dist = MathTools.distanceSquared(nozzleLoc,closest); - if (dist < BRANCH_SNAP_DISTANCE) { - // FIXME : directions should be checked (insert an elbow) - currentPosition.set(nozzleLoc); - updateCurrentPoint(); - setInfoText("Connect to nozzle (l) :" + currentPosition); - return true; - } - //System.out.println(u[0]); - return false; - } - - private PipeControlPoint endingLockToComponent(INode componentNode) { - // we'll must scan all free pcp's and their direction to accept the connection. - 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); - - setPreviousPosition(currentPosition); - updateCurrentPoint(); - - - - } - - /** - * Updates tool graphics for current point - */ - private void updateCurrentPoint() { - InlineComponent straight = (InlineComponent)added.get(added.size()-1); - // TODO: the inline length is from previous update step. - double l = straight.getPrevious().getControlPoint().getInlineLength(); - Vector3d v = new Vector3d(); - v.sub(currentPosition, previousPosition); - double length = v.length(); - if (length > MathTools.NEAR_ZERO) { - v.scale(1.0/length); - v.scale(0.5*(length+l)); - v.add(previousPosition); - straight.getControlPoint().setWorldPosition(v); - straight.getControlPoint().setLength(length); - } - try { - PipingRules.positionUpdate(straight.getControlPoint(),false); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - private PipelineComponent getLast() { - if (added.size() == 0) - return startComponent; - return added.get(added.size()-1); - } - - - /** - * Removes last point from pipeline - */ - public void removePoint() { - if (added.size() < 3) - return; - InlineComponent straight = (InlineComponent)added.remove(added.size()-1); - TurnComponent turn = (TurnComponent)added.remove(added.size()-1); - straight.getControlPoint().remove(); - turn.getControlPoint().remove(); - if (added.size() > 1) { - setPreviousPosition(added.get(added.size()-2).getWorldPosition()); - } else { - setPreviousPosition(startComponent.getWorldPosition()); - if (direction != null) - setLockType(LockType.CUSTOM, true); - } - - } - - private void endPiping() throws Exception { - 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); - } - panel.useDefaultAction(); - } + return null; + } + + private PositionType endingLockToStraight(INode straightNode, double mu[]) { + if (!allowBranches) { + updateCurrentPoint(); + return null; + } + InlineComponent s = (InlineComponent)straightNode; + Point3d sStart = new Point3d(); + Point3d sEnd = new Point3d(); + s.getControlPoint().getInlineControlPointEnds(sStart, sEnd); + Vector3d sDir = new Vector3d(sEnd); + sDir.sub(sStart); + Vector3d dir = new Vector3d(currentPosition); + Point3d prev = new Point3d(previousPosition); + dir.sub(prev); + // intersection point in pipe where branch would be inserted to + Vector3d branchPoint = new Vector3d(); + // intersection point in straight pipe that is currently routed + Vector3d routePoint = new Vector3d(); + MathTools.intersectStraightStraight(sStart, sDir, new Vector3d(prev), dir, branchPoint, routePoint, mu); + 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 other + 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) { + Nozzle nozzle = (Nozzle)nozzleNode; + Vector3d dir = new Vector3d(currentPosition); + Point3d prev = new Point3d(previousPosition); + dir.sub(prev); + Vector3d nozzleLoc = nozzle.getWorldPosition(); + double u[] = new double[1]; + Vector3d closest = MathTools.closestPointOnStraight(new Point3d(nozzleLoc), new Point3d(prev), new Vector3d(dir), u); + double dist = MathTools.distanceSquared(nozzleLoc,closest); + if (dist < BRANCH_SNAP_DISTANCE) { + // FIXME : directions should be checked (insert an elbow) + currentPosition.set(nozzleLoc); + updateCurrentPoint(); + setInfoText("Connect to nozzle (l) :" + currentPosition); + return true; + } + //System.out.println(u[0]); + return false; + } + + private PipeControlPoint endingLockToComponent(INode componentNode) { + // we'll must scan all free pcp's and their direction to accept the connection. + return null; + } + + protected 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); + + setPreviousPosition(currentPosition); + updateCurrentPoint(); + + + + } + + /** + * Updates tool graphics for current point + */ + protected void updateCurrentPoint() { + InlineComponent straight = (InlineComponent)added.get(added.size()-1); + // TODO: the inline length is from previous update step. + double l; + if (!reversed) + l = straight.getPrevious().getControlPoint().getInlineLength(); + else + l = straight.getNext().getControlPoint().getInlineLength(); + Vector3d v = new Vector3d(); + v.sub(currentPosition, previousPosition); + double length = v.length(); + if (length > MathTools.NEAR_ZERO) { + v.scale(1.0/length); + v.scale(0.5*(length+l)); + v.add(previousPosition); + straight.getControlPoint().setWorldPosition(v); + straight.getControlPoint().setLength(length); + } + try { + PipingRules.positionUpdate(straight.getControlPoint(),false); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private PipelineComponent getLast() { + if (added.size() == 0) + return startComponent; + return added.get(added.size()-1); + } + + + /** + * Removes last point from pipeline + */ + public void removePoint() { + if (added.size() < 3) + return; + InlineComponent straight = (InlineComponent)added.remove(added.size()-1); + TurnComponent turn = (TurnComponent)added.remove(added.size()-1); + straight.getControlPoint().remove(); + turn.getControlPoint().remove(); + if (added.size() > 1) { + setPreviousPosition(added.get(added.size()-2).getWorldPosition()); + } else { + setPreviousPosition(startComponent.getWorldPosition()); + if (direction != null) + setLockType(LockType.CUSTOM, true); + } + + } + + protected void endPiping() throws Exception { + state = ToolState.NOT_ACTIVE; + + if (endTo != null) { + ComponentUtils.connect(getLast(), endTo, endType, currentPosition); + } + panel.useDefaultAction(); + } }