1 /*******************************************************************************
\r
2 * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.
\r
3 * All rights reserved. This program and the accompanying materials
\r
4 * are made available under the terms of the Eclipse Public License v1.0
\r
5 * which accompanies this distribution, and is available at
\r
6 * http://www.eclipse.org/legal/epl-v10.html
\r
9 * VTT Technical Research Centre of Finland - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package fi.vtt.simantics.processeditor.actions;
\r
13 import java.awt.event.KeyEvent;
\r
14 import java.awt.event.MouseEvent;
\r
15 import java.math.BigDecimal;
\r
16 import java.util.ArrayList;
\r
17 import java.util.List;
\r
19 import javax.vecmath.Point3d;
\r
20 import javax.vecmath.Vector3d;
\r
22 import org.eclipse.jface.action.Action;
\r
23 import org.eclipse.jface.action.IToolBarManager;
\r
24 import org.eclipse.jface.resource.ImageDescriptor;
\r
25 import org.simantics.db.Graph;
\r
26 import org.simantics.db.GraphRequestAdapter;
\r
27 import org.simantics.db.GraphRequestStatus;
\r
28 import org.simantics.db.GraphRequestWithResult;
\r
29 import org.simantics.db.Resource;
\r
30 import org.simantics.layer0.utils.EntityFactory;
\r
31 import org.simantics.layer0.utils.IEntity;
\r
32 import org.simantics.proconf.g3d.actions.InteractiveAction;
\r
33 import org.simantics.proconf.g3d.base.ConstraintDetector;
\r
34 import org.simantics.proconf.g3d.base.G3DAPI;
\r
35 import org.simantics.proconf.g3d.base.G3DTools;
\r
36 import org.simantics.proconf.g3d.base.MathTools;
\r
37 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;
\r
38 import org.simantics.proconf.g3d.common.StructuredResourceSelection;
\r
39 import org.simantics.proconf.g3d.dnd.DropListener;
\r
40 import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;
\r
41 import org.simantics.utils.datastructures.Pair;
\r
43 import com.jme.renderer.ColorRGBA;
\r
44 import com.jme.scene.Geometry;
\r
45 import com.jme.scene.Line;
\r
46 import com.jme.scene.state.MaterialState;
\r
48 import fi.vtt.simantics.processeditor.Activator;
\r
49 import fi.vtt.simantics.processeditor.ProcessResource;
\r
50 import fi.vtt.simantics.processeditor.common.ControlPointTools;
\r
51 import fi.vtt.simantics.processeditor.common.PipeComponentProvider;
\r
52 import fi.vtt.simantics.processeditor.common.PipingTools2;
\r
53 import fi.vtt.simantics.processeditor.common.PipingTools2.Direction;
\r
54 import fi.vtt.simantics.processeditor.dialogs.PipelineDialog;
\r
55 import fi.vtt.simantics.processeditor.gizmo.PositionSelectionGizmo;
\r
56 import fi.vtt.simantics.processeditor.stubs.BranchEndControlPoint;
\r
57 import fi.vtt.simantics.processeditor.stubs.PipeControlPoint;
\r
58 import fi.vtt.simantics.processeditor.stubs.PipeRun;
\r
59 import fi.vtt.simantics.processeditor.stubs.PipelineComponent;
\r
60 import fi.vtt.simantics.processeditor.stubs.VariableLengthInlineComponent;
\r
61 import fi.vtt.simantics.processeditor.views.ProcessEditor;
\r
64 * Action for Routing Pipes
\r
66 * FIXME : does several thing that should be done by PipingTools.
\r
67 * TODO : instead of using lines to show route of pipe, generate pipe and change it real-time
\r
72 public class RoutePipeAction extends InteractiveAction implements DropListener, SplitPointListener {
\r
75 private static final ImageDescriptor X_AXIS_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/x-axis.png");
\r
76 private static final ImageDescriptor Y_AXIS_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/y-axis.png");
\r
77 private static final ImageDescriptor Z_AXIS_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/z-axis.png");
\r
78 private static final ImageDescriptor X_PLANE_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/x-plane.png");
\r
79 private static final ImageDescriptor Y_PLANE_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/y-plane.png");
\r
80 private static final ImageDescriptor Z_PLANE_ICON = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/z-plane.png");
\r
82 private static final ImageDescriptor CAMERA_ICON = Activator.imageDescriptorFromPlugin("org.simantics.proconf.g3d", "icons/eye.png");
\r
85 private Action xAxisAction;
\r
86 private Action yAxisAction;
\r
87 private Action zAxisAction;
\r
88 private Action xPlaneAction;
\r
89 private Action yPlaneAction;
\r
90 private Action zPlaneAction;
\r
92 private Action cameraAction;
\r
94 ConstraintDetector detector = null;
\r
96 public RoutePipeAction(ThreeDimensionalEditorBase parent) {
\r
98 detector = new ConstraintDetector(parent);
\r
99 xAxisAction = new Action("X",Action.AS_RADIO_BUTTON) {
\r
100 public void run() {
\r
101 if (lock == LockType.X)
\r
102 setLockType(LockType.NONE,false);
\r
104 setLockType(LockType.X,false);
\r
107 xAxisAction.setImageDescriptor(X_AXIS_ICON);
\r
108 xAxisAction.setToolTipText("Lock X-Axis");
\r
109 yAxisAction = new Action("Y",Action.AS_RADIO_BUTTON) {
\r
110 public void run() {
\r
111 if (lock == LockType.Y)
\r
112 setLockType(LockType.NONE,false);
\r
114 setLockType(LockType.Y,false);
\r
117 yAxisAction.setImageDescriptor(Y_AXIS_ICON);
\r
118 yAxisAction.setToolTipText("Lock Y-Axis");
\r
119 zAxisAction = new Action("Z",Action.AS_RADIO_BUTTON) {
\r
120 public void run() {
\r
121 if (lock == LockType.Z)
\r
122 setLockType(LockType.NONE,false);
\r
124 setLockType(LockType.Z,false);
\r
127 zAxisAction.setImageDescriptor(Z_AXIS_ICON);
\r
128 zAxisAction.setToolTipText("Lock Z-Axis");
\r
129 xPlaneAction = new Action("X",Action.AS_RADIO_BUTTON) {
\r
130 public void run() {
\r
131 if (lock == LockType.YZ)
\r
132 setLockType(LockType.NONE,false);
\r
134 setLockType(LockType.YZ,false);
\r
137 xPlaneAction.setImageDescriptor(X_PLANE_ICON);
\r
138 xPlaneAction.setToolTipText("Lock X-Plane");
\r
139 yPlaneAction = new Action("Y",Action.AS_RADIO_BUTTON) {
\r
140 public void run() {
\r
141 if (lock == LockType.XZ)
\r
142 setLockType(LockType.NONE,false);
\r
144 setLockType(LockType.XZ,false);
\r
147 yPlaneAction.setImageDescriptor(Y_PLANE_ICON);
\r
148 yPlaneAction.setToolTipText("Lock Y-Plane");
\r
149 zPlaneAction = new Action("Z",Action.AS_RADIO_BUTTON) {
\r
150 public void run() {
\r
151 if (lock == LockType.XY)
\r
152 setLockType(LockType.NONE,false);
\r
154 setLockType(LockType.XY,false);
\r
157 zPlaneAction.setImageDescriptor(Z_PLANE_ICON);
\r
158 zPlaneAction.setToolTipText("Lock Z-Plane");
\r
159 cameraAction = new Action("C", Action.AS_CHECK_BOX) {
\r
160 public void run() {
\r
161 useCamera = this.isChecked();
\r
164 cameraAction.setImageDescriptor(CAMERA_ICON);
\r
165 cameraAction.setToolTipText("Use camera");
\r
166 splitPointAction = new SelectSplitPointAction(parent,this);
\r
170 public void fillToolBar(IToolBarManager manager) {
\r
172 manager.add(cameraAction);
\r
173 cameraAction.setChecked(useCamera);
\r
174 manager.add(xAxisAction);
\r
175 manager.add(yAxisAction);
\r
176 manager.add(zAxisAction);
\r
177 manager.add(xPlaneAction);
\r
178 manager.add(yPlaneAction);
\r
179 manager.add(zPlaneAction);
\r
183 enum LockType {NONE,X,Y,Z,XY,YZ,XZ,CUSTOM};
\r
184 LockType lock = LockType.NONE;
\r
186 private void setLockType(LockType type, boolean force) {
\r
187 if (force || lock != LockType.CUSTOM) {
\r
190 xAxisAction.setChecked(false);
\r
191 yAxisAction.setChecked(false);
\r
192 zAxisAction.setChecked(false);
\r
193 xPlaneAction.setChecked(false);
\r
194 yPlaneAction.setChecked(false);
\r
195 zPlaneAction.setChecked(false);
\r
196 xAxisAction.setEnabled(true);
\r
197 yAxisAction.setEnabled(true);
\r
198 zAxisAction.setEnabled(true);
\r
199 xPlaneAction.setEnabled(true);
\r
200 yPlaneAction.setEnabled(true);
\r
201 zPlaneAction.setEnabled(true);
\r
204 xAxisAction.setChecked(true);
\r
207 yAxisAction.setChecked(true);
\r
210 zAxisAction.setChecked(true);
\r
213 zPlaneAction.setChecked(true);
\r
216 yPlaneAction.setChecked(true);
\r
219 xPlaneAction.setChecked(true);
\r
222 xAxisAction.setEnabled(false);
\r
223 yAxisAction.setEnabled(false);
\r
224 zAxisAction.setEnabled(false);
\r
225 xPlaneAction.setEnabled(false);
\r
226 yPlaneAction.setEnabled(false);
\r
227 zPlaneAction.setEnabled(false);
\r
232 private double BRANCH_SNAP_DISTANCE = 0.05;
\r
233 private double NOZZLE_SNAP_DISTANCE = 0.05;
\r
235 private double istep = 10.0;
\r
236 private int decimals = 2;
\r
238 private double pipeDiameter = 0.2;
\r
239 private double elbowRadius = 0.5;
\r
240 private double eps = 0.001;
\r
242 private ArrayList<Point3d> controlPoints = new ArrayList<Point3d>();
\r
244 private Point3d currentPoint = new Point3d();
\r
245 private Point3d lastPoint = new Point3d();
\r
247 private Vector3d customLockDir = null;
\r
249 private Line selectionLine;
\r
250 private List<Line> pipeShapes = new ArrayList<Line>();
\r
251 private MaterialState ms;
\r
254 private Resource selectedPort = null;
\r
255 private PositionType selectedType = null;
\r
256 private Resource beginComponentResource = null;
\r
258 private Resource endComponentResource = null;
\r
259 private Resource endComponentPort = null;
\r
260 private PositionType endPortType = null;
\r
262 private Resource highlightedResource = null;
\r
264 private boolean useCamera = false;
\r
266 private List<Pair<Resource, PositionType>> positions = null;
\r
268 private SelectSplitPointAction splitPointAction;
\r
269 private PositionSelectionGizmo gizmo = null;
\r
273 private enum ToolState{NOT_ACTIVE, INITIALIZING, SELECTING_POSITION, SELECTING_SPLIT, ROUTING};
\r
274 private ToolState state = ToolState.NOT_ACTIVE;
\r
277 public void activate() {
\r
278 state = ToolState.INITIALIZING;
\r
279 controlPoints.clear();
\r
280 if (beginComponentResource == null) {
\r
281 List<IGraphicsNode> mos = parent.getSelectionAdapter().getSelectedObjects();
\r
282 if (mos.size() != 1) {
\r
286 beginComponentResource = mos.get(0).getResource();
\r
288 parent.getSession().asyncRead(new GraphRequestAdapter() {
\r
290 public GraphRequestStatus perform(Graph g) throws Exception {
\r
291 positions = checkStartNode(g,beginComponentResource);
\r
292 if (positions.size() == 0) {
\r
296 state = ToolState.SELECTING_POSITION;
\r
298 return GraphRequestStatus.transactionComplete();
\r
303 ms = parent.getRenderingComponent().getDisplaySystem().getRenderer().createMaterialState();
\r
304 ms.setEmissive(new ColorRGBA(1.f,1.f,1.f,1.f));
\r
312 public void deactivate() {
\r
313 for (Line l : pipeShapes)
\r
314 l.removeFromParent();
\r
315 pipeShapes.clear();
\r
316 if (selectionLine != null)
\r
317 selectionLine.removeFromParent();
\r
318 selectionLine = null;
\r
319 customLockDir = null;
\r
321 setLockType(LockType.NONE,true);
\r
322 beginComponentResource = null;
\r
323 endComponentResource = null;
\r
324 detector.clearConstraintHighlights();
\r
325 state = ToolState.NOT_ACTIVE;
\r
326 selectedPort = null;
\r
327 selectedType = null;
\r
331 private List<Pair<Resource, PositionType>> checkStartNode(Graph g, Resource resource) {
\r
332 List<Pair<Resource, PositionType>> positions = new ArrayList<Pair<Resource,PositionType>>();
\r
334 IEntity beginComponent = EntityFactory.create(g, resource);
\r
336 if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.Nozzle)) {
\r
337 if (PipingTools2.isFreeNozzle(beginComponent)) {
\r
339 positions.add(new Pair<Resource, PositionType>(beginComponent.getSingleRelatedObject(ProcessResource.plant3Dresource.HasControlPoint).getResource(),PositionType.NEXT));
\r
341 } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {
\r
342 // variable length inline component is exception from other pipeline components,
\r
343 // since a new pipe can branch it
\r
344 VariableLengthInlineComponent vlic = new VariableLengthInlineComponent(beginComponent);
\r
345 PipeControlPoint pcp = vlic.getControlPoint();
\r
346 if (pcp.getNext() == null) {
\r
348 positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.NEXT));
\r
349 } else if (pcp.getPrevious() == null) {
\r
351 positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.PREVIOUS));
\r
353 positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.SPLIT));
\r
354 } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.EndComponent)) {
\r
355 PipelineComponent component = new PipelineComponent(beginComponent);
\r
356 PipeControlPoint pcp = component.getControlPoint();
\r
357 if (pcp.getNext() == null && pcp.getPrevious() == null) {
\r
358 throw new RuntimeException("End component " + beginComponent.getResource() + " is not connected to anything.");
\r
359 //positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.NEXT));
\r
361 for (PipeControlPoint p : pcp.getSubPoint()) {
\r
362 if (p.getNext() == null && p.getPrevious() == null) {
\r
363 positions.add(new Pair<Resource, PositionType>(p.getResource(),PositionType.NEXT));
\r
366 } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.PipelineComponent)) {
\r
368 PipelineComponent component = new PipelineComponent(beginComponent);
\r
370 PipeControlPoint pcp = component.getControlPoint();
\r
371 if (pcp.getNext() == null) {
\r
372 positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.NEXT));
\r
373 } else if (pcp.getPrevious() == null) {
\r
374 positions.add(new Pair<Resource, PositionType>(pcp.getResource(),PositionType.PREVIOUS));
\r
376 if (!beginComponent.isInstanceOf(ProcessResource.plant3Dresource.SizeChangeComponent)||
\r
377 !beginComponent.isInstanceOf(ProcessResource.plant3Dresource.OffsetComponent)) {
\r
378 for (PipeControlPoint p : pcp.getSubPoint()) {
\r
379 if (p.getNext() == null && p.getPrevious() == null) {
\r
380 positions.add(new Pair<Resource, PositionType>(p.getResource(),PositionType.NEXT));
\r
391 public void update() {
\r
395 return; // TODO : throw Exception?
\r
398 case SELECTING_POSITION:
\r
399 updateSelectPosition();
\r
401 case SELECTING_SPLIT:
\r
402 updateSelectSplit();
\r
411 private void updateSelectPosition() {
\r
413 if (positions == null) {
\r
414 throw new RuntimeException("positions must be loaded before select position can be activated");
\r
416 if (selectedPort != null) {
\r
417 throw new RuntimeException("position is already selected");
\r
419 if (positions.size() == 1) {
\r
420 selectedPort = positions.get(0).first;
\r
421 selectedType = positions.get(0).second;
\r
422 state = ToolState.INITIALIZING;
\r
426 if (requiresNewPipeRun()){
\r
427 if(!getNewPipeRunSpecs()) {
\r
432 if (selectedType == PositionType.SPLIT) {
\r
438 } else if (gizmo == null) {
\r
439 state = ToolState.INITIALIZING; // asyncRead!
\r
440 parent.getSession().asyncRead(new GraphRequestAdapter() {
\r
442 public GraphRequestStatus perform(Graph g) throws Exception {
\r
443 List<Pair<Point3d, PositionType>> pos = new ArrayList<Pair<Point3d,PositionType>>();
\r
444 for (Pair<Resource, PositionType> p : positions) {
\r
445 IEntity entity = EntityFactory.create(g,p.first);
\r
446 Point3d position = ControlPointTools.getRealPosition(entity, p.second);
\r
447 pos.add(new Pair<Point3d, PositionType>(position,p.second));
\r
449 gizmo = new PositionSelectionGizmo(parent, pos);
\r
450 parent.setGizmo(gizmo);
\r
451 parent.getRenderingComponent().getNoShadowRoot().attachChild(gizmo.getNode());
\r
452 state = ToolState.SELECTING_POSITION;
\r
453 return GraphRequestStatus.transactionComplete();
\r
460 if (input.keyPressed(KeyEvent.VK_ESCAPE)) {
\r
461 state = ToolState.INITIALIZING;
\r
462 parent.setGizmo(null);
\r
468 if (gizmo.getSelected() >= 0 && input.mouseClicked() && input.clickButton() == MouseEvent.BUTTON1) {
\r
469 state = ToolState.INITIALIZING; // asyncRead!
\r
470 parent.setGizmo(null);
\r
471 selectedPort = positions.get(gizmo.getSelected()).first;
\r
472 selectedType = positions.get(gizmo.getSelected()).second;
\r
475 if (selectedType == PositionType.SPLIT) {
\r
484 parent.getDefaultAction().update();
\r
491 private boolean requiresNewPipeRun() {
\r
492 GraphRequestWithResult<Boolean> createsNewPipeline = new GraphRequestWithResult<Boolean>() {
\r
494 public Boolean performWithResult(Graph g) throws Exception {
\r
495 if(g.isInstanceOf(selectedPort, ProcessResource.plant3Dresource.NozzleControlPoint))
\r
497 if (selectedType == PositionType.SPLIT)
\r
503 parent.getSession().syncRead(createsNewPipeline);
\r
504 return createsNewPipeline.getResult();
\r
507 private boolean getNewPipeRunSpecs() {
\r
508 PipelineDialog dialog;
\r
509 dialog = new PipelineDialog(parent.getRenderingComposite().getShell(),pipeDiameter,elbowRadius);
\r
510 if (dialog.open() == PipelineDialog.CANCEL) {
\r
514 pipeDiameter = dialog.getPipeDiameter();
\r
515 elbowRadius = dialog.getTurnRadius();
\r
519 private void startRouting() {
\r
520 state = ToolState.INITIALIZING;
\r
521 parent.getSession().asyncRead(new GraphRequestAdapter() {
\r
523 public GraphRequestStatus perform(Graph g) throws Exception {
\r
524 PipeControlPoint pcp = new PipeControlPoint(g,selectedPort);
\r
525 lastPoint = ControlPointTools.getRealPosition(pcp, selectedType);//G3DTools.getPoint(pcp.getWorldPosition());
\r
526 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint)) {
\r
527 lock = LockType.CUSTOM;
\r
528 customLockDir = ControlPointTools.getDirectedControlPointDirection(pcp);
\r
529 } else if (pcp.isInstanceOf(ProcessResource.plant3Dresource.FixedLengthControlPoint)||
\r
530 pcp.isInstanceOf(ProcessResource.plant3Dresource.TurnControlPoint)) {
\r
531 lock = LockType.CUSTOM;
\r
532 if (selectedType == PositionType.NEXT)
\r
533 customLockDir = ControlPointTools.getPathLegDirection(pcp, Direction.NEXT);
\r
535 customLockDir = ControlPointTools.getPathLegDirection(pcp, Direction.PREVIOUS);
\r
537 lock = LockType.NONE;
\r
539 IEntity pipeRun = ControlPointTools.getPipeRun(pcp);
\r
540 if (pipeRun != null) {
\r
541 pipeDiameter = pipeRun.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasPipeDiameter);
\r
542 elbowRadius = pipeRun.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasTurnRadius);
\r
544 return GraphRequestStatus.transactionComplete();
\r
548 public void requestCompleted(GraphRequestStatus status) {
\r
550 state = ToolState.ROUTING;
\r
555 private void startSplitting() {
\r
556 parent.getSession().asyncRead(new GraphRequestAdapter() {
\r
558 public GraphRequestStatus perform(Graph g) throws Exception {
\r
559 PipeControlPoint pcp = new PipeControlPoint(g,selectedPort);
\r
560 Point3d p1 = new Point3d();
\r
561 Point3d p2 = new Point3d();
\r
562 ControlPointTools.getInlineControlPointEnds(pcp, p1, p2);
\r
563 splitPointAction.setSplit(p1, p2);
\r
564 splitPointAction.activate();
\r
565 state = ToolState.SELECTING_SPLIT;
\r
566 return GraphRequestStatus.transactionComplete();
\r
572 private void updateSelectSplit() {
\r
573 if (splitPointAction.active()) {
\r
574 splitPointAction.update();
\r
577 throw new RuntimeException("SplitPointAction should be active");
\r
582 public void setSplitPoint(Point3d point) {
\r
583 splitPointAction.deactivate();
\r
584 if (point == null) {
\r
592 state = ToolState.ROUTING;
\r
596 private void updateRouting() {
\r
597 if(input.keyPressed(KeyEvent.VK_ESCAPE)) {
\r
598 controlPoints.clear();
\r
602 if (input.keyPressed(KeyEvent.VK_C)) {
\r
603 useCamera = !useCamera;
\r
604 cameraAction.setChecked(useCamera);
\r
607 parent.getDefaultAction().update();
\r
611 parent.getSession().syncRead(new GraphRequestAdapter() {
\r
613 public GraphRequestStatus perform(Graph g) throws Exception {
\r
615 Vector3d o = new Vector3d();
\r
616 Vector3d d = new Vector3d();
\r
617 parent.createPickRay(o, d);
\r
618 if (!updateCurrentPoint(o, d))
\r
619 return GraphRequestStatus.transactionComplete();
\r
620 //Point3d startPoint = new Point3d();
\r
621 double mu[] = new double[2];
\r
623 IEntity endTo = null;
\r
624 PositionType endType = null;
\r
625 IEntity endPort = null;
\r
627 if (parent.getSelectionAdapter().getHighlightSelection().size() > 0) {
\r
628 highlightedResource = parent.getSelectionAdapter().getHighlightSelection().getSelectionList().get(0);
\r
630 highlightedResource = null;
\r
633 if (highlightedResource != null) {
\r
634 IEntity highlightNode = EntityFactory.create(g,highlightedResource);
\r
636 if (lock == LockType.NONE) {
\r
637 if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.Nozzle) && endingToNozzle(highlightNode,o,d)) {
\r
638 endTo = highlightNode;
\r
639 } else if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {
\r
640 endTo = highlightNode;
\r
641 endType = endingToStraight(new VariableLengthInlineComponent(highlightNode),mu,o,d);
\r
642 } else if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.PipelineComponent) && (endPort = endingToComponent(highlightNode,o,d)) != null) {
\r
643 endTo = highlightNode;
\r
648 if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent) && (endType = endingLockToStraight(new VariableLengthInlineComponent(highlightNode),mu)) != null) {
\r
649 endTo = highlightNode;
\r
650 } else if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.Nozzle) && endingLockToNozzle(highlightNode)) {
\r
651 endTo = highlightNode;
\r
652 } else if (highlightNode.isInstanceOf(ProcessResource.plant3Dresource.PipelineComponent) && (endPort = endingLockToComponent(highlightNode)) != null) {
\r
653 endTo = highlightNode;
\r
664 parent.setViewChanged(true);
\r
665 if (input.mouseClicked()) {
\r
666 if (input.clickButton() == MouseEvent.BUTTON1) {
\r
667 if (controlPoints.size() > 0) {
\r
669 setLockType(LockType.NONE,true);
\r
670 if (endTo != null) {
\r
671 endComponentResource = endTo.getResource();
\r
672 if (endPort != null)
\r
673 endComponentPort = endPort.getResource();
\r
674 endPortType = endType;
\r
679 throw new RuntimeException("kjf");
\r
680 // // user was selecting position of branch
\r
681 // lastPoint.set(startPoint);
\r
682 // controlPoints.add(new Point3d(startPoint));
\r
683 // if (selectionLine != null)
\r
684 // selectionLine.removeFromParent();
\r
685 // selectionLine = null;
\r
687 } else if (input.clickButton() == MouseEvent.BUTTON2){
\r
688 detector.updateConstraintReference();
\r
689 } else if (input.clickButton() == MouseEvent.BUTTON3){
\r
694 return GraphRequestStatus.transactionComplete();
\r
700 private void createLine() {
\r
701 controlPoints.add(new Point3d(lastPoint));
\r
702 Line line = new Line();
\r
703 line.setRenderState(ms);
\r
705 PipeComponentProvider.createStraightEdges(line, currentPoint, currentPoint, pipeDiameter*0.5);
\r
706 pipeShapes.add(line);
\r
707 parent.getRenderingComponent().getNoShadowRoot().attachChild(line);
\r
708 line.setCullMode(Geometry.CULL_NEVER);
\r
713 * Adds current point to pipeline
\r
716 private void addPoint() {
\r
718 controlPoints.add(new Point3d(currentPoint));
\r
719 Line line = new Line();
\r
720 line.setRenderState(ms);
\r
721 PipeComponentProvider.createStraightEdges(line, controlPoints.get(controlPoints.size() - 1), currentPoint, pipeDiameter*0.5);
\r
722 pipeShapes.add(line);
\r
723 parent.getRenderingComponent().getNoShadowRoot().attachChild(line);
\r
724 line.setCullMode(Geometry.CULL_NEVER);
\r
725 lastPoint.set(currentPoint);
\r
729 * Updates tool graphics for current point
\r
731 private void updateCurrentPoint() {
\r
732 PipeComponentProvider.createStraightEdges(pipeShapes.get(pipeShapes.size() - 1), controlPoints.get(controlPoints.size() - 1), currentPoint, pipeDiameter*0.5);
\r
736 * Removes last point from pipeline
\r
738 public void removePoint() {
\r
739 if (controlPoints.size() < 2)
\r
741 controlPoints.remove(controlPoints.size() - 1);
\r
743 pipeShapes.get(pipeShapes.size() - 1).removeFromParent();
\r
744 pipeShapes.remove(pipeShapes.size() - 1);
\r
745 PipeComponentProvider.createStraightEdges(pipeShapes.get(pipeShapes.size() - 1), controlPoints.get(controlPoints.size() - 1), currentPoint, pipeDiameter*0.5);
\r
747 lastPoint.set(controlPoints.get(controlPoints.size()-1));
\r
748 if (controlPoints.size() < 2 && customLockDir != null) {
\r
749 setLockType(LockType.CUSTOM, true);
\r
755 private boolean endingToNozzle(IEntity nozzle,Vector3d o, Vector3d d) {
\r
756 IEntity pcp = nozzle.getSingleRelatedObject(ProcessResource.plant3Dresource.HasControlPoint);
\r
757 if (pcp != null && (pcp.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasNext) != null ||
\r
758 pcp.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasPrevious) != null))
\r
759 return false; // nozzle is already connected to pipe
\r
760 currentPoint = G3DTools.getPoint(nozzle.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
761 Point3d previousPipePoint = controlPoints.get(controlPoints.size() - 1);
\r
762 Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint));
\r
764 if (p.distance(currentPoint) > NOZZLE_SNAP_DISTANCE) {
\r
769 updateCurrentPoint();
\r
771 setInfoText("Connect to nozzle " + currentPoint);
\r
776 private PositionType endingToStraight(VariableLengthInlineComponent s, double mu[], Vector3d o, Vector3d d) {
\r
778 Point3d sStart = new Point3d();
\r
779 Point3d sEnd = new Point3d();
\r
780 //detector.clearConstraintHighlights();
\r
782 Point3d previousPipePoint = controlPoints.get(controlPoints.size() - 1);
\r
784 if (lock == LockType.NONE) {
\r
785 Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint));
\r
788 // snapping is detected, check if snapped point can create branch with straight
\r
789 PositionType t = endingLockToStraight(s, mu);
\r
792 // if not, we'll have to remove highlight that was added when snapped point was detected
\r
793 detector.clearConstraintHighlights();
\r
796 PipingTools2.getInlineComponentEnds(s, sStart, sEnd);
\r
797 Vector3d sDir = new Vector3d(sEnd);
\r
799 MathTools.intersectStraightStraight(sStart, sDir, o, d, currentPoint, new Point3d(), mu);
\r
803 throw new RuntimeException("Lock shouldn't be on");
\r
807 updateCurrentPoint();
\r
809 // branch point must lie between straight's ends. If connection point is exactly
\r
810 // on straight end user may want to connect pipes to each other
\r
811 // TODO : take account sizes of inline components)
\r
812 // TODO : actually make connection if its detected
\r
813 boolean connectPrev = false;
\r
814 boolean connectNext = false;
\r
817 currentPoint.set(sStart);
\r
818 connectPrev = true;
\r
820 else if (mu[0] > 1.0) {
\r
821 currentPoint.set(sEnd);
\r
822 connectNext = true;
\r
824 boolean connect = false;
\r
826 PipeControlPoint pcp = s.getControlPoint();
\r
827 if (pcp.getPrevious() == null)
\r
829 } else if (connectNext) {
\r
830 PipeControlPoint pcp = s.getControlPoint();
\r
831 if (pcp.getNext() == null)
\r
835 updateCurrentPoint();
\r
838 info += "Connect pipes :";
\r
840 info += "Make Branch :";
\r
842 setInfoText(info + currentPoint + " " + Math.max(0.0, Math.min(mu[0], 1.0)));
\r
845 return PositionType.NEXT;
\r
847 return PositionType.PREVIOUS;
\r
851 return PositionType.SPLIT;
\r
855 private IEntity endingToComponent(IEntity component, Vector3d o, Vector3d d) {
\r
856 // TODO : scan all empty pcps of the component and select closest one.
\r
860 private PositionType endingLockToStraight(VariableLengthInlineComponent s, double mu[]) {
\r
862 Point3d sStart = new Point3d();//G3DTools.getPoint(s.getHasControlPoint().getPreviousPoint().getLocalPosition());
\r
863 Point3d sEnd = new Point3d(); //G3DTools.getPoint(s.getHasControlPoint().getNextPoint().getLocalPosition());
\r
864 PipingTools2.getInlineComponentEnds(s, sStart, sEnd);
\r
865 Vector3d sDir = new Vector3d(sEnd);
\r
867 Vector3d dir = new Vector3d(currentPoint);
\r
868 Point3d prev = controlPoints.get(controlPoints.size() - 1);
\r
870 // intersection point in pipe where branch would be inserted to
\r
871 Vector3d branchPoint = new Vector3d();
\r
872 // intersection point in straight pipe that is currently routed
\r
873 Vector3d routePoint = new Vector3d();
\r
874 MathTools.intersectStraightStraight(sStart, sDir, new Vector3d(prev), dir, branchPoint, routePoint, mu);
\r
875 routePoint.sub(branchPoint);
\r
876 // startPoint of branch must be between pipe ends
\r
877 // TODO : take account sizes of elbows (or other components)
\r
878 // branch point must be between pipe ends and intersection points must be quite close to each othert
\r
879 if (mu[0] > 0.0 && mu[0] < 1.0 && routePoint.lengthSquared() < BRANCH_SNAP_DISTANCE) {
\r
880 currentPoint.set(branchPoint);
\r
882 updateCurrentPoint();
\r
884 setInfoText("Make branch (l) :" + currentPoint + " " + Math.max(0.0, Math.min(mu[0], 1.0)) + " " + routePoint.lengthSquared());
\r
885 return PositionType.SPLIT;
\r
890 private boolean endingLockToNozzle(IEntity nozzle) {
\r
891 Vector3d dir = new Vector3d(currentPoint);
\r
892 Point3d prev = controlPoints.get(controlPoints.size() - 1);
\r
894 Point3d nozzleLoc = G3DTools.getPoint(nozzle.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
895 double u[] = new double[1];
\r
896 Vector3d closest = MathTools.closestPointOnStraight(new Point3d(nozzleLoc), new Point3d(prev), new Vector3d(dir), u);
\r
897 double dist = nozzleLoc.distanceSquared(new Point3d(closest));
\r
898 if (dist < BRANCH_SNAP_DISTANCE) {
\r
899 // FIXME : directions should be checked (insert an elbow)
\r
900 currentPoint.set(nozzleLoc);
\r
901 updateCurrentPoint();
\r
902 setInfoText("Connect to nozzle (l) :" + currentPoint);
\r
905 //System.out.println(u[0]);
\r
909 private IEntity endingLockToComponent(IEntity component) {
\r
910 // we'll must scan all free pcp's and their direction to accept the connection.
\r
914 private void updateRoute(Vector3d o, Vector3d d) {
\r
915 detector.clearConstraintHighlights();
\r
916 Point3d previousPipePoint = controlPoints.get(controlPoints.size() - 1);
\r
918 if (lock == LockType.NONE) {
\r
919 Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint));
\r
922 s += detector.getSnapString();
\r
925 Vector3d dir = new Vector3d(currentPoint);
\r
926 dir.sub(previousPipePoint);
\r
927 Point3d p = detector.getPointSnap(new Vector3d(previousPipePoint), dir);
\r
930 s += detector.getSnapString();
\r
934 updateCurrentPoint();
\r
935 s += currentPoint.toString();
\r
939 private boolean updateCurrentPoint(Vector3d o, Vector3d d) {
\r
940 if (lock != LockType.CUSTOM) {
\r
941 if (input.keyPressed(KeyEvent.VK_X)) {
\r
942 if (lock == LockType.X)
\r
943 setLockType(LockType.YZ,false);
\r
945 setLockType(LockType.X,false);
\r
947 if (input.keyPressed(KeyEvent.VK_Y)) {
\r
948 if (lock == LockType.Y)
\r
949 setLockType(LockType.XZ,false);
\r
951 setLockType(LockType.Y,false);
\r
953 if (input.keyPressed(KeyEvent.VK_Z)) {
\r
954 if (lock == LockType.Z)
\r
955 setLockType(LockType.XY,false);
\r
957 setLockType(LockType.Z,false);
\r
959 if (input.keyPressed(KeyEvent.VK_N)) {
\r
960 setLockType(LockType.NONE,false);
\r
962 if (input.keyPressed(KeyEvent.VK_BACK_SPACE)) {
\r
966 Vector3d point = new Vector3d(lastPoint);
\r
967 boolean step = ((input.moveModifiers() & MouseEvent.CTRL_DOWN_MASK) > 0);
\r
970 MathTools.intersectStraightStraight(point, new Vector3d(1.0,0.0,0.0), o,d, currentPoint, new Vector3d());
\r
972 currentPoint.x = Math.round(istep * currentPoint.x) / istep;
\r
973 BigDecimal bx = new BigDecimal(currentPoint.x);
\r
974 bx.setScale(decimals, BigDecimal.ROUND_HALF_UP);
\r
975 currentPoint.x = bx.doubleValue();
\r
979 MathTools.intersectStraightStraight(point, new Vector3d(0.0,1.0,0.0), o,d, currentPoint, new Vector3d());
\r
981 currentPoint.y = Math.round(istep * currentPoint.y) / istep;
\r
982 BigDecimal bx = new BigDecimal(currentPoint.y);
\r
983 bx.setScale(decimals, BigDecimal.ROUND_HALF_UP);
\r
984 currentPoint.y = bx.doubleValue();
\r
988 MathTools.intersectStraightStraight(point, new Vector3d(0.0,0.0,1.0), o,d, currentPoint, new Vector3d());
\r
990 currentPoint.z = Math.round(istep * currentPoint.z) / istep;
\r
991 BigDecimal bx = new BigDecimal(currentPoint.z);
\r
992 bx.setScale(decimals, BigDecimal.ROUND_HALF_UP);
\r
993 currentPoint.z = bx.doubleValue();
\r
996 MathTools.intersectStraightPlane(o, d, point, new Vector3d(0.0,0.0,1.0), currentPoint);
\r
999 MathTools.intersectStraightPlane(o, d, point, new Vector3d(0.0,1.0,0.0), currentPoint);
\r
1002 MathTools.intersectStraightPlane(o, d, point, new Vector3d(1.0,0.0,0.0), currentPoint);
\r
1005 Vector3d normal = parent.getCamera().getUnNormalizedHeading();
\r
1006 normal.normalize();
\r
1008 MathTools.intersectStraightPlane(o, d, point, normal, currentPoint);
\r
1011 MathTools.intersectStraightStraight(point, new Vector3d(customLockDir), o,d, currentPoint, new Vector3d());
\r
1012 double dist = MathTools.distanceFromPlane(new Vector3d(currentPoint), customLockDir, lastPoint);
\r
1014 currentPoint.set(lastPoint);
\r
1023 private ArrayList<Point3d> filterPoints() {
\r
1024 ArrayList<Point3d> filteredControlPoints = new ArrayList<Point3d>();
\r
1026 // this loop filters control points that are not needed
\r
1027 for (int i = 0; i < controlPoints.size() - 2; i++) {
\r
1028 Point3d start = controlPoints.get(i);
\r
1030 filteredControlPoints.add(start);
\r
1032 Point3d middle = controlPoints.get(i+1);
\r
1033 Point3d end = controlPoints.get(i+2);
\r
1035 Vector3d dir1 = new Vector3d(middle);
\r
1037 Vector3d dir2 = new Vector3d(end);
\r
1039 double angle = dir1.angle(dir2);
\r
1040 if (angle > eps && angle < (Math.PI - eps))
\r
1041 filteredControlPoints.add(middle);
\r
1042 // if angle is near PI pipe turns back to where it started
\r
1043 // if angle is near zero, pipe is straight and there's no need for control point
\r
1045 if (i == controlPoints.size() - 3)
\r
1046 filteredControlPoints.add(end);
\r
1049 return filteredControlPoints;
\r
1052 private PipeControlPoint connectPipeStart(Graph graph, PipeRun pipeRun, boolean reversed) {
\r
1053 PipeControlPoint pcp = new PipeControlPoint(graph,selectedPort);
\r
1054 IEntity beginComponent = EntityFactory.create(graph,beginComponentResource);
\r
1055 if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.Nozzle)) {
\r
1056 PipingTools2.linkNozzleAndPipeRun(beginComponent, pipeRun);
\r
1057 // TODO : set diameters same
\r
1058 //reversed = false;
\r
1060 } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {
\r
1061 switch (selectedType) {
\r
1064 PipeControlPoint tcp = createTurn(graph, pipeRun, 0);
\r
1065 connectControlPoints(pcp, tcp, reversed);
\r
1070 PipeControlPoint tcp = createTurn(graph, pipeRun, 0);
\r
1071 connectControlPoints(pcp, tcp, reversed);
\r
1075 //reversed = false;
\r
1076 // 1. create (non visible) splitting component.
\r
1077 PipelineComponent newComponent = PipingTools2.instantiatePipelineComponent(graph, PipingTools2.getPipeRun(beginComponent).getResource(), ProcessResource.plant3Dresource.BranchSplitComponent);
\r
1078 PipeControlPoint mainCP = newComponent.getControlPoint();
\r
1079 // 2. create control point for the branch
\r
1080 BranchEndControlPoint becp = BranchEndControlPoint.createDefault(graph);
\r
1081 mainCP.addSubPoint(becp);
\r
1082 pipeRun.addControlPoints(becp);
\r
1083 pcp = becp.toPipeControlPoint();
\r
1084 ControlPointTools.setWorldPosition(mainCP, controlPoints.get(0));
\r
1086 PipingTools2.splitVariableLengthComponent(newComponent, beginComponent);
\r
1088 } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.PipelineComponent)) {
\r
1089 //if (selectedType == PositionType.PREVIOUS)
\r
1090 //reversed = true;
\r
1092 //reversed = false;
\r
1094 throw new RuntimeException("unknown starting component");
\r
1100 private PipeControlPoint connectPipeEnd(Graph graph, PipeRun pipeline, boolean reversed) {
\r
1101 PipeControlPoint pcp = null;
\r
1102 IEntity endComponent = null;
\r
1103 if (endComponentResource != null)
\r
1104 endComponent = EntityFactory.create(graph, endComponentResource);
\r
1105 if (endComponent == null) {
\r
1107 } else if (endComponent.isInstanceOf(ProcessResource.plant3Dresource.Nozzle)){
\r
1108 pcp = new PipeControlPoint(endComponent.getSingleRelatedObject(ProcessResource.plant3Dresource.HasControlPoint));
\r
1109 PipingTools2.linkNozzleAndPipeRun(endComponent, pipeline);
\r
1110 } else if (endComponent.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {
\r
1111 assert(endPortType != null);
\r
1112 if (endPortType == PositionType.SPLIT) {
\r
1113 //System.out.println(lastPoint + " " + currentPoint + " " + positions.get(positions.size() - 1));
\r
1114 Point3d pos = lastPoint;
\r
1115 // 1. create (non visible) splitting component.
\r
1116 PipelineComponent newComponent = PipingTools2.instantiatePipelineComponent(graph, PipingTools2.getPipeRun(endComponent).getResource(), ProcessResource.plant3Dresource.BranchSplitComponent);
\r
1118 PipeControlPoint mainCP = newComponent.getControlPoint();
\r
1119 // 2. create control point for the branch
\r
1120 BranchEndControlPoint becp = BranchEndControlPoint.createDefault(graph);
\r
1121 mainCP.addSubPoint(becp);
\r
1122 pipeline.addControlPoints(becp);
\r
1123 pcp = becp.toPipeControlPoint();
\r
1124 ControlPointTools.setWorldPosition(mainCP, pos);
\r
1126 PipingTools2.splitVariableLengthComponent(newComponent, endComponent);
\r
1130 } else if (endComponent.isInstanceOf(ProcessResource.plant3Dresource.FixedLengthInlineComponent)) {
\r
1131 // attach to selected port, reverse the piperun if needed
\r
1132 pcp = new PipeControlPoint(graph,endComponentPort);
\r
1133 if (!reversed && pcp.getPrevious() != null || reversed && pcp.getNext() != null) {
\r
1134 PipingTools2.reversePipeRun(ControlPointTools.getPipeRun(pcp));
\r
1140 private PipeControlPoint createTurn(Graph coreTC,PipeRun pipeRun, int i) {
\r
1141 PipelineComponent elbow = PipingTools2.instantiatePipelineComponent(coreTC,pipeRun.getResource(), ProcessResource.plant3Dresource.Elbow);
\r
1142 G3DAPI.setWorldPosition(elbow, controlPoints.get(i));
\r
1143 return elbow.getControlPoint();
\r
1146 private PipeControlPoint createInline(Graph graph, PipeRun pipeRun, int i) {
\r
1147 Point3d p1 = controlPoints.get(i-1);
\r
1148 Point3d p2 = controlPoints.get(i);
\r
1149 Vector3d v = new Vector3d(p2);
\r
1151 double length = v.length();
\r
1154 PipelineComponent straight = PipingTools2.instantiatePipelineComponent(graph,pipeRun.getResource(), ProcessResource.plant3Dresource.Straight);
\r
1155 G3DAPI.setWorldPosition(straight, v);
\r
1156 straight.setRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength, length);
\r
1157 return straight.getControlPoint();
\r
1161 private void connectControlPoints(PipeControlPoint previous, PipeControlPoint pcp, boolean reversed) {
\r
1162 if (previous != null) {
\r
1163 PipeControlPoint sccp;
\r
1164 PipeControlPoint ocp;
\r
1165 if (previous.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
1167 ocp = sccp.getSubPoint().iterator().next();
\r
1168 } else if (previous.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
1170 sccp = ocp.getSubPointOf();
\r
1173 previous.setNext(pcp);
\r
1174 pcp.setPrevious(previous);
\r
1176 previous.setPrevious(pcp);
\r
1177 pcp.setNext(previous);
\r
1182 sccp.setNext(pcp);
\r
1184 pcp.setPrevious(ocp);
\r
1186 sccp.setPrevious(pcp);
\r
1187 ocp.setPrevious(pcp);
\r
1188 pcp.setNext(sccp);
\r
1194 private void endPiping() {
\r
1195 state = ToolState.NOT_ACTIVE;
\r
1197 if (controlPoints.size() > 2) // if there's only two control points, filtering does nothing
\r
1198 controlPoints = filterPoints();
\r
1200 if (controlPoints.size() > 1) {
\r
1201 parent.getSession().asyncWrite(new GraphRequestAdapter() {
\r
1203 public GraphRequestStatus perform(Graph graph) throws Exception {
\r
1204 PipeRun pipeline = null;
\r
1206 PipelineComponent beginComponent = new PipelineComponent(graph,beginComponentResource);
\r
1207 if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.Nozzle) ||
\r
1208 selectedType == PositionType.SPLIT) {
\r
1212 pipeline = PipeRun.createDefault(graph);
\r
1213 ((ProcessEditor) parent).getPlant(graph).addChild(pipeline);
\r
1214 pipeline.setPipeDiameter(pipeDiameter);
\r
1215 pipeline.setTurnRadius(elbowRadius);
\r
1217 } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.SizeChangeComponent)||
\r
1218 beginComponent.isInstanceOf(ProcessResource.plant3Dresource.OffsetComponent)){
\r
1219 PipeControlPoint pcp = new PipeControlPoint(graph,selectedPort);
\r
1220 if (selectedType == PositionType.NEXT) {
\r
1221 // get the piperun from offsetpoint
\r
1223 pipeline = pcp.getSubPoint().iterator().next().getControlPointOfPipeRun();
\r
1224 } else if (selectedType == PositionType.PREVIOUS) {
\r
1226 pipeline = pcp.getControlPointOfPipeRun();
\r
1228 throw new RuntimeException("Wrong PsoitionType " + selectedType + " for a SizeChangeComponent");
\r
1231 } else if (beginComponent.isInstanceOf(ProcessResource.plant3Dresource.PipelineComponent)) {
\r
1233 pipeline = new PipeRun(beginComponent.getParent());
\r
1234 if (selectedType == PositionType.PREVIOUS) {
\r
1240 throw new RuntimeException("Cannot start routing pipe : object not supported!");
\r
1243 PipeControlPoint previous = null;
\r
1244 for (int i = 0; i < controlPoints.size(); i++) {
\r
1245 PipeControlPoint pcp = null;
\r
1247 pcp = connectPipeStart(graph, pipeline,reversed);
\r
1250 pcp = createInline(graph, pipeline, i);
\r
1251 connectControlPoints(previous, pcp, reversed);
\r
1253 if (i == controlPoints.size() - 1) {
\r
1254 pcp = connectPipeEnd(graph, pipeline, reversed);
\r
1257 pcp = createTurn(graph,pipeline,i);
\r
1261 if (pcp != null) {
\r
1262 connectControlPoints(previous, pcp, reversed);
\r
1263 //pipeline.addSgetHasControlPointSet().add(pcp);
\r
1267 return GraphRequestStatus.transactionComplete();
\r
1271 public void requestCompleted(GraphRequestStatus status) {
\r
1283 private void endThreaded() {
\r
1284 parent.getRenderingComposite().getDisplay().asyncExec(new Runnable() {
\r
1286 public void run() {
\r
1293 public void init() {
\r
1294 this.setText("Route pipe");
\r
1295 this.setToolTipText("Starts routing a new pipeline");
\r
1296 this.setImageDescriptor(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Straight.png"));
\r
1300 public boolean usable(Graph g, List<Resource> resources) {
\r
1301 if (resources.size() != 1) {
\r
1304 return checkStartNode(g,resources.get(0)).size() > 0;
\r
1309 public boolean acceptDrop(StructuredResourceSelection s, Resource[] ids) {
\r
1310 if (s.size() != 1)
\r
1314 if (ids.length != 1)
\r
1316 final Resource dropped = ids[0];
\r
1317 final Resource target = s.iterator().next();
\r
1318 GraphRequestWithResult<Boolean> query = new GraphRequestWithResult<Boolean>() {
\r
1320 public Boolean performWithResult(Graph g) throws Exception {
\r
1321 if(!g.isInstanceOf(dropped, ProcessResource.plant3Dresource.VariableLengthInlineComponent))
\r
1323 // TODO : check that type is not abstract
\r
1324 List<Resource> list = new ArrayList<Resource>();
\r
1326 return usable(g, list);
\r
1329 parent.getSession().syncRead(query);
\r
1330 return query.getResult();
\r
1333 public void doDrop(StructuredResourceSelection s, Resource[] ids) {
\r
1334 beginComponentResource = s.iterator().next();
\r
1335 parent.setCurrentAction(this);
\r
1338 public void setInfoText(String text) {
\r