import javax.vecmath.Tuple3d;
import javax.vecmath.Vector3d;
+import org.simantics.db.Resource;
import org.simantics.g3d.math.MathTools;
import org.simantics.g3d.math.Ray;
import org.simantics.g3d.scenegraph.NodeMap;
import org.simantics.g3d.scenegraph.base.INode;
import org.simantics.g3d.tools.ConstraintDetector;
-import org.simantics.g3d.tools.DummyConstraintDetector;
import org.simantics.g3d.vtk.gizmo.TranslateAxisGizmo;
import org.simantics.g3d.vtk.swt.InteractiveVtkComposite;
import org.simantics.g3d.vtk.swt.vtkSwtAction;
import org.simantics.g3d.vtk.utils.vtkUtil;
import org.simantics.plant3d.Activator;
+import org.simantics.plant3d.gizmo.ConstraintPointGizmo;
import org.simantics.plant3d.gizmo.SplitPointSelectionGizmo;
import org.simantics.plant3d.gizmo.TerminalSelectionGizmo;
-import org.simantics.plant3d.ontology.Plant3D;
import org.simantics.plant3d.scenegraph.EndComponent;
import org.simantics.plant3d.scenegraph.InlineComponent;
import org.simantics.plant3d.scenegraph.Nozzle;
};
LockType lock = LockType.NONE;
+ boolean lockForced;
private double BRANCH_SNAP_DISTANCE = 0.05;
private double NOZZLE_SNAP_DISTANCE = 0.05;
private int decimals = 2;
private P3DRootNode root;
- private PipelineComponent startComponent;
- private PipeRun pipeRun;
+ protected PipelineComponent startComponent;
+ protected PipeRun pipeRun;
+ private boolean allowBranches;
- private TranslateAxisGizmo translateAxisGizmo = new TranslateAxisGizmo();
+ protected TranslateAxisGizmo translateAxisGizmo = new TranslateAxisGizmo();
private SplitPointSelectionGizmo splitPointSelectionGizmo;
+ private ConstraintPointGizmo constraintPointGizmo;
private TerminalSelectionGizmo terminalSelectionGizmo;
- private NodeMap<vtkProp,INode> nodeMap;
+ private NodeMap<Resource,vtkProp,INode> nodeMap;
- private enum ToolState{NOT_ACTIVE, INITIALIZING, SELECTING_POSITION, SELECTING_SPLIT, ROUTING};
- private ToolState state = ToolState.NOT_ACTIVE;
+ protected enum ToolState{NOT_ACTIVE, INITIALIZING, SELECTING_POSITION, SELECTING_SPLIT, ROUTING};
+ protected ToolState state = ToolState.NOT_ACTIVE;
private ConstraintDetector detector;// = new DummyConstraintDetector();
- private boolean useDefault = false;
- private Vector3d direction = null;
- private Vector3d previousPosition = null;
- private Vector3d currentPosition = null;
+ protected boolean useDefault = false;
+ protected Vector3d direction = null;
+ protected Vector3d previousPosition = null;
+ protected Vector3d currentPosition = null;
boolean step = false;
private Set<PositionType> allowed = new HashSet<PositionType>();
-
public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root) {
+ this(panel,root, true);
+ }
+
+ public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root, boolean allowBranches) {
super(panel);
this.root = root;
+ this.allowBranches = allowBranches;
setText("Route Pipe");
setImageDescriptor(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/Straight.png"));
nodeMap = root.getNodeMap();
splitPointSelectionGizmo = new SplitPointSelectionGizmo(panel);
terminalSelectionGizmo = new TerminalSelectionGizmo(panel);
+ constraintPointGizmo = new ConstraintPointGizmo(panel);
detector = new org.simantics.g3d.vtk.swt.ConstraintDetector(panel);
}
allowed.add(PositionType.NEXT);
if (this.startComponent.getPrevious() == null && !(this.startComponent instanceof Nozzle))
allowed.add(PositionType.PREVIOUS);
- if (this.startComponent instanceof InlineComponent && !this.startComponent.getControlPoint().isFixed())
+ if (allowBranches && this.startComponent instanceof InlineComponent && !this.startComponent.getControlPoint().isFixedLength())
allowed.add(PositionType.SPLIT);
setEnabled(allowed.size() > 0);
}
public void deattach() {
deactivate();
startComponent = null;
- nodeMap.commit("Route pipe");
+
deattachUI();
super.deattach();
panel.refresh();
splitPointSelectionGizmo.deattach();
if (terminalSelectionGizmo.isAttached())
terminalSelectionGizmo.deattach();
+ if (constraintPointGizmo.isAttached())
+ constraintPointGizmo.deattach();
if (infoActor != null) {
panel.getRenderer().RemoveActor(infoActor);
infoActor.Delete();
panel.unlock();
}
- private List<PipelineComponent> added = new ArrayList<PipelineComponent>();
+ protected List<PipelineComponent> added = new ArrayList<PipelineComponent>();
@Override
public boolean keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
panel.useDefaultAction();
- if (lock != LockType.CUSTOM) {
+ if (lock != LockType.CUSTOM || !lockForced) {
if ((e.getModifiersEx() & KeyEvent.SHIFT_DOWN_MASK) > 0) {
if (e.getKeyCode() == KeyEvent.VK_X) {
if (lock != LockType.XY && lock != LockType.XZ) {
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;
+ if (useDefault)
+ setInfoText("Rotating camera");
System.out.println("UseDefault " + useDefault);
}
boolean startRemovable = false;
- private void activate() throws Exception {
+ protected void activate() throws Exception {
state = ToolState.INITIALIZING;
added.clear();
- private void activateNextPrev(PipeControlPoint start) throws Exception{
+ protected void activateNextPrev(PipeControlPoint start) throws Exception{
if (!reversed && start.isDualInline())
start = start.getSubPoint().get(0);
else if (reversed && start.isDualSub())
if (startComponent instanceof Nozzle) {
direction = startComponent.getControlPoint().getDirectedControlPointDirection();
lock = LockType.CUSTOM;
+ lockForced = true;
} else if (startComponent instanceof PipelineComponent){
if (startComponent instanceof InlineComponent) {
direction = startComponent.getControlPoint().getPathLegDirection(reversed ? Direction.PREVIOUS : Direction.NEXT);
lock = LockType.CUSTOM;
+ lockForced = true;
if (((InlineComponent) startComponent).isVariableLength()) {
startWithTurn = true;
direction = null;
lock = LockType.NONE;
+ lockForced = false;
}
Vector3d v = new Vector3d();
if (!reversed) {
start.getControlPointEnds(previousPosition,v);
}
} else if (startComponent instanceof TurnComponent) {
- if (start.isFixed()) {
+ if (start.asFixedAngle()) {
direction = startComponent.getControlPoint().getPathLegDirection(reversed ? Direction.PREVIOUS : Direction.NEXT);
lock = LockType.CUSTOM;
+ lockForced = start.isFixedAngle();
} else {
direction = null;
lock = LockType.NONE;
+ lockForced = false;
}
} else if (startComponent instanceof EndComponent) {
throw new Exception("Not supported");
updateCurrentPoint();
}
- private void setPreviousPosition(Vector3d v) {
+ protected void setPreviousPosition(Vector3d v) {
previousPosition = new Vector3d(v);
if (translateAxisGizmo.isAttached())
translateAxisGizmo.setPosition(previousPosition);
state = ToolState.SELECTING_SPLIT;
}
public void deactivate() {
- for (PipelineComponent component : added) {
- component.getControlPoint().setDeletable(true);
- }
+ if (added.size() > 0) {
+ for (PipelineComponent component : added) {
+ component.getControlPoint().setDeletable(true);
+ }
+
+ for (PipelineComponent comp : added) {
+ PipingRules.requestUpdate(comp.getControlPoint());
+ }
+ try {
+ PipingRules.update();
+ nodeMap.commit("Route pipe");
+ } catch (Exception e) {
+ ExceptionUtils.logAndShowError(e);
+ }
+ added.clear();
+ }
- added.clear();
startComponent.getControlPoint().setDeletable(startRemovable);
direction = null;
startRemovable = false;
detector.clearConstraintHighlights();
state = ToolState.NOT_ACTIVE;
- setEnabled(false);
-
+ setEnabled(false);
}
private void setLockType(LockType type, boolean force) {
- if (force || lock != LockType.CUSTOM) {
+ if (force || (lock != LockType.CUSTOM || !lockForced) ) {
lock = type;
switch (lock) {
addPoint();
}
} else {
- throw new RuntimeException("kjf");
+ throw new RuntimeException("RoutePipeAction initlialization has been failed, no added components found");
// // user was selecting position of branch
// lastPoint.set(startPoint);
// controlPoints.add(new Point3d(startPoint));
private void updateConstraints() {
detector.clearConstraints();
+ constraintPointGizmo.clearPositions();
if (hoverObject == null) {
+ if (constraintPointGizmo.isAttached())
+ constraintPointGizmo.deattach();
return;
}
if (hoverObject instanceof Nozzle) {
c.getEnds(p1, p2);
detector.addContraintPoint(p1);
detector.addContraintPoint(p2);
+ detector.addContraintPoint(new Point3d(c.getWorldPosition()));
} else if (hoverObject instanceof TurnComponent) {
TurnComponent n = (TurnComponent)hoverObject;
detector.addContraintPoint(new Point3d(n.getWorldPosition()));
}
+ if (detector.getConstraintPoints().size() > 0) {
+ for (Point3d p : detector.getConstraintPoints()) {
+ constraintPointGizmo.addPosition(new Vector3d(p));
+ }
+ if (constraintPointGizmo.isAttached())
+ constraintPointGizmo.deattach();
+ constraintPointGizmo.attach(panel);
+ }
}
@Override
INode hoverObject = null;
- private void updateRouting(double x, double y) {
-// if(input.keyPressed(KeyEvent.VK_ESCAPE)) {
-// controlPoints.clear();
-// end();
-// return;
-// }
-// if (input.keyPressed(KeyEvent.VK_C)) {
-// useCamera = !useCamera;
-// cameraAction.setChecked(useCamera);
-// }
+ protected void updateRouting(double x, double y) {
if (useDefault) {
//panel.getDefaultAction().update();
return;
} else if (hoverObject instanceof InlineComponent && ((InlineComponent)hoverObject).isVariableLength()) {
endTo = (InlineComponent)hoverObject;
endType = endingToStraight(endTo,mu,o,d);
+ if (endType == null)
+ endTo = null;
} else if (hoverObject instanceof PipelineComponent && (endPort = endingToComponent(hoverObject,o,d)) != null) {
endTo = (PipelineComponent)hoverObject;
} else {
panel.refresh();
}
- private boolean updateCurrentPoint(Vector3d o, Vector3d d) {
+ protected boolean updateCurrentPoint(Vector3d o, Vector3d d) {
Vector3d point = new Vector3d(this.previousPosition);
return null;
}
- private void updateRoute(Vector3d o, Vector3d d) {
+ protected void updateRoute(Vector3d o, Vector3d d) {
detector.clearConstraintHighlights();
Point3d previousPipePoint = new Point3d(previousPosition);
String s = "";
}
private PositionType endingToStraight(INode straightNode, double mu[], Vector3d o, Vector3d d) {
+ if (!allowBranches) {
+ updateCurrentPoint();
+ return null;
+ }
InlineComponent s = (InlineComponent)straightNode;
String info = "";
Point3d sStart = new Point3d();
//detector.clearConstraintHighlights();
Point3d previousPipePoint = new Point3d(previousPosition);
+ Point3d currentPipePoint = new Point3d(currentPosition);
//String st = "";
if (lock == LockType.NONE) {
Point3d p = detector.getSnappedPoint(o, d, new Vector3d(previousPipePoint));
if (t != null)
return t;
// if not, we'll have to remove highlight that was added when snapped point was detected
- detector.clearConstraintHighlights();
- }
+ detector.clearConstraintHighlights();
+ }
-
Vector3d sDir = new Vector3d(sEnd);
sDir.sub(sStart);
MathTools.intersectStraightStraight(sStart, sDir, o, d, currentPosition, new Point3d(), mu);
// branch point must lie between straight's ends. If connection point is exactly
// on straight end user may want to connect pipes to each other
// TODO : take account sizes of inline components)
- // TODO : actually make connection if its detected
+
boolean connectPrev = false;
boolean connectNext = false;
-
- if (mu[0] < 0.0) {
- currentPosition.set(sStart);
+ boolean branch = false;
+ if (mu[0] < 0.1) {
connectPrev = true;
}
- else if (mu[0] > 1.0) {
- currentPosition.set(sEnd);
+ else if (mu[0] > 0.9) {
connectNext = true;
}
- boolean connect = false;
+
+
if (connectPrev) {
PipeControlPoint pcp = s.getControlPoint();
- if (pcp.getPrevious() == null)
- connect = true;
+ if (pcp.getPrevious() != null)
+ connectPrev = false;
} else if (connectNext) {
PipeControlPoint pcp = s.getControlPoint();
- if (pcp.getNext() == null)
- connect = true;
+ 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;
+ }
}
- updateCurrentPoint();
-
- if (connect)
+
+ if (connectNext || connectPrev)
info += "Connect pipes :";
- else
- info += "Make Branch :";
+ else if (branch)
+ info += "Create a Branch :";
setInfoText(info + currentPosition + " " + Math.max(0.0, Math.min(mu[0], 1.0)));
- if (connect) {
- if (connectNext) {
- return PositionType.NEXT;
- } else {
- return PositionType.PREVIOUS;
- }
-
+ 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;
}
- return PositionType.SPLIT;
}
}
private PositionType endingLockToStraight(INode straightNode, double mu[]) {
+ if (!allowBranches) {
+ updateCurrentPoint();
+ return null;
+ }
InlineComponent s = (InlineComponent)straightNode;
Point3d sStart = new Point3d();
Point3d sEnd = new Point3d();
updateCurrentPoint();
- setInfoText("Make branch (l) :" + currentPosition + " " + Math.max(0.0, Math.min(mu[0], 1.0)) + " " + routePoint.lengthSquared());
+ setInfoText("Create a branch (l) :" + currentPosition + " " + Math.max(0.0, Math.min(mu[0], 1.0)) + " " + routePoint.lengthSquared());
return PositionType.SPLIT;
}
return null;
return null;
}
- private void addPoint() throws Exception {
+ protected void addPoint() throws Exception {
InlineComponent previous = (InlineComponent)getLast();
PipeControlPoint previousCP = previous.getControlPoint();
TurnComponent turn = ComponentUtils.createTurn(root);
/**
* Updates tool graphics for current point
*/
- private void updateCurrentPoint() {
+ protected void updateCurrentPoint() {
InlineComponent straight = (InlineComponent)added.get(added.size()-1);
// TODO: the inline length is from previous update step.
double l;
}
- private void endPiping() throws Exception {
+ protected void endPiping() throws Exception {
state = ToolState.NOT_ACTIVE;
if (endTo != null) {