From 9823254b72141ab6e5706ddd0d7f9f2b3fbaa56b Mon Sep 17 00:00:00 2001 From: Marko Luukkainen Date: Wed, 21 Aug 2019 10:46:28 +0300 Subject: [PATCH] SCL function for connecting pipeline components gitlab #28 Change-Id: I8ab03b0593d62824feb2a2b994a13376c6654d15 --- .../scl/Plant3d/Utils/ComponentUtils.scl | 7 + .../plant3d/actions/RoutePipeAction.java | 126 ++++----------- .../controlpoint/PipeControlPoint.java | 4 +- .../plant3d/utils/ComponentUtils.java | 150 +++++++++++++++++- 4 files changed, 190 insertions(+), 97 deletions(-) diff --git a/org.simantics.plant3d/scl/Plant3d/Utils/ComponentUtils.scl b/org.simantics.plant3d/scl/Plant3d/Utils/ComponentUtils.scl index c3ef6365..24b2e42c 100644 --- a/org.simantics.plant3d/scl/Plant3d/Utils/ComponentUtils.scl +++ b/org.simantics.plant3d/scl/Plant3d/Utils/ComponentUtils.scl @@ -2,6 +2,7 @@ import "Plant3d/Scenegraph/PipelineComponent" import "Plant3d/Scenegraph/Equipment" import "Plant3d/Scenegraph/Nozzle" import "Plant3d/Scenegraph/P3DRootNode" +import "G3D/Math/Vector3d" import "./P3DUtil" importJava "org.simantics.plant3d.utils.ComponentUtils" where @@ -21,6 +22,12 @@ importJava "org.simantics.plant3d.utils.ComponentUtils" where @JavaName addComponent addComponent :: P3DRootNode -> PipelineComponent -> InsertInstruction -> PipelineComponent + @JavaName connect + connect :: PipelineComponent -> PipelineComponent -> Boolean + + @JavaName connect + connect2 :: PipelineComponent -> PipelineComponent -> PositionType -> Vector3d -> Boolean + importJava "org.simantics.plant3d.utils.ComponentUtils$InsertInstruction" where data InsertInstruction diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java b/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java index c922f38f..be82d85e 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java @@ -2,6 +2,7 @@ package org.simantics.plant3d.actions; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashSet; @@ -303,7 +304,7 @@ public class RoutePipeAction extends vtkSwtAction { if (startComponent instanceof InlineComponent) { direction = startComponent.getControlPoint().getPathLegDirection(reversed ? Direction.PREVIOUS : Direction.NEXT); lock = LockType.CUSTOM; - if (startComponent.getType().equals(Plant3D.URIs.Builtin_Straight)) { + if (((InlineComponent) startComponent).isVariableLength()) { startWithTurn = true; direction = null; lock = LockType.NONE; @@ -491,6 +492,14 @@ public class RoutePipeAction extends vtkSwtAction { return true; } + @Override + public boolean mouseWheelMoved(MouseWheelEvent e) { + if (useDefault) { + getDefaultAction().mouseWheelMoved(e); + } + return true; + } + @Override public boolean mouseClicked(MouseEvent e) { if (useDefault) { @@ -563,7 +572,7 @@ public class RoutePipeAction extends vtkSwtAction { } try { Vector3d pos = new Vector3d(t); - InlineComponent branchSplit = createBranchSplit((InlineComponent)startComponent, pos); + InlineComponent branchSplit = ComponentUtils.createBranchSplit((InlineComponent)startComponent, pos); PipeControlPoint branchSplitCP = branchSplit.getControlPoint(); reversed = false; PipeRun newRun = new PipeRun(); @@ -586,24 +595,13 @@ public class RoutePipeAction extends vtkSwtAction { return true; } - private InlineComponent createBranchSplit(InlineComponent component, Vector3d pos) throws Exception{ - InlineComponent branchSplit = ComponentUtils.createBranchSplit(root); - String branchName = component.getPipeRun().getUniqueName("Branch"); - branchSplit.setName(branchName); - component.getPipeRun().addChild(branchSplit); - PipeControlPoint branchSplitCP = branchSplit.getControlPoint(); - branchSplitCP.setWorldPosition(pos); - PipingRules.splitVariableLengthComponent(branchSplit, component, false); - return branchSplit; - } - @Override public boolean mouseMoved(MouseEvent e) { if (useDefault) { getDefaultAction().mouseMoved(e); return true; } - step = ((e.getModifiers() & MouseEvent.CTRL_DOWN_MASK) > 0); + step = ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0); update(e.getX(), e.getY()); return true; } @@ -699,7 +697,7 @@ public class RoutePipeAction extends vtkSwtAction { } } else { if (hoverObject instanceof InlineComponent && ((InlineComponent)hoverObject).isVariableLength() && (endType = endingLockToStraight(hoverObject,mu)) != null) { - endTo = (InlineComponent)hoverObject;; + endTo = (InlineComponent)hoverObject; } else if (hoverObject instanceof Nozzle && endingLockToNozzle(hoverObject)) { endTo = (Nozzle)hoverObject; } else if ((hoverObject instanceof PipelineComponent) && ((endPort = endingLockToComponent(hoverObject)) != null)) { @@ -809,6 +807,23 @@ public class RoutePipeAction extends vtkSwtAction { s += detector.getSnapString(); } + //System.out.println(previousPosition + " -> " + currentPosition); +// double dist = MathTools.distance(previousPosition, currentPosition); +// if (dist < pipeRun.getTurnRadius()) { +// s += "Too close"; +// Vector3d v = new Vector3d(currentPosition); +// v.sub(previousPosition); +// double vl = v.length(); +// if (vl > MathTools.NEAR_ZERO) { +// v.scale(1.0/vl); +// } else { +// +// return; +// } +// v.scale(pipeRun.getTurnRadius()); +// v.add(previousPosition); +// currentPosition.set(v); +// } updateCurrentPoint(); s += currentPosition.toString(); @@ -963,8 +978,8 @@ public class RoutePipeAction extends vtkSwtAction { private PositionType endingLockToStraight(INode straightNode, double mu[]) { InlineComponent s = (InlineComponent)straightNode; - Point3d sStart = new Point3d();//G3DTools.getPoint(s.getHasControlPoint().getPreviousPoint().getLocalPosition()); - Point3d sEnd = new Point3d(); //G3DTools.getPoint(s.getHasControlPoint().getNextPoint().getLocalPosition()); + Point3d sStart = new Point3d(); + Point3d sEnd = new Point3d(); s.getControlPoint().getInlineControlPointEnds(sStart, sEnd); Vector3d sDir = new Vector3d(sEnd); sDir.sub(sStart); @@ -979,7 +994,7 @@ public class RoutePipeAction extends vtkSwtAction { routePoint.sub(branchPoint); // startPoint of branch must be between pipe ends // TODO : take account sizes of elbows (or other components) - // branch point must be between pipe ends and intersection points must be quite close to each othert + // 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); @@ -1113,80 +1128,7 @@ public class RoutePipeAction extends vtkSwtAction { state = ToolState.NOT_ACTIVE; if (endTo != null) { - PipeControlPoint endCP = endTo.getControlPoint(); - if (endType == null || endType == PositionType.NEXT || endType == PositionType.PREVIOUS) { - - PipelineComponent current = getLast(); - PipeControlPoint currentCP = current.getControlPoint(); - - boolean requiresReverse = false; - if (!reversed && endCP.getPrevious() != null) { - requiresReverse = true; - } else if (reversed && endCP.getNext() != null) { - requiresReverse = true; - } - PipeRun other = endCP.getPipeRun(); - boolean mergeRuns = pipeRun.equalSpecs(other); - - if (requiresReverse) { - // Pipe line must be traversible with next/previous relations without direction change. - // Now the component, where we are connecting the created pipeline is defined in different order. - PipingRules.reverse(other); - - } - if (mergeRuns) { - // Runs have compatible specs and must be merged - if (pipeRun != other) // FIXME: temporary workaround. - PipingRules.merge(pipeRun, other); - if (!reversed) { - currentCP.setNext(endCP); - endCP.setPrevious(currentCP); - } else { - currentCP.setPrevious(endCP); - endCP.setNext(currentCP); - } - } else { - // Runs do not have compatible specs, and a reducer must be attached in between. - InlineComponent reducer = ComponentUtils.createReducer(root); - PipeControlPoint pcp = reducer.getControlPoint(); - PipeControlPoint ocp = pcp.getSubPoint().get(0); - - Vector3d endPos = endCP.getWorldPosition(); - Vector3d currentPos = currentCP.getWorldPosition(); - Vector3d v = new Vector3d(endPos); - v.sub(currentPos); - v.scale(0.5); - v.add(currentPos); - - PipingRules.addSizeChange(reversed, pipeRun, other, reducer, currentCP, endCP); - - pcp.setWorldPosition(v); - reducer.updateParameters(); - } - - } else if (endType == PositionType.SPLIT) { - InlineComponent branchSplit = createBranchSplit((InlineComponent)endTo, currentPosition); - PipeControlPoint branchSplitCP = branchSplit.getControlPoint(); - PipeControlPoint pcp = new PipeControlPoint(branchSplit,pipeRun); - branchSplitCP.children.add(pcp); - pcp.parent = branchSplitCP; - pcp.setWorldOrientation(branchSplitCP.getWorldOrientation()); - pcp.setWorldPosition(branchSplitCP.getWorldPosition()); - - PipelineComponent current = getLast(); - PipeControlPoint currentCP = current.getControlPoint(); - - - if(!reversed) { - pcp.setPrevious(currentCP); - currentCP.setNext(pcp); - } else { - pcp.setNext(currentCP); - currentCP.setPrevious(pcp); - } - - } - PipingRules.positionUpdate(endCP); + ComponentUtils.connect(getLast(), endTo, endType, currentPosition); } panel.useDefaultAction(); } diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java index 8e3e6bbd..66055865 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java @@ -1189,9 +1189,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } if (br0 != null) { if (br0.getNext() == component) - prev.setNext(null); + br0.setNext(null); else if (br0.getPrevious() == component) - prev.setPrevious(null); + br0.setPrevious(null); else if (br0.getBranch0() == component) br0.setBranch0(null); } diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java b/org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java index 4a488809..cc19260b 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.vecmath.Point3d; import javax.vecmath.Vector3d; import org.simantics.Simantics; @@ -13,6 +14,7 @@ import org.simantics.db.Resource; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; +import org.simantics.g3d.math.MathTools; import org.simantics.g3d.scenegraph.GeometryProvider; import org.simantics.layer0.Layer0; import org.simantics.plant3d.ontology.Plant3D; @@ -25,11 +27,9 @@ import org.simantics.plant3d.scenegraph.PipeRun; import org.simantics.plant3d.scenegraph.PipelineComponent; import org.simantics.plant3d.scenegraph.TurnComponent; import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint; -import org.simantics.plant3d.scenegraph.controlpoint.PipingRules; import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Direction; import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType; -import org.simantics.plant3d.utils.Item.Type; -import org.simantics.utils.ui.ExceptionUtils; +import org.simantics.plant3d.scenegraph.controlpoint.PipingRules; public class ComponentUtils { @@ -474,4 +474,148 @@ public class ComponentUtils { return newComponent; } + public static boolean connect(PipelineComponent current, PipelineComponent endTo) throws Exception { + return connect(current, endTo, null, null); + } + + /** + * Connects component to another component + * @param current + * @param endTo + * @param endType + * @param position + * @return + * @throws Exception + */ + public static boolean connect(PipelineComponent current, PipelineComponent endTo, PositionType endType, Vector3d position) throws Exception{ + PipeControlPoint endCP = endTo.getControlPoint(); + boolean reversed; + if (current.getNext() == null) + reversed = false; + else if (current.getPrevious() == null) + reversed = true; + else + return false; + + PipeRun pipeRun = current.getPipeRun(); + P3DRootNode root = (P3DRootNode)current.getRootNode(); + PipeControlPoint currentCP = current.getControlPoint(); + + if (endType == null || endType == PositionType.NEXT || endType == PositionType.PREVIOUS) { + + + + boolean requiresReverse = false; + if (!reversed && endCP.getPrevious() != null) { + if (endCP.getNext() != null) + return false; + requiresReverse = true; + } else if (reversed && endCP.getNext() != null) { + if (endCP.getPrevious() != null) + return false; + requiresReverse = true; + } + PipeRun other = endCP.getPipeRun(); + boolean mergeRuns = pipeRun.equalSpecs(other); + + if (requiresReverse) { + // Pipe line must be traversible with next/previous relations without direction change. + // Now the component, where we are connecting the created pipeline is defined in different order. + PipingRules.reverse(other); + + } + if (mergeRuns) { + // Runs have compatible specs and must be merged + if (pipeRun != other) // FIXME: temporary workaround. + PipingRules.merge(pipeRun, other); + if (!reversed) { + currentCP.setNext(endCP); + endCP.setPrevious(currentCP); + } else { + currentCP.setPrevious(endCP); + endCP.setNext(currentCP); + } + } else { + // Runs do not have compatible specs, and a reducer must be attached in between. + InlineComponent reducer = ComponentUtils.createReducer(root); + PipeControlPoint pcp = reducer.getControlPoint(); + PipeControlPoint ocp = pcp.getSubPoint().get(0); + + Vector3d endPos = endCP.getWorldPosition(); + Vector3d currentPos = currentCP.getWorldPosition(); + Vector3d v = new Vector3d(endPos); + v.sub(currentPos); + v.scale(0.5); + v.add(currentPos); + + PipingRules.addSizeChange(reversed, pipeRun, other, reducer, currentCP, endCP); + + pcp.setWorldPosition(v); + reducer.updateParameters(); + } + PipingRules.positionUpdate(endCP); + return true; + + } else if (endType == PositionType.SPLIT) { + InlineComponent branchSplit = createBranchSplit((InlineComponent)endTo, position); + if (branchSplit == null) + return false; + PipeControlPoint branchSplitCP = branchSplit.getControlPoint(); + PipeControlPoint pcp = new PipeControlPoint(branchSplit,pipeRun); + branchSplitCP.children.add(pcp); + pcp.parent = branchSplitCP; + pcp.setWorldOrientation(branchSplitCP.getWorldOrientation()); + pcp.setWorldPosition(branchSplitCP.getWorldPosition()); + + + if(!reversed) { + pcp.setPrevious(currentCP); + currentCP.setNext(pcp); + } else { + pcp.setNext(currentCP); + currentCP.setPrevious(pcp); + } + PipingRules.positionUpdate(endCP); + return true; + } + return false; + } + + public static InlineComponent createBranchSplit(InlineComponent component, Vector3d pos) throws Exception{ + if (!component.isVariableLength()) + return null; + PipeRun pipeRun = component.getPipeRun(); + Vector3d sStart = new Vector3d(); + Vector3d sEnd = new Vector3d(); + component.getControlPoint().getInlineControlPointEnds(sStart, sEnd); + + if (MathTools.distance(sStart, sEnd) < (pipeRun.getPipeDiameter()*0.5)) + return null; + + + Vector3d p = MathTools.closestPointOnEdge(new Vector3d(pos), sStart, sEnd); + if (p == sStart) { + Vector3d v = new Vector3d(sEnd); + v.sub(sStart); + v.normalize(); + v.scale(component.getPipeRun().getPipeDiameter()*0.5); + p.add(v); + } else if (p == sEnd) { + Vector3d v = new Vector3d(sStart); + v.sub(sEnd); + v.normalize(); + v.scale(component.getPipeRun().getPipeDiameter()*0.5); + p.add(v); + } + + P3DRootNode root = (P3DRootNode)component.getRootNode(); + InlineComponent branchSplit = ComponentUtils.createBranchSplit(root); + String branchName = component.getPipeRun().getUniqueName("Branch"); + branchSplit.setName(branchName); + component.getPipeRun().addChild(branchSplit); + PipeControlPoint branchSplitCP = branchSplit.getControlPoint(); + branchSplitCP.setWorldPosition(p); + PipingRules.splitVariableLengthComponent(branchSplit, component, false); + return branchSplit; + } } -- 2.45.2