import javax.vecmath.Tuple3d;
import javax.vecmath.Vector3d;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Label;
import org.simantics.db.Resource;
import org.simantics.g3d.math.MathTools;
import org.simantics.g3d.math.Ray;
import org.simantics.g3d.scenegraph.NodeMap;
import org.simantics.g3d.scenegraph.base.INode;
+import org.simantics.g3d.toolbar.ToolComposite;
import org.simantics.g3d.tools.ConstraintDetector;
import org.simantics.g3d.vtk.gizmo.TranslateAxisGizmo;
import org.simantics.g3d.vtk.swt.InteractiveVtkComposite;
public class RoutePipeAction extends vtkSwtAction {
enum LockType {
- X, Y, Z, XY, YZ, XZ, NONE, CUSTOM
+ X, Y, Z, XY, XZ, YZ, NONE, CUSTOM
};
LockType lock = LockType.NONE;
+ boolean lockForced;
private double BRANCH_SNAP_DISTANCE = 0.05;
private double NOZZLE_SNAP_DISTANCE = 0.05;
+ private static double BRANCH_DOT_PRODUCT = 0.95; // dot product value used for prevent branch creation
+ private static double ALIGN_DOT_PRODUCT = 0.99; // dot product for creating turn when connecting pipes
private double istep = 10.0;
private int decimals = 2;
private Set<PositionType> allowed = new HashSet<PositionType>();
- public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root) {
- this(panel,root, true);
+ protected ToolComposite toolComposite;
+ protected Combo axisCombo;
+ protected Button cameraButton;
+
+ public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root, ToolComposite toolComposite) {
+ this(panel,root, toolComposite, true);
}
- public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root, boolean allowBranches) {
+ public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root, ToolComposite toolComposite, boolean allowBranches) {
super(panel);
this.root = root;
this.allowBranches = allowBranches;
terminalSelectionGizmo = new TerminalSelectionGizmo(panel);
constraintPointGizmo = new ConstraintPointGizmo(panel);
detector = new org.simantics.g3d.vtk.swt.ConstraintDetector(panel);
+ this.toolComposite = toolComposite;
}
public void setComponent(PipelineComponent component) {
setEnabled(allowed.size() > 0);
}
- public void deattach() {
- deactivate();
- startComponent = null;
-
- deattachUI();
- super.deattach();
- panel.refresh();
- }
+ protected void createTools(ToolComposite toolComposite) {
+ Label label = new Label(toolComposite, SWT.READ_ONLY);
+ label.setText("Route direction:");
+ axisCombo = new Combo(toolComposite, SWT.READ_ONLY);
+ axisCombo.add("X");
+ axisCombo.add("Y");
+ axisCombo.add("Z");
+ axisCombo.add("XY");
+ axisCombo.add("XZ");
+ axisCombo.add("YZ");
+ axisCombo.add("None");
+ axisCombo.add("Custom");
+ axisCombo.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Combo c = (Combo)e.getSource();
+ setLockType(LockType.values()[c.getSelectionIndex()],false);
+ panel.getComponent().setFocus();
+
+ }
+ });
+ axisCombo.select(lock.ordinal());
+ cameraButton = new Button(toolComposite, SWT.TOGGLE);
+ cameraButton.setText("Camera");
+ cameraButton.setSelection(useDefault);
+ cameraButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ setUseDefault(((Button)e.getSource()).getSelection());
+ panel.getComponent().setFocus();
+ }
+ });
+ Button close = new Button(toolComposite, SWT.PUSH);
+ close.setText("Close");
+ close.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ panel.useDefaultAction();
+ };
+ });
+ toolComposite.relayout();
+ }
+
+ public void deattach() {
+ deactivate();
+ setDBUndo(true);
+ if (toolComposite != null) {
+ toolComposite.clear();
+ axisCombo = null;
+ cameraButton = null;
+ }
+
+ startComponent = null;
+
+ deattachUI();
+ super.deattach();
+ panel.refresh();
+ }
public void attach() {
if (startComponent == null)
return;
-
+ if (toolComposite != null) {
+ createTools(toolComposite);
+ }
+ setDBUndo(false);
super.attach();
ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
public void run() {
public boolean keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
panel.useDefaultAction();
- if (lock != LockType.CUSTOM) {
+ if (lock != LockType.CUSTOM || !lockForced) {
if ((e.getModifiersEx() & KeyEvent.SHIFT_DOWN_MASK) > 0) {
if (e.getKeyCode() == KeyEvent.VK_X) {
if (lock != LockType.XY && lock != LockType.XZ) {
else
setLockType(LockType.NONE, false);
}
+ if (e.getKeyCode() == KeyEvent.VK_L && direction != null) {
+ if (lock != LockType.CUSTOM)
+ setLockType(LockType.CUSTOM, false);
+ else
+ setLockType(LockType.NONE, false);
+ }
}
}
if (e.getKeyCode() == KeyEvent.VK_C) {
- useDefault = !useDefault;
- System.out.println("UseDefault " + useDefault);
+ setUseDefault(!useDefault);
}
-
-
-
update();
return true;
}
+ private void setUseDefault(boolean b) {
+ useDefault = b;
+ if (useDefault)
+ setInfoText("Rotating camera");
+ if (cameraButton != null)
+ cameraButton.setSelection(useDefault);
+ }
+
private void update() {
panel.refresh();
protected void activateNextPrev(PipeControlPoint start) throws Exception{
if (!reversed && start.isDualInline())
- start = start.getSubPoint().get(0);
+ start = start.getDualSub();
else if (reversed && start.isDualSub())
start = start.parent;
if (startComponent instanceof Nozzle) {
direction = startComponent.getControlPoint().getDirectedControlPointDirection();
lock = LockType.CUSTOM;
+ lockForced = true;
} else if (startComponent instanceof PipelineComponent){
if (startComponent instanceof InlineComponent) {
- direction = startComponent.getControlPoint().getPathLegDirection(reversed ? Direction.PREVIOUS : Direction.NEXT);
+ direction = startComponent.getControlPoint().getInlineDir();
+ if (reversed) direction.negate();
lock = LockType.CUSTOM;
+ lockForced = true;
if (((InlineComponent) startComponent).isVariableLength()) {
startWithTurn = true;
direction = null;
lock = LockType.NONE;
+ lockForced = false;
}
Vector3d v = new Vector3d();
if (!reversed) {
if (start.asFixedAngle()) {
direction = startComponent.getControlPoint().getPathLegDirection(reversed ? Direction.PREVIOUS : Direction.NEXT);
lock = LockType.CUSTOM;
+ lockForced = start.isFixedAngle();
} else {
direction = null;
lock = LockType.NONE;
+ lockForced = false;
}
} else if (startComponent instanceof EndComponent) {
throw new Exception("Not supported");
translateAxisGizmo.attach(panel);
setPreviousPosition(previousPosition);
updateCurrentPoint();
+ updateWidget();
}
protected void setPreviousPosition(Vector3d v) {
translateAxisGizmo.attach(panel);
setPreviousPosition(previousPosition);
updateCurrentPoint();
+ updateWidget();
}
private void activateSplit(PipeControlPoint start) throws Exception{
}
private void setLockType(LockType type, boolean force) {
- if (force || lock != LockType.CUSTOM) {
+ if (type == LockType.CUSTOM && (direction == null || added.size() > 0)) {
+ // nothing to do..
+ } else if (force || (lock != LockType.CUSTOM || !lockForced || added.size() > 0) ) {
+
lock = type;
switch (lock) {
break;
}
+
}
+ updateWidget();
+ }
+
+ private void updateWidget() {
+ if (axisCombo != null) {
+ axisCombo.select(lock.ordinal());
+ axisCombo.setEnabled(!lockForced || lock != LockType.CUSTOM);
+ }
}
@Override
addPoint();
}
} else {
- throw new RuntimeException("RoutePipeAction initlialization has been failed, no added components found");
+ throw new RuntimeException("RoutePipeAction initialization has failed, no added components found");
// // user was selecting position of branch
// lastPoint.set(startPoint);
// controlPoints.add(new Point3d(startPoint));
updateRoute(o,d);
}
} else {
- if (hoverObject instanceof InlineComponent && ((InlineComponent)hoverObject).isVariableLength() && (endType = endingLockToStraight(hoverObject,mu)) != null) {
+ if (hoverObject instanceof InlineComponent && ((InlineComponent)hoverObject).isVariableLength() && (endType = endingLockToStraight(hoverObject,mu, new Point3d(currentPosition))) != null) {
endTo = (InlineComponent)hoverObject;
} else if (hoverObject instanceof Nozzle && endingLockToNozzle(hoverObject)) {
endTo = (Nozzle)hoverObject;
return true;
}
+ @SuppressWarnings("unused")
private Vector3d getLockDir() {
switch (lock) {
case CUSTOM:
return new Vector3d(0,1,0);
case Z:
return new Vector3d(0,0,1);
+ default:
+ return null;
}
- return null;
}
protected void updateRoute(Vector3d o, Vector3d d) {
}
private PositionType endingToStraight(INode straightNode, double mu[], Vector3d o, Vector3d d) {
- if (!allowBranches) {
- updateCurrentPoint();
- return null;
- }
+// if (!allowBranches) {
+// updateCurrentPoint();
+// return null;
+// }
InlineComponent s = (InlineComponent)straightNode;
- String info = "";
+
Point3d sStart = new Point3d();
Point3d sEnd = new Point3d();
s.getEnds(sStart, sEnd);
if (p != null) {
currentPosition = new Vector3d(p);
// snapping is detected, check if snapped point can create branch with straight
- PositionType t = endingLockToStraight(s, mu);
+ PositionType t = endingLockToStraight(s, mu, currentPipePoint);
if (t != null)
return t;
// if not, we'll have to remove highlight that was added when snapped point was detected
// 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;
- }
+ return endingToStraight(mu, s, sStart, sEnd, currentPipePoint);
+ }
+
+ private PositionType endingToStraight(double mu[], InlineComponent s, Point3d sStart, Point3d sEnd , Point3d currentPipePoint) {
+ String info = "";
+
+ boolean connectPrev = false;
+ boolean connectNext = false;
+ boolean branch = false;
+ if (mu[0] < 0.1) {
+ connectPrev = true;
+ }
+ else if (mu[0] > 0.9) {
+ connectNext = true;
+ }
-
- if (connectPrev) {
- PipeControlPoint pcp = s.getControlPoint();
- if (pcp.getPrevious() != null)
- connectPrev = false;
- } else if (connectNext) {
- PipeControlPoint pcp = s.getControlPoint();
- if (pcp.getNext() != null)
- connectNext = false;
- } else {
- Vector3d dir = s.getControlPoint().getPathLegDirection(Direction.NEXT);
- Vector3d currDir = getLast().getControlPoint().getPathLegDirection(Direction.NEXT);
- dir.normalize();
- currDir.normalize();
- double dot = dir.dot(currDir);
- System.out.println(dot + " " + currDir + " " + dir);
- if (dot > 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;
- }
-
+
+ if (connectPrev) {
+ PipeControlPoint pcp = s.getControlPoint();
+ if (pcp.getPrevious() != null)
+ connectPrev = false;
+ } else if (connectNext) {
+ PipeControlPoint pcp = s.getControlPoint();
+ if (pcp.getNext() != null)
+ connectNext = false;
+ } else {
+ Vector3d dir = s.getControlPoint().getPathLegDirection(Direction.NEXT);
+ Vector3d currDir = getLast().getControlPoint().getPathLegDirection(Direction.NEXT);
+ dir.normalize();
+ currDir.normalize();
+ double dot = dir.dot(currDir);
+ System.out.println(dot + " " + currDir + " " + dir);
+ if (dot > BRANCH_DOT_PRODUCT || dot < -BRANCH_DOT_PRODUCT) {
+ // pipes are almost in the same direction, creating a branch is not feasible.
+ branch = false;
+ } else {
+ branch = true;
+ }
+ }
+
+
+ if (connectNext || connectPrev)
+ info += "Connect pipes :";
+ else if (branch)
+ info += "Create a Branch :";
+
+ setInfoText(info + currentPosition + " " + Math.max(0.0, Math.min(mu[0], 1.0)));
+ if (connectNext) {
+ currentPosition.set(sEnd);
+ updateCurrentPoint();
+ return PositionType.NEXT;
+ } else if (connectPrev){
+ currentPosition.set(sStart);
+ updateCurrentPoint();
+ return PositionType.PREVIOUS;
+ } else if (branch && allowBranches) {
+ return PositionType.SPLIT;
+ } else {
+ currentPosition.set(currentPipePoint);
+ updateCurrentPoint();
+ return null;
+ }
}
private PipeControlPoint endingToComponent(INode componentNode, Vector3d o, Vector3d d) {
PipelineComponent component = (PipelineComponent)componentNode;
PipeControlPoint pcp = component.getControlPoint();
+ PipeControlPoint connect = null;
if (component instanceof EndComponent) {
if (pcp.getNext() != null || pcp.getPrevious() != null)
return null;
- return pcp;
+ connect = pcp;
} else if (component instanceof TurnComponent) {
if (pcp.getNext() == null || pcp.getPrevious() == null)
- return pcp;
- return null;
+ connect = pcp;
+ else
+ return null;
} else if (component instanceof InlineComponent) {
// TODO : scan all empty pcps of the component and select closest one.
if (pcp.getNext() == null || pcp.getPrevious() == null)
- return pcp;
- return null;
+ connect = pcp;
+ else
+ return null;
+ }
+ if (connect != null) {
+ currentPosition.set(connect.getWorldPosition());
+ updateCurrentPoint();
+ setInfoText("Connect to " + component.getName());
+ return connect;
}
-
return null;
}
- private PositionType endingLockToStraight(INode straightNode, double mu[]) {
- if (!allowBranches) {
- updateCurrentPoint();
- return null;
- }
+ private PositionType endingLockToStraight(INode straightNode, double mu[], Point3d currentPipePoint) {
+// if (!allowBranches) {
+// updateCurrentPoint();
+// return null;
+// }
InlineComponent s = (InlineComponent)straightNode;
Point3d sStart = new Point3d();
Point3d sEnd = new Point3d();
// 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;
+
+ if (routePoint.lengthSquared() > BRANCH_SNAP_DISTANCE)
+ return null;
+
+ return endingToStraight(mu, s, sStart, sEnd, currentPipePoint);
+
+// if (mu[0] > 0.0 && mu[0] < 1.0 && routePoint.lengthSquared() < BRANCH_SNAP_DISTANCE) {
+// currentPosition.set(branchPoint);
+//
+// updateCurrentPoint();
+//
+// setInfoText("Create a branch (l) :" + currentPosition + " " + Math.max(0.0, Math.min(mu[0], 1.0)) + " " + routePoint.lengthSquared());
+// return PositionType.SPLIT;
+// }
+// return null;
}
private boolean endingLockToNozzle(INode nozzleNode) {
return null;
}
+ protected void addTurn() throws Exception{
+ InlineComponent previous = (InlineComponent)getLast();
+ PipeControlPoint previousCP = previous.getControlPoint();
+ TurnComponent turn = ComponentUtils.createTurn(root);
+ PipeControlPoint turnCP = turn.getControlPoint();
+ turn.setName(pipeRun.getUniqueName("Elbow"));
+ pipeRun.addChild(turn);
+ added.add(turn);
+ turnCP.setDeletable(false); // mark turnCP nonDeletable so that PipingRules won't delete it immediately.
+ if (!reversed) {
+ previousCP.setNext(turnCP);
+ turnCP.setPrevious(previousCP);
+ } else {
+ previousCP.setPrevious(turnCP);
+ turnCP.setNext(previousCP);
+ }
+
+ turnCP.setWorldPosition(currentPosition);
+ turnCP.setTurnAngle(0.0);
+ turnCP.setLength(0.0);
+
+ }
+
+ protected void addStraight() throws Exception{
+ TurnComponent turn = (TurnComponent)getLast();
+ PipeControlPoint turnCP = turn.getControlPoint();
+
+ InlineComponent straight = ComponentUtils.createStraight(root);
+
+ PipeControlPoint straightCP = straight.getControlPoint();
+ straight.setName(pipeRun.getUniqueName("Pipe"));
+
+
+ pipeRun.addChild(straight);
+
+ added.add(straight);
+
+
+
+ if (!reversed) {
+ turnCP.setNext(straightCP);
+ straightCP.setPrevious(turnCP);
+ } else {
+ turnCP.setPrevious(straightCP);
+ straightCP.setNext(turnCP);
+ }
+
+ turnCP.setWorldPosition(currentPosition);
+ turnCP.setTurnAngle(0.0);
+ turnCP.setLength(0.0);
+ straightCP.setWorldPosition(currentPosition);
+ straightCP.setLength(0.0);
+
+ }
+
protected void addPoint() throws Exception {
- 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);
-
+ addTurn();
+ addStraight();
setPreviousPosition(currentPosition);
updateCurrentPoint();
state = ToolState.NOT_ACTIVE;
if (endTo != null) {
+ if (endType == PositionType.NEXT || endType == PositionType.PREVIOUS && endTo instanceof InlineComponent) {
+ Vector3d dir = endTo.getControlPoint().getPathLegDirection(Direction.NEXT);
+ Vector3d currDir = getLast().getControlPoint().getPathLegDirection(Direction.NEXT);
+ dir.normalize();
+ currDir.normalize();
+ double dot = dir.dot(currDir);
+ System.out.println(dot + " " + currDir + " " + dir);
+ if (dot < ALIGN_DOT_PRODUCT && dot> -ALIGN_DOT_PRODUCT) {
+ addTurn();
+ }
+
+ }
ComponentUtils.connect(getLast(), endTo, endType, currentPosition);
}
panel.useDefaultAction();