-/*******************************************************************************\r
- * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package fi.vtt.simantics.processeditor.actions;\r
-\r
-import java.awt.event.KeyEvent;\r
-import java.awt.event.MouseEvent;\r
-import java.math.BigDecimal;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import javax.vecmath.Point3d;\r
-import javax.vecmath.Vector3d;\r
-\r
-import org.eclipse.jface.action.Action;\r
-import org.eclipse.jface.action.IToolBarManager;\r
-import org.eclipse.jface.resource.ImageDescriptor;\r
-import org.simantics.db.Graph;\r
-import org.simantics.db.GraphRequestAdapter;\r
-import org.simantics.db.GraphRequestStatus;\r
-import org.simantics.db.GraphRequestWithResult;\r
-import org.simantics.db.Resource;\r
-import org.simantics.layer0.utils.EntityFactory;\r
-import org.simantics.layer0.utils.IEntity;\r
-import org.simantics.proconf.g3d.actions.InteractiveAction;\r
-import org.simantics.proconf.g3d.base.ConstraintDetector;\r
-import org.simantics.proconf.g3d.base.G3DAPI;\r
-import org.simantics.proconf.g3d.base.G3DTools;\r
-import org.simantics.proconf.g3d.base.MathTools;\r
-import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
-import org.simantics.proconf.g3d.common.StructuredResourceSelection;\r
-import org.simantics.proconf.g3d.dnd.DropListener;\r
-import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;\r
-import org.simantics.utils.datastructures.Pair;\r
-\r
-import com.jme.renderer.ColorRGBA;\r
-import com.jme.scene.Geometry;\r
-import com.jme.scene.Line;\r
-import com.jme.scene.state.MaterialState;\r
-\r
-import fi.vtt.simantics.processeditor.Activator;\r
-import fi.vtt.simantics.processeditor.ProcessResource;\r
-import fi.vtt.simantics.processeditor.common.ControlPointTools;\r
-import fi.vtt.simantics.processeditor.common.PipeComponentProvider;\r
-import fi.vtt.simantics.processeditor.common.PipingTools2;\r
-import fi.vtt.simantics.processeditor.common.PipingTools2.Direction;\r
-import fi.vtt.simantics.processeditor.dialogs.PipelineDialog;\r
-import fi.vtt.simantics.processeditor.gizmo.PositionSelectionGizmo;\r
-import fi.vtt.simantics.processeditor.stubs.BranchEndControlPoint;\r
-import fi.vtt.simantics.processeditor.stubs.PipeControlPoint;\r
-import fi.vtt.simantics.processeditor.stubs.PipeRun;\r
-import fi.vtt.simantics.processeditor.stubs.PipelineComponent;\r
-import fi.vtt.simantics.processeditor.stubs.VariableLengthInlineComponent;\r
-import fi.vtt.simantics.processeditor.views.ProcessEditor;\r
-\r
-/**\r
- * Action for Routing Pipes\r
- * \r
- * FIXME : does several thing that should be done by PipingTools.\r
- * TODO : instead of using lines to show route of pipe, generate pipe and change it real-time\r
- * \r
- * @author MLMARKO\r
- *\r
- */\r
-public class RoutePipeAction extends InteractiveAction implements DropListener, SplitPointListener {\r
- \r
- \r
- private static final ImageDescriptor X_AXIS_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/x-axis.png");\r
- private static final ImageDescriptor Y_AXIS_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/y-axis.png");\r
- private static final ImageDescriptor Z_AXIS_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/z-axis.png");\r
- private static final ImageDescriptor X_PLANE_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/x-plane.png");\r
- private static final ImageDescriptor Y_PLANE_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/y-plane.png");\r
- private static final ImageDescriptor Z_PLANE_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/z-plane.png");\r
- \r
- private static final ImageDescriptor CAMERA_ICON = Activator.imageDescriptorFromPlugin("org.simantics.proconf.g3d", "icons/eye.png");\r
- \r
- \r
- private Action xAxisAction;\r
- private Action yAxisAction;\r
- private Action zAxisAction;\r
- private Action xPlaneAction;\r
- private Action yPlaneAction;\r
- private Action zPlaneAction;\r
- \r
- private Action cameraAction;\r
- \r
- ConstraintDetector detector = null;\r
- \r
- public RoutePipeAction(ThreeDimensionalEditorBase parent) {\r
- super(parent);\r
- detector = new ConstraintDetector(parent);\r
- xAxisAction = new Action("X",Action.AS_RADIO_BUTTON) {\r
- public void run() {\r
- if (lock == LockType.X)\r
- setLockType(LockType.NONE,false);\r
- else\r
- setLockType(LockType.X,false);\r
- }\r
- };\r
- xAxisAction.setImageDescriptor(X_AXIS_ICON);\r
- xAxisAction.setToolTipText("Lock X-Axis");\r
- yAxisAction = new Action("Y",Action.AS_RADIO_BUTTON) {\r
- public void run() {\r
- if (lock == LockType.Y)\r
- setLockType(LockType.NONE,false);\r
- else\r
- setLockType(LockType.Y,false);\r
- }\r
- };\r
- yAxisAction.setImageDescriptor(Y_AXIS_ICON);\r
- yAxisAction.setToolTipText("Lock Y-Axis");\r
- zAxisAction = new Action("Z",Action.AS_RADIO_BUTTON) {\r
- public void run() {\r
- if (lock == LockType.Z)\r
- setLockType(LockType.NONE,false);\r
- else\r
- setLockType(LockType.Z,false);\r
- }\r
- };\r
- zAxisAction.setImageDescriptor(Z_AXIS_ICON);\r
- zAxisAction.setToolTipText("Lock Z-Axis");\r
- xPlaneAction = new Action("X",Action.AS_RADIO_BUTTON) {\r
- public void run() {\r
- if (lock == LockType.YZ)\r
- setLockType(LockType.NONE,false);\r
- else\r
- setLockType(LockType.YZ,false);\r
- }\r
- };\r
- xPlaneAction.setImageDescriptor(X_PLANE_ICON);\r
- xPlaneAction.setToolTipText("Lock X-Plane");\r
- yPlaneAction = new Action("Y",Action.AS_RADIO_BUTTON) {\r
- public void run() {\r
- if (lock == LockType.XZ)\r
- setLockType(LockType.NONE,false);\r
- else\r
- setLockType(LockType.XZ,false);\r
- }\r
- };\r
- yPlaneAction.setImageDescriptor(Y_PLANE_ICON);\r
- yPlaneAction.setToolTipText("Lock Y-Plane");\r
- zPlaneAction = new Action("Z",Action.AS_RADIO_BUTTON) {\r
- public void run() {\r
- if (lock == LockType.XY)\r
- setLockType(LockType.NONE,false);\r
- else\r
- setLockType(LockType.XY,false);\r
- }\r
- };\r
- zPlaneAction.setImageDescriptor(Z_PLANE_ICON);\r
- zPlaneAction.setToolTipText("Lock Z-Plane");\r
- cameraAction = new Action("C", Action.AS_CHECK_BOX) {\r
- public void run() {\r
- useCamera = this.isChecked();\r
- }\r
- };\r
- cameraAction.setImageDescriptor(CAMERA_ICON);\r
- cameraAction.setToolTipText("Use camera");\r
- splitPointAction = new SelectSplitPointAction(parent,this);\r
- \r
- }\r
- \r
- public void fillToolBar(IToolBarManager manager) {\r
- \r
- manager.add(cameraAction);\r
- cameraAction.setChecked(useCamera);\r
- manager.add(xAxisAction);\r
- manager.add(yAxisAction);\r
- manager.add(zAxisAction);\r
- manager.add(xPlaneAction);\r
- manager.add(yPlaneAction);\r
- manager.add(zPlaneAction); \r
- \r
- }\r
-\r
- enum LockType {NONE,X,Y,Z,XY,YZ,XZ,CUSTOM};\r
- LockType lock = LockType.NONE;\r
- \r
- private void setLockType(LockType type, boolean force) {\r
- if (force || lock != LockType.CUSTOM) {\r
- lock = type;\r
- }\r
- xAxisAction.setChecked(false);\r
- yAxisAction.setChecked(false);\r
- zAxisAction.setChecked(false);\r
- xPlaneAction.setChecked(false);\r
- yPlaneAction.setChecked(false);\r
- zPlaneAction.setChecked(false);\r
- xAxisAction.setEnabled(true);\r
- yAxisAction.setEnabled(true);\r
- zAxisAction.setEnabled(true);\r
- xPlaneAction.setEnabled(true);\r
- yPlaneAction.setEnabled(true);\r
- zPlaneAction.setEnabled(true);\r
- switch (lock) {\r
- case X:\r
- xAxisAction.setChecked(true);\r
- break;\r
- case Y:\r
- yAxisAction.setChecked(true);\r
- break;\r
- case Z:\r
- zAxisAction.setChecked(true);\r
- break; \r
- case XY:\r
- zPlaneAction.setChecked(true);\r
- break; \r
- case XZ:\r
- yPlaneAction.setChecked(true);\r
- break; \r
- case YZ:\r
- xPlaneAction.setChecked(true);\r
- break; \r
- case CUSTOM:\r
- xAxisAction.setEnabled(false);\r
- yAxisAction.setEnabled(false);\r
- zAxisAction.setEnabled(false);\r
- xPlaneAction.setEnabled(false);\r
- yPlaneAction.setEnabled(false);\r
- zPlaneAction.setEnabled(false);\r
- break;\r
- }\r
- }\r
- \r
- private double BRANCH_SNAP_DISTANCE = 0.05;\r
- private double NOZZLE_SNAP_DISTANCE = 0.05;\r
- \r
- private double istep = 10.0;\r
- private int decimals = 2;\r
- \r
- private double pipeDiameter = 0.2;\r
- private double elbowRadius = 0.5;\r
- private double eps = 0.001;\r
- \r
- private ArrayList<Point3d> controlPoints = new ArrayList<Point3d>();\r
-\r
- private Point3d currentPoint = new Point3d();\r
- private Point3d lastPoint = new Point3d();\r
- \r
- private Vector3d customLockDir = null;\r
- \r
- private Line selectionLine;\r
- private List<Line> pipeShapes = new ArrayList<Line>();\r
- private MaterialState ms;\r
- \r
- \r
- private Resource selectedPort = null;\r
- private PositionType selectedType = null;\r
- private Resource beginComponentResource = null;\r
- \r
- private Resource endComponentResource = null;\r
- private Resource endComponentPort = null;\r
- private PositionType endPortType = null;\r
- \r
- private Resource highlightedResource = null;\r
- \r
- private boolean useCamera = false;\r
- \r
- private List<Pair<Resource, PositionType>> positions = null;\r
- \r
- private SelectSplitPointAction splitPointAction;\r
- private PositionSelectionGizmo gizmo = null;\r
- \r
- \r
- \r
- private enum ToolState{NOT_ACTIVE, INITIALIZING, SELECTING_POSITION, SELECTING_SPLIT, ROUTING};\r
- private ToolState state = ToolState.NOT_ACTIVE;\r
- \r
- @Override\r
- public void activate() {\r
- state = ToolState.INITIALIZING;\r
- controlPoints.clear();\r
- if (beginComponentResource == null) {\r
- List<IGraphicsNode> mos = parent.getSelectionAdapter().getSelectedObjects();\r
- if (mos.size() != 1) {\r
- end();\r
- return;\r
- }\r
- beginComponentResource = mos.get(0).getResource();\r
- }\r
- parent.getSession().asyncRead(new GraphRequestAdapter() {\r
- @Override\r
- public GraphRequestStatus perform(Graph g) throws Exception {\r
- positions = checkStartNode(g,beginComponentResource);\r
- if (positions.size() == 0) {\r
- positions = null;\r
- end();\r
- } else {\r
- state = ToolState.SELECTING_POSITION;\r
- }\r
- return GraphRequestStatus.transactionComplete();\r
- }\r
- });\r
- \r
- if (ms == null) {\r
- ms = parent.getRenderingComponent().getDisplaySystem().getRenderer().createMaterialState();\r
- ms.setEmissive(new ColorRGBA(1.f,1.f,1.f,1.f));\r
- }\r
-\r
- }\r
- \r
- \r
-\r
- @Override\r
- public void deactivate() {\r
- for (Line l : pipeShapes)\r
- l.removeFromParent();\r
- pipeShapes.clear();\r
- if (selectionLine != null)\r
- selectionLine.removeFromParent();\r
- selectionLine = null;\r
- customLockDir = null;\r
- \r
- setLockType(LockType.NONE,true);\r
- beginComponentResource = null;\r
- endComponentResource = null;\r
- detector.clearConstraintHighlights(); \r
- state = ToolState.NOT_ACTIVE;\r
- selectedPort = null;\r
- selectedType = null;\r
- \r
- }\r
- \r
- private List<Pair<Resource, PositionType>> checkStartNode(Graph g, Resource resource) {\r
- List<Pair<Resource, PositionType>> positions = new ArrayList<Pair<Resource,PositionType>>();\r
- \r
- IEntity beginComponent = EntityFactory.create(g, resource);\r
- \r
- if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.Nozzle)) {\r
- if (PipingTools2.isFreeNozzle(beginComponent)) {\r
-\r
- positions.add(new Pair<Resource, PositionType>(beginComponent.getSingleRelatedObject(ProcessResource.plant3Dresource.HasControlPoint).getResource(),PositionType.NEXT));\r
- } \r
- } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {\r
- // variable length inline component is exception from other pipeline components,\r
- // since a new pipe can branch it\r
- VariableLengthInlineComponent vlic = new VariableLengthInlineComponent(beginComponent);\r
- PipeControlPoint pcp = vlic.getControlPoint();\r
- if (pcp.getNext() == null) {\r
-\r
- positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.NEXT)); \r
- } else if (pcp.getPrevious() == null) {\r
-\r
- positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.PREVIOUS));\r
- }\r
- positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.SPLIT));\r
- } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.EndComponent)) {\r
- PipelineComponent component = new PipelineComponent(beginComponent); \r
- PipeControlPoint pcp = component.getControlPoint();\r
- if (pcp.getNext() == null && pcp.getPrevious() == null) { \r
- throw new RuntimeException("End component " + beginComponent.getResource() + " is not connected to anything.");\r
- //positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.NEXT));\r
- }\r
- for (PipeControlPoint p : pcp.getSubPoint()) {\r
- if (p.getNext() == null && p.getPrevious() == null) {\r
- positions.add(new Pair<Resource, PositionType>(p.getResource(),PositionType.NEXT));\r
- }\r
- }\r
- } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.PipelineComponent)) {\r
- \r
- PipelineComponent component = new PipelineComponent(beginComponent);\r
- \r
- PipeControlPoint pcp = component.getControlPoint();\r
- if (pcp.getNext() == null) {\r
- positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.NEXT));\r
- } else if (pcp.getPrevious() == null) {\r
- positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.PREVIOUS));\r
- }\r
- if (!beginComponent.isInstanceOf(ProcessResource.plant3Dresource.SizeChangeComponent)||\r
- !beginComponent.isInstanceOf(ProcessResource.plant3Dresource.OffsetComponent)) {\r
- for (PipeControlPoint p : pcp.getSubPoint()) {\r
- if (p.getNext() == null && p.getPrevious() == null) {\r
- positions.add(new Pair<Resource, PositionType>(p.getResource(),PositionType.NEXT));\r
- }\r
- }\r
- } \r
- } else {\r
- return positions;\r
- }\r
- return positions;\r
- }\r
-\r
- @Override\r
- public void update() {\r
- \r
- switch (state) {\r
- case NOT_ACTIVE:\r
- return; // TODO : throw Exception?\r
- case INITIALIZING:\r
- return;\r
- case SELECTING_POSITION:\r
- updateSelectPosition();\r
- break;\r
- case SELECTING_SPLIT:\r
- updateSelectSplit();\r
- break;\r
- case ROUTING:\r
- updateRouting();\r
- break;\r
- }\r
- return;\r
- }\r
-\r
- private void updateSelectPosition() {\r
- \r
- if (positions == null) {\r
- throw new RuntimeException("positions must be loaded before select position can be activated");\r
- }\r
- if (selectedPort != null) {\r
- throw new RuntimeException("position is already selected");\r
- }\r
- if (positions.size() == 1) {\r
- selectedPort = positions.get(0).first;\r
- selectedType = positions.get(0).second;\r
- state = ToolState.INITIALIZING;\r
- \r
- \r
- \r
- if (requiresNewPipeRun()){\r
- if(!getNewPipeRunSpecs()) {\r
- end();\r
- return;\r
- }\r
- }\r
- if (selectedType == PositionType.SPLIT) {\r
- startSplitting();\r
- } else {\r
- startRouting();\r
- }\r
-\r
- } else if (gizmo == null) {\r
- state = ToolState.INITIALIZING; // asyncRead!\r
- parent.getSession().asyncRead(new GraphRequestAdapter() {\r
- @Override\r
- public GraphRequestStatus perform(Graph g) throws Exception {\r
- List<Pair<Point3d, PositionType>> pos = new ArrayList<Pair<Point3d,PositionType>>();\r
- for (Pair<Resource, PositionType> p : positions) {\r
- IEntity entity = EntityFactory.create(g,p.first);\r
- Point3d position = ControlPointTools.getRealPosition(entity, p.second);\r
- pos.add(new Pair<Point3d, PositionType>(position,p.second));\r
- }\r
- gizmo = new PositionSelectionGizmo(parent, pos);\r
- parent.setGizmo(gizmo);\r
- parent.getRenderingComponent().getNoShadowRoot().attachChild(gizmo.getNode());\r
- state = ToolState.SELECTING_POSITION;\r
- return GraphRequestStatus.transactionComplete();\r
- }\r
- });\r
- \r
- } else {\r
- gizmo.update();\r
- \r
- if (input.keyPressed(KeyEvent.VK_ESCAPE)) {\r
- state = ToolState.INITIALIZING;\r
- parent.setGizmo(null);\r
- gizmo = null;\r
- end();\r
- return;\r
- }\r
-\r
- if (gizmo.getSelected() >= 0 && input.mouseClicked() && input.clickButton() == MouseEvent.BUTTON1) {\r
- state = ToolState.INITIALIZING; // asyncRead!\r
- parent.setGizmo(null);\r
- selectedPort = positions.get(gizmo.getSelected()).first;\r
- selectedType = positions.get(gizmo.getSelected()).second;\r
- gizmo = null;\r
- \r
- if (selectedType == PositionType.SPLIT) {\r
- startSplitting(); \r
- return;\r
- } else {\r
- startRouting();\r
- }\r
- } \r
- \r
- if (useCamera) {\r
- parent.getDefaultAction().update();\r
- return;\r
- }\r
- }\r
- \r
- }\r
- \r
- private boolean requiresNewPipeRun() {\r
- GraphRequestWithResult<Boolean> createsNewPipeline = new GraphRequestWithResult<Boolean>() {\r
- @Override\r
- public Boolean performWithResult(Graph g) throws Exception {\r
- if(g.isInstanceOf(selectedPort, ProcessResource.plant3Dresource.NozzleControlPoint))\r
- return true;\r
- if (selectedType == PositionType.SPLIT)\r
- return true;\r
- return false;\r
- \r
- }\r
- };\r
- parent.getSession().syncRead(createsNewPipeline);\r
- return createsNewPipeline.getResult();\r
- }\r
- \r
- private boolean getNewPipeRunSpecs() {\r
- PipelineDialog dialog;\r
- dialog = new PipelineDialog(parent.getRenderingComposite().getShell(),pipeDiameter,elbowRadius);\r
- if (dialog.open() == PipelineDialog.CANCEL) {\r
- end();\r
- return false;\r
- }\r
- pipeDiameter = dialog.getPipeDiameter();\r
- elbowRadius = dialog.getTurnRadius();\r
- return true;\r
- }\r
- \r
- private void startRouting() {\r
- state = ToolState.INITIALIZING;\r
- parent.getSession().asyncRead(new GraphRequestAdapter() {\r
- @Override\r
- public GraphRequestStatus perform(Graph g) throws Exception {\r
- PipeControlPoint pcp = new PipeControlPoint(g,selectedPort);\r
- lastPoint = ControlPointTools.getRealPosition(pcp, selectedType);//G3DTools.getPoint(pcp.getWorldPosition());\r
- if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint)) {\r
- lock = LockType.CUSTOM;\r
- customLockDir = ControlPointTools.getDirectedControlPointDirection(pcp);\r
- } else if (pcp.isInstanceOf(ProcessResource.plant3Dresource.FixedLengthControlPoint)||\r
- pcp.isInstanceOf(ProcessResource.plant3Dresource.TurnControlPoint)) {\r
- lock = LockType.CUSTOM;\r
- if (selectedType == PositionType.NEXT)\r
- customLockDir = ControlPointTools.getPathLegDirection(pcp, Direction.NEXT);\r
- else\r
- customLockDir = ControlPointTools.getPathLegDirection(pcp, Direction.PREVIOUS);\r
- } else {\r
- lock = LockType.NONE;\r
- }\r
- IEntity pipeRun = ControlPointTools.getPipeRun(pcp);\r
- if (pipeRun != null) {\r
- pipeDiameter = pipeRun.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasPipeDiameter);\r
- elbowRadius = pipeRun.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasTurnRadius);\r
- }\r
- return GraphRequestStatus.transactionComplete();\r
- }\r
- \r
- @Override\r
- public void requestCompleted(GraphRequestStatus status) {\r
- createLine();\r
- state = ToolState.ROUTING;\r
- }\r
- });\r
- }\r
- \r
- private void startSplitting() {\r
- parent.getSession().asyncRead(new GraphRequestAdapter() {\r
- @Override\r
- public GraphRequestStatus perform(Graph g) throws Exception {\r
- PipeControlPoint pcp = new PipeControlPoint(g,selectedPort);\r
- Point3d p1 = new Point3d();\r
- Point3d p2 = new Point3d();\r
- ControlPointTools.getInlineControlPointEnds(pcp, p1, p2);\r
- splitPointAction.setSplit(p1, p2);\r
- splitPointAction.activate();\r
- state = ToolState.SELECTING_SPLIT;\r
- return GraphRequestStatus.transactionComplete();\r
- }\r
- }); \r
- }\r
- \r
- \r
- private void updateSelectSplit() {\r
- if (splitPointAction.active()) {\r
- splitPointAction.update();\r
- return;\r
- } else {\r
- throw new RuntimeException("SplitPointAction should be active");\r
- }\r
- }\r
- \r
- @Override\r
- public void setSplitPoint(Point3d point) {\r
- splitPointAction.deactivate();\r
- if (point == null) {\r
- end();\r
- return;\r
- } else {\r
- \r
- \r
- lastPoint = point;\r
- createLine();\r
- state = ToolState.ROUTING;\r
- }\r
- }\r
- \r
- private void updateRouting() {\r
- if(input.keyPressed(KeyEvent.VK_ESCAPE)) {\r
- controlPoints.clear();\r
- end();\r
- return;\r
- }\r
- if (input.keyPressed(KeyEvent.VK_C)) {\r
- useCamera = !useCamera;\r
- cameraAction.setChecked(useCamera);\r
- }\r
- if (useCamera) {\r
- parent.getDefaultAction().update();\r
- return;\r
- }\r
- \r
- parent.getSession().syncRead(new GraphRequestAdapter() {\r
- @Override\r
- public GraphRequestStatus perform(Graph g) throws Exception {\r
- \r
- Vector3d o = new Vector3d();\r
- Vector3d d = new Vector3d();\r
- parent.createPickRay(o, d);\r
- if (!updateCurrentPoint(o, d))\r
- return GraphRequestStatus.transactionComplete();\r
- //Point3d startPoint = new Point3d();\r
- double mu[] = new double[2];\r
- \r
- IEntity endTo = null;\r
- PositionType endType = null;\r
- IEntity endPort = null;\r
- \r
- if (parent.getSelectionAdapter().getHighlightSelection().size() > 0) {\r
- highlightedResource = parent.getSelectionAdapter().getHighlightSelection().getSelectionList().get(0);\r
- } else {\r
- highlightedResource = null;\r
- }\r
-\r
- if (highlightedResource != null) {\r
- IEntity highlightNode = EntityFactory.create(g,highlightedResource);\r
- \r
- if (lock == LockType.NONE) {\r
- if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.Nozzle) && endingToNozzle(highlightNode,o,d)) {\r
- endTo = highlightNode;\r
- } else if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {\r
- endTo = highlightNode;\r
- endType = endingToStraight(new VariableLengthInlineComponent(highlightNode),mu,o,d); \r
- } else if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.PipelineComponent) && (endPort = endingToComponent(highlightNode,o,d)) != null) {\r
- endTo = highlightNode;\r
- } else {\r
- updateRoute(o,d); \r
- }\r
- } else { \r
- if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent) && (endType = endingLockToStraight(new VariableLengthInlineComponent(highlightNode),mu)) != null) {\r
- endTo = highlightNode;\r
- } else if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.Nozzle) && endingLockToNozzle(highlightNode)) {\r
- endTo = highlightNode;\r
- } else if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.PipelineComponent) && (endPort = endingLockToComponent(highlightNode)) != null) {\r
- endTo = highlightNode;\r
- } else {\r
- updateRoute(o,d);\r
- }\r
- }\r
- \r
- \r
- } else {\r
- updateRoute(o,d);\r
- }\r
- \r
- parent.setViewChanged(true);\r
- if (input.mouseClicked()) {\r
- if (input.clickButton() == MouseEvent.BUTTON1) {\r
- if (controlPoints.size() > 0) {\r
- addPoint();\r
- setLockType(LockType.NONE,true);\r
- if (endTo != null) {\r
- endComponentResource = endTo.getResource();\r
- if (endPort != null)\r
- endComponentPort = endPort.getResource();\r
- endPortType = endType;\r
- \r
- endPiping();\r
- }\r
- } else {\r
- throw new RuntimeException("kjf");\r
-// // user was selecting position of branch\r
-// lastPoint.set(startPoint);\r
-// controlPoints.add(new Point3d(startPoint));\r
-// if (selectionLine != null)\r
-// selectionLine.removeFromParent();\r
-// selectionLine = null;\r
- }\r
- } else if (input.clickButton() == MouseEvent.BUTTON2){\r
- detector.updateConstraintReference();\r
- } else if (input.clickButton() == MouseEvent.BUTTON3){ \r
- endPiping();\r
- }\r
- }\r
- \r
- return GraphRequestStatus.transactionComplete();\r
- } \r
- });\r
- \r
- }\r
- \r
- private void createLine() {\r
- controlPoints.add(new Point3d(lastPoint));\r
- Line line = new Line();\r
- line.setRenderState(ms);\r
- \r
- PipeComponentProvider.createStraightEdges(line, currentPoint, currentPoint, pipeDiameter*0.5);\r
- pipeShapes.add(line);\r
- parent.getRenderingComponent().getNoShadowRoot().attachChild(line); \r
- line.setCullMode(Geometry.CULL_NEVER);\r
- }\r
- \r
- \r
- /**\r
- * Adds current point to pipeline\r
- *\r
- */\r
- private void addPoint() {\r
- \r
- controlPoints.add(new Point3d(currentPoint));\r
- Line line = new Line();\r
- line.setRenderState(ms);\r
- PipeComponentProvider.createStraightEdges(line, controlPoints.get(controlPoints.size() - 1), currentPoint, pipeDiameter*0.5);\r
- pipeShapes.add(line);\r
- parent.getRenderingComponent().getNoShadowRoot().attachChild(line); \r
- line.setCullMode(Geometry.CULL_NEVER);\r
- lastPoint.set(currentPoint);\r
- }\r
- \r
- /**\r
- * Updates tool graphics for current point \r
- */\r
- private void updateCurrentPoint() {\r
- PipeComponentProvider.createStraightEdges(pipeShapes.get(pipeShapes.size() - 1), controlPoints.get(controlPoints.size() - 1), currentPoint, pipeDiameter*0.5);\r
- }\r
- \r
- /**\r
- * Removes last point from pipeline\r
- */\r
- public void removePoint() {\r
- if (controlPoints.size() < 2)\r
- return;\r
- controlPoints.remove(controlPoints.size() - 1);\r
-\r
- pipeShapes.get(pipeShapes.size() - 1).removeFromParent();\r
- pipeShapes.remove(pipeShapes.size() - 1);\r
- PipeComponentProvider.createStraightEdges(pipeShapes.get(pipeShapes.size() - 1), controlPoints.get(controlPoints.size() - 1), currentPoint, pipeDiameter*0.5);\r
- \r
- lastPoint.set(controlPoints.get(controlPoints.size()-1));\r
- if (controlPoints.size() < 2 && customLockDir != null) {\r
- setLockType(LockType.CUSTOM, true);\r
- }\r
- }\r
- \r
- \r
- \r
- private boolean endingToNozzle(IEntity nozzle,Vector3d o, Vector3d d) { \r
- IEntity pcp = nozzle.getSingleRelatedObject(ProcessResource.plant3Dresource.HasControlPoint);\r
- if (pcp != null && (pcp.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasNext) != null ||\r
- pcp.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasPrevious) != null))\r
- return false; // nozzle is already connected to pipe\r
- currentPoint = G3DTools.getPoint(nozzle.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));\r
- Point3d previousPipePoint = controlPoints.get(controlPoints.size() - 1);\r
- Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint));\r
- if (p != null) {\r
- if (p.distance(currentPoint) > NOZZLE_SNAP_DISTANCE) {\r
- return false;\r
- }\r
- } \r
- \r
- updateCurrentPoint();\r
- \r
- setInfoText("Connect to nozzle " + currentPoint);\r
- return true;\r
- \r
- }\r
- \r
- private PositionType endingToStraight(VariableLengthInlineComponent s, double mu[], Vector3d o, Vector3d d) {\r
- String info = "";\r
- Point3d sStart = new Point3d();\r
- Point3d sEnd = new Point3d();\r
- //detector.clearConstraintHighlights();\r
- \r
- Point3d previousPipePoint = controlPoints.get(controlPoints.size() - 1);\r
- //String st = "";\r
- if (lock == LockType.NONE) {\r
- Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint));\r
- if (p != null) {\r
- currentPoint = p;\r
- // snapping is detected, check if snapped point can create branch with straight\r
- PositionType t = endingLockToStraight(s, mu);\r
- if (t != null)\r
- return t;\r
- // if not, we'll have to remove highlight that was added when snapped point was detected\r
- detector.clearConstraintHighlights();\r
- } \r
- \r
- PipingTools2.getInlineComponentEnds(s, sStart, sEnd);\r
- Vector3d sDir = new Vector3d(sEnd);\r
- sDir.sub(sStart);\r
- MathTools.intersectStraightStraight(sStart, sDir, o, d, currentPoint, new Point3d(), mu);\r
- \r
-\r
- } else {\r
- throw new RuntimeException("Lock shouldn't be on");\r
-\r
- }\r
- \r
- updateCurrentPoint();\r
- \r
- // branch point must lie between straight's ends. If connection point is exactly\r
- // on straight end user may want to connect pipes to each other\r
- // TODO : take account sizes of inline components)\r
- // TODO : actually make connection if its detected\r
- boolean connectPrev = false;\r
- boolean connectNext = false;\r
- \r
- if (mu[0] < 0.0) {\r
- currentPoint.set(sStart);\r
- connectPrev = true;\r
- }\r
- else if (mu[0] > 1.0) {\r
- currentPoint.set(sEnd);\r
- connectNext = true;\r
- }\r
- boolean connect = false;\r
- if (connectPrev) {\r
- PipeControlPoint pcp = s.getControlPoint();\r
- if (pcp.getPrevious() == null)\r
- connect = true;\r
- } else if (connectNext) {\r
- PipeControlPoint pcp = s.getControlPoint();\r
- if (pcp.getNext() == null)\r
- connect = true;\r
- }\r
- \r
- updateCurrentPoint();\r
- \r
- if (connect)\r
- info += "Connect pipes :";\r
- else\r
- info += "Make Branch :";\r
- \r
- setInfoText(info + currentPoint + " " + Math.max(0.0, Math.min(mu[0], 1.0)));\r
- if (connect) {\r
- if (connectNext) {\r
- return PositionType.NEXT;\r
- } else {\r
- return PositionType.PREVIOUS;\r
- }\r
- \r
- }\r
- return PositionType.SPLIT;\r
- \r
- }\r
- \r
- private IEntity endingToComponent(IEntity component, Vector3d o, Vector3d d) {\r
- // TODO : scan all empty pcps of the component and select closest one.\r
- return null;\r
- }\r
- \r
- private PositionType endingLockToStraight(VariableLengthInlineComponent s, double mu[]) {\r
- \r
- Point3d sStart = new Point3d();//G3DTools.getPoint(s.getHasControlPoint().getPreviousPoint().getLocalPosition());\r
- Point3d sEnd = new Point3d(); //G3DTools.getPoint(s.getHasControlPoint().getNextPoint().getLocalPosition());\r
- PipingTools2.getInlineComponentEnds(s, sStart, sEnd);\r
- Vector3d sDir = new Vector3d(sEnd);\r
- sDir.sub(sStart);\r
- Vector3d dir = new Vector3d(currentPoint);\r
- Point3d prev = controlPoints.get(controlPoints.size() - 1);\r
- dir.sub(prev);\r
- // intersection point in pipe where branch would be inserted to\r
- Vector3d branchPoint = new Vector3d();\r
- // intersection point in straight pipe that is currently routed\r
- Vector3d routePoint = new Vector3d();\r
- MathTools.intersectStraightStraight(sStart, sDir, new Vector3d(prev), dir, branchPoint, routePoint, mu);\r
- routePoint.sub(branchPoint);\r
- // startPoint of branch must be between pipe ends\r
- // TODO : take account sizes of elbows (or other components)\r
- // branch point must be between pipe ends and intersection points must be quite close to each othert\r
- if (mu[0] > 0.0 && mu[0] < 1.0 && routePoint.lengthSquared() < BRANCH_SNAP_DISTANCE) {\r
- currentPoint.set(branchPoint);\r
- \r
- updateCurrentPoint();\r
- \r
- setInfoText("Make branch (l) :" + currentPoint + " " + Math.max(0.0, Math.min(mu[0], 1.0)) + " " + routePoint.lengthSquared());\r
- return PositionType.SPLIT;\r
- }\r
- return null;\r
- }\r
- \r
- private boolean endingLockToNozzle(IEntity nozzle) {\r
- Vector3d dir = new Vector3d(currentPoint);\r
- Point3d prev = controlPoints.get(controlPoints.size() - 1);\r
- dir.sub(prev);\r
- Point3d nozzleLoc = G3DTools.getPoint(nozzle.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));\r
- double u[] = new double[1];\r
- Vector3d closest = MathTools.closestPointOnStraight(new Point3d(nozzleLoc), new Point3d(prev), new Vector3d(dir), u);\r
- double dist = nozzleLoc.distanceSquared(new Point3d(closest));\r
- if (dist < BRANCH_SNAP_DISTANCE) {\r
- // FIXME : directions should be checked (insert an elbow)\r
- currentPoint.set(nozzleLoc);\r
- updateCurrentPoint();\r
- setInfoText("Connect to nozzle (l) :" + currentPoint);\r
- return true;\r
- } \r
- //System.out.println(u[0]);\r
- return false;\r
- }\r
- \r
- private IEntity endingLockToComponent(IEntity component) {\r
- // we'll must scan all free pcp's and their direction to accept the connection.\r
- return null;\r
- }\r
- \r
- private void updateRoute(Vector3d o, Vector3d d) {\r
- detector.clearConstraintHighlights();\r
- Point3d previousPipePoint = controlPoints.get(controlPoints.size() - 1);\r
- String s = "";\r
- if (lock == LockType.NONE) {\r
- Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint));\r
- if (p != null)\r
- currentPoint = p;\r
- s += detector.getSnapString();\r
-\r
- } else {\r
- Vector3d dir = new Vector3d(currentPoint);\r
- dir.sub(previousPipePoint);\r
- Point3d p = detector.getPointSnap(new Vector3d(previousPipePoint), dir);\r
- if (p != null)\r
- currentPoint = p;\r
- s += detector.getSnapString();\r
-\r
- }\r
- \r
- updateCurrentPoint();\r
- s += currentPoint.toString();\r
- setInfoText(s);\r
- }\r
- \r
- private boolean updateCurrentPoint(Vector3d o, Vector3d d) {\r
- if (lock != LockType.CUSTOM) {\r
- if (input.keyPressed(KeyEvent.VK_X)) {\r
- if (lock == LockType.X)\r
- setLockType(LockType.YZ,false);\r
- else\r
- setLockType(LockType.X,false);\r
- }\r
- if (input.keyPressed(KeyEvent.VK_Y)) {\r
- if (lock == LockType.Y)\r
- setLockType(LockType.XZ,false);\r
- else\r
- setLockType(LockType.Y,false);\r
- }\r
- if (input.keyPressed(KeyEvent.VK_Z)) {\r
- if (lock == LockType.Z)\r
- setLockType(LockType.XY,false);\r
- else\r
- setLockType(LockType.Z,false);\r
- }\r
- if (input.keyPressed(KeyEvent.VK_N)) {\r
- setLockType(LockType.NONE,false);\r
- }\r
- if (input.keyPressed(KeyEvent.VK_BACK_SPACE)) {\r
- removePoint();\r
- }\r
- }\r
- Vector3d point = new Vector3d(lastPoint);\r
- boolean step = ((input.moveModifiers() & MouseEvent.CTRL_DOWN_MASK) > 0);\r
- switch(lock) {\r
- case X:\r
- MathTools.intersectStraightStraight(point, new Vector3d(1.0,0.0,0.0), o,d, currentPoint, new Vector3d());\r
- if (step) {\r
- currentPoint.x = Math.round(istep * currentPoint.x) / istep;\r
- BigDecimal bx = new BigDecimal(currentPoint.x);\r
- bx.setScale(decimals, BigDecimal.ROUND_HALF_UP);\r
- currentPoint.x = bx.doubleValue();\r
- }\r
- break;\r
- case Y:\r
- MathTools.intersectStraightStraight(point, new Vector3d(0.0,1.0,0.0), o,d, currentPoint, new Vector3d());\r
- if (step) {\r
- currentPoint.y = Math.round(istep * currentPoint.y) / istep;\r
- BigDecimal bx = new BigDecimal(currentPoint.y);\r
- bx.setScale(decimals, BigDecimal.ROUND_HALF_UP);\r
- currentPoint.y = bx.doubleValue();\r
- }\r
- break;\r
- case Z:\r
- MathTools.intersectStraightStraight(point, new Vector3d(0.0,0.0,1.0), o,d, currentPoint, new Vector3d());\r
- if (step) {\r
- currentPoint.z = Math.round(istep * currentPoint.z) / istep;\r
- BigDecimal bx = new BigDecimal(currentPoint.z);\r
- bx.setScale(decimals, BigDecimal.ROUND_HALF_UP);\r
- currentPoint.z = bx.doubleValue();\r
- }break;\r
- case XY:\r
- MathTools.intersectStraightPlane(o, d, point, new Vector3d(0.0,0.0,1.0), currentPoint);\r
- break;\r
- case XZ:\r
- MathTools.intersectStraightPlane(o, d, point, new Vector3d(0.0,1.0,0.0), currentPoint);\r
- break;\r
- case YZ:\r
- MathTools.intersectStraightPlane(o, d, point, new Vector3d(1.0,0.0,0.0), currentPoint);\r
- break;\r
- case NONE:\r
- Vector3d normal = parent.getCamera().getUnNormalizedHeading();\r
- normal.normalize();\r
- \r
- MathTools.intersectStraightPlane(o, d, point, normal, currentPoint);\r
- break;\r
- case CUSTOM:\r
- MathTools.intersectStraightStraight(point, new Vector3d(customLockDir), o,d, currentPoint, new Vector3d());\r
- double dist = MathTools.distanceFromPlane(new Vector3d(currentPoint), customLockDir, lastPoint);\r
- if (dist < 0.0)\r
- currentPoint.set(lastPoint);\r
- break;\r
- default:\r
- return false;\r
- }\r
- return true;\r
- }\r
- \r
- \r
- private ArrayList<Point3d> filterPoints() {\r
- ArrayList<Point3d> filteredControlPoints = new ArrayList<Point3d>();\r
- \r
- // this loop filters control points that are not needed\r
- for (int i = 0; i < controlPoints.size() - 2; i++) {\r
- Point3d start = controlPoints.get(i);\r
- if (i == 0)\r
- filteredControlPoints.add(start);\r
- \r
- Point3d middle = controlPoints.get(i+1);\r
- Point3d end = controlPoints.get(i+2);\r
- \r
- Vector3d dir1 = new Vector3d(middle);\r
- dir1.sub(start);\r
- Vector3d dir2 = new Vector3d(end);\r
- dir2.sub(middle);\r
- double angle = dir1.angle(dir2);\r
- if (angle > eps && angle < (Math.PI - eps))\r
- filteredControlPoints.add(middle);\r
- // if angle is near PI pipe turns back to where it started\r
- // if angle is near zero, pipe is straight and there's no need for control point\r
- \r
- if (i == controlPoints.size() - 3)\r
- filteredControlPoints.add(end);\r
- \r
- } \r
- return filteredControlPoints;\r
- }\r
- \r
- private PipeControlPoint connectPipeStart(Graph graph, PipeRun pipeRun, boolean reversed) {\r
- PipeControlPoint pcp = new PipeControlPoint(graph,selectedPort);\r
- IEntity beginComponent = EntityFactory.create(graph,beginComponentResource);\r
- if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.Nozzle)) {\r
- PipingTools2.linkNozzleAndPipeRun(beginComponent, pipeRun);\r
- // TODO : set diameters same\r
- //reversed = false;\r
- \r
- } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {\r
- switch (selectedType) {\r
- case NEXT:\r
- {\r
- PipeControlPoint tcp = createTurn(graph, pipeRun, 0);\r
- connectControlPoints(pcp, tcp, reversed);\r
- return tcp;\r
- }\r
- case PREVIOUS:\r
- {\r
- PipeControlPoint tcp = createTurn(graph, pipeRun, 0);\r
- connectControlPoints(pcp, tcp, reversed);\r
- return tcp;\r
- }\r
- case SPLIT:\r
- //reversed = false;\r
- // 1. create (non visible) splitting component.\r
- PipelineComponent newComponent = PipingTools2.instantiatePipelineComponent(graph, PipingTools2.getPipeRun(beginComponent).getResource(), ProcessResource.plant3Dresource.BranchSplitComponent); \r
- PipeControlPoint mainCP = newComponent.getControlPoint();\r
- // 2. create control point for the branch\r
- BranchEndControlPoint becp = BranchEndControlPoint.createDefault(graph);\r
- mainCP.addSubPoint(becp);\r
- pipeRun.addControlPoints(becp);\r
- pcp = becp.toPipeControlPoint();\r
- ControlPointTools.setWorldPosition(mainCP, controlPoints.get(0));\r
- \r
- PipingTools2.splitVariableLengthComponent(newComponent, beginComponent);\r
- }\r
- } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.PipelineComponent)) {\r
- //if (selectedType == PositionType.PREVIOUS)\r
- //reversed = true;\r
- //else\r
- //reversed = false;\r
- } else {\r
- throw new RuntimeException("unknown starting component");\r
- }\r
- \r
- return pcp;\r
- }\r
- \r
- private PipeControlPoint connectPipeEnd(Graph graph, PipeRun pipeline, boolean reversed) {\r
- PipeControlPoint pcp = null;\r
- IEntity endComponent = null;\r
- if (endComponentResource != null)\r
- endComponent = EntityFactory.create(graph, endComponentResource);\r
- if (endComponent == null) {\r
- return null;\r
- } else if (endComponent.isInstanceOf(ProcessResource.plant3Dresource.Nozzle)){\r
- pcp = new PipeControlPoint(endComponent.getSingleRelatedObject(ProcessResource.plant3Dresource.HasControlPoint));\r
- PipingTools2.linkNozzleAndPipeRun(endComponent, pipeline);\r
- } else if (endComponent.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {\r
- assert(endPortType != null);\r
- if (endPortType == PositionType.SPLIT) {\r
- //System.out.println(lastPoint + " " + currentPoint + " " + positions.get(positions.size() - 1));\r
- Point3d pos = lastPoint;\r
- // 1. create (non visible) splitting component.\r
- PipelineComponent newComponent = PipingTools2.instantiatePipelineComponent(graph, PipingTools2.getPipeRun(endComponent).getResource(), ProcessResource.plant3Dresource.BranchSplitComponent);\r
- \r
- PipeControlPoint mainCP = newComponent.getControlPoint();\r
- // 2. create control point for the branch\r
- BranchEndControlPoint becp = BranchEndControlPoint.createDefault(graph);\r
- mainCP.addSubPoint(becp);\r
- pipeline.addControlPoints(becp);\r
- pcp = becp.toPipeControlPoint();\r
- ControlPointTools.setWorldPosition(mainCP, pos);\r
- \r
- PipingTools2.splitVariableLengthComponent(newComponent, endComponent);\r
- } else {\r
- \r
- } \r
- } else if (endComponent.isInstanceOf(ProcessResource.plant3Dresource.FixedLengthInlineComponent)) {\r
- // attach to selected port, reverse the piperun if needed\r
- pcp = new PipeControlPoint(graph,endComponentPort);\r
- if (!reversed && pcp.getPrevious() != null || reversed && pcp.getNext() != null) {\r
- PipingTools2.reversePipeRun(ControlPointTools.getPipeRun(pcp));\r
- }\r
- }\r
- return pcp;\r
- }\r
- \r
- private PipeControlPoint createTurn(Graph coreTC,PipeRun pipeRun, int i) {\r
- PipelineComponent elbow = PipingTools2.instantiatePipelineComponent(coreTC,pipeRun.getResource(), ProcessResource.plant3Dresource.Elbow);\r
- G3DAPI.setWorldPosition(elbow, controlPoints.get(i));\r
- return elbow.getControlPoint();\r
- }\r
- \r
- private PipeControlPoint createInline(Graph graph, PipeRun pipeRun, int i) {\r
- Point3d p1 = controlPoints.get(i-1);\r
- Point3d p2 = controlPoints.get(i);\r
- Vector3d v = new Vector3d(p2);\r
- v.sub(p1);\r
- double length = v.length();\r
- v.scale(0.5);\r
- v.add(p1);\r
- PipelineComponent straight = PipingTools2.instantiatePipelineComponent(graph,pipeRun.getResource(), ProcessResource.plant3Dresource.Straight);\r
- G3DAPI.setWorldPosition(straight, v);\r
- straight.setRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength, length);\r
- return straight.getControlPoint();\r
- \r
- }\r
- \r
- private void connectControlPoints(PipeControlPoint previous, PipeControlPoint pcp, boolean reversed) {\r
- if (previous != null) {\r
- PipeControlPoint sccp;\r
- PipeControlPoint ocp;\r
- if (previous.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {\r
- sccp = previous;\r
- ocp = sccp.getSubPoint().iterator().next();\r
- } else if (previous.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {\r
- ocp = previous;\r
- sccp = ocp.getSubPointOf();\r
- } else {\r
- if (!reversed) {\r
- previous.setNext(pcp);\r
- pcp.setPrevious(previous);\r
- } else {\r
- previous.setPrevious(pcp);\r
- pcp.setNext(previous);\r
- }\r
- return;\r
- }\r
- if (!reversed) {\r
- sccp.setNext(pcp);\r
- ocp.setNext(pcp);\r
- pcp.setPrevious(ocp);\r
- } else {\r
- sccp.setPrevious(pcp);\r
- ocp.setPrevious(pcp);\r
- pcp.setNext(sccp);\r
- }\r
- \r
- }\r
- }\r
- \r
- private void endPiping() {\r
- state = ToolState.NOT_ACTIVE;\r
- \r
- if (controlPoints.size() > 2) // if there's only two control points, filtering does nothing\r
- controlPoints = filterPoints();\r
- \r
- if (controlPoints.size() > 1) {\r
- parent.getSession().asyncWrite(new GraphRequestAdapter() {\r
- @Override\r
- public GraphRequestStatus perform(Graph graph) throws Exception {\r
- PipeRun pipeline = null;\r
- boolean reversed;\r
- PipelineComponent beginComponent = new PipelineComponent(graph,beginComponentResource);\r
- if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.Nozzle) ||\r
- selectedType == PositionType.SPLIT) {\r
-\r
- \r
-// \r
- pipeline = PipeRun.createDefault(graph);\r
- ((ProcessEditor) parent).getPlant(graph).addChild(pipeline);\r
- pipeline.setPipeDiameter(pipeDiameter);\r
- pipeline.setTurnRadius(elbowRadius);\r
- reversed = false;\r
- } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.SizeChangeComponent)||\r
- beginComponent.isInstanceOf(ProcessResource.plant3Dresource.OffsetComponent)){\r
- PipeControlPoint pcp = new PipeControlPoint(graph,selectedPort);\r
- if (selectedType == PositionType.NEXT) {\r
- // get the piperun from offsetpoint\r
- reversed = false;\r
- pipeline = pcp.getSubPoint().iterator().next().getControlPointOfPipeRun();\r
- } else if (selectedType == PositionType.PREVIOUS) {\r
- reversed = true;\r
- pipeline = pcp.getControlPointOfPipeRun();\r
- } else {\r
- throw new RuntimeException("Wrong PsoitionType " + selectedType + " for a SizeChangeComponent");\r
- }\r
- \r
- } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.PipelineComponent)) {\r
- \r
- pipeline = new PipeRun(beginComponent.getParent());\r
- if (selectedType == PositionType.PREVIOUS) {\r
- reversed = true;\r
- } else {\r
- reversed = false;\r
- }\r
- } else {\r
- throw new RuntimeException("Cannot start routing pipe : object not supported!");\r
- }\r
-\r
- PipeControlPoint previous = null;\r
- for (int i = 0; i < controlPoints.size(); i++) {\r
- PipeControlPoint pcp = null;\r
- if (i == 0) {\r
- pcp = connectPipeStart(graph, pipeline,reversed);\r
-\r
- } else {\r
- pcp = createInline(graph, pipeline, i);\r
- connectControlPoints(previous, pcp, reversed);\r
- previous = pcp;\r
- if (i == controlPoints.size() - 1) {\r
- pcp = connectPipeEnd(graph, pipeline, reversed);\r
- } else {\r
- \r
- pcp = createTurn(graph,pipeline,i);\r
- }\r
- }\r
- \r
- if (pcp != null) {\r
- connectControlPoints(previous, pcp, reversed);\r
- //pipeline.addSgetHasControlPointSet().add(pcp);\r
- previous = pcp;\r
- }\r
- }\r
- return GraphRequestStatus.transactionComplete();\r
- }\r
- \r
- @Override\r
- public void requestCompleted(GraphRequestStatus status) {\r
- endThreaded();\r
- }\r
- });\r
-\r
- \r
- \r
- } else {\r
- endThreaded(); \r
- }\r
- }\r
- \r
- private void endThreaded() {\r
- parent.getRenderingComposite().getDisplay().asyncExec(new Runnable() {\r
- @Override\r
- public void run() {\r
- end();\r
- }\r
- });\r
- }\r
-\r
- @Override\r
- public void init() {\r
- this.setText("Route pipe");\r
- this.setToolTipText("Starts routing a new pipeline");\r
- this.setImageDescriptor(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Straight.png"));\r
- }\r
-\r
- @Override\r
- public boolean usable(Graph g, List<Resource> resources) {\r
- if (resources.size() != 1) {\r
- return false;\r
- }\r
- return checkStartNode(g,resources.get(0)).size() > 0;\r
- }\r
- \r
- \r
- \r
- public boolean acceptDrop(StructuredResourceSelection s, Resource[] ids) {\r
- if (s.size() != 1)\r
- return false;\r
- if (ids == null)\r
- return false;\r
- if (ids.length != 1)\r
- return false;\r
- final Resource dropped = ids[0];\r
- final Resource target = s.iterator().next();\r
- GraphRequestWithResult<Boolean> query = new GraphRequestWithResult<Boolean>() {\r
- @Override\r
- public Boolean performWithResult(Graph g) throws Exception {\r
- if(!g.isInstanceOf(dropped, ProcessResource.plant3Dresource.VariableLengthInlineComponent))\r
- return false;\r
- // TODO : check that type is not abstract\r
- List<Resource> list = new ArrayList<Resource>();\r
- list.add(target);\r
- return usable(g, list);\r
- }\r
- };\r
- parent.getSession().syncRead(query);\r
- return query.getResult();\r
- }\r
- \r
- public void doDrop(StructuredResourceSelection s, Resource[] ids) {\r
- beginComponentResource = s.iterator().next(); \r
- parent.setCurrentAction(this);\r
- }\r
- \r
- public void setInfoText(String text) {\r
- \r
- }\r
-\r
-}
\ No newline at end of file