-/*******************************************************************************\r
- * Copyright (c) 2007- VTT Technical Research Centre of Finland.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.processeditor.common;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-\r
-import javax.vecmath.AxisAngle4d;\r
-import javax.vecmath.Point3d;\r
-import javax.vecmath.Vector3d;\r
-\r
-import org.simantics.db.Graph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.processeditor.ProcessResource;\r
-import org.simantics.processeditor.stubs.PipeControlPoint;\r
-import org.simantics.processeditor.stubs.PipeRun;\r
-import org.simantics.processeditor.stubs.PipelineComponent;\r
-import org.simantics.proconf.g3d.base.G3DTools;\r
-import org.simantics.proconf.g3d.base.MathTools;\r
-import org.simantics.utils.ui.ErrorLogger;\r
-\r
-\r
-/**\r
- * Rules that update pipeline.\r
- * TODO : optimize, remove stubs\r
- * \r
- * FIXME : transformations\r
- * \r
- * TODO : FixedAngleTurnComponents are handled like VariableAngleTurnComponents\r
- * \r
- * \r
- * @author Marko Luukkainen <Marko.Luukkainen@vtt.fi>\r
- *\r
- */\r
-public class PipingRules {\r
- \r
- private static final boolean DEBUG = false;\r
- private static final boolean DUMMY = false;\r
- \r
- private static final double MIN_TURN_ANGLE = 0.01;\r
- \r
- private static final int REMOVE_NONE = 0;\r
- private static final int REMOVE_START = 1;\r
- private static final int REMOVE_END = 2;\r
- private static final int REMOVE_BOTH = 3;\r
- \r
- private enum PathLegUpdateType {NONE,PREV,NEXT,PREV_S,NEXT_S};\r
- \r
- /**\r
- * Rule\r
- * \r
- * @param resources\r
- * @param pp\r
- * @throws TransactionException\r
- */\r
- public static void pipeControlPointPositionUpdate(Graph g, Resource pp) {\r
- \r
- PipeControlPoint pcp = new PipeControlPoint(g,pp);\r
- if (DEBUG) System.out.println("PipeControlPoint changed " + pp);\r
- \r
- boolean changed = ControlPointTools.isControlPointChanged(pcp);\r
-\r
- \r
- if (changed) {\r
- if (pcp.isInstanceOf(ProcessResource.plant3Dresource.PathLegEndControlPoint)) {\r
- updatePathLegEndControlPoint(pcp);\r
- } else {\r
- updateInlineControlPoint(pcp);\r
- }\r
- } \r
- \r
- }\r
- \r
- \r
- \r
- public static class ExpandIterInfo {\r
- // these two are turn control points\r
- private PipeControlPoint start; \r
- private PipeControlPoint end;\r
- private int type;\r
- \r
- public ExpandIterInfo() {\r
- \r
- }\r
- \r
- public ExpandIterInfo(PipeControlPoint tcp, int type) {\r
- if (type == REMOVE_START)\r
- start = tcp;\r
- else \r
- end = tcp;\r
- this.type = type;\r
- }\r
- \r
- public ExpandIterInfo(PipeControlPoint start, PipeControlPoint end) {\r
- this.start = start;\r
- this.end = end;\r
- this.type = REMOVE_BOTH;\r
- }\r
- \r
- public PipeControlPoint getEnd() {\r
- return end;\r
- }\r
- public void setEnd(PipeControlPoint end) {\r
- this.end = end;\r
- }\r
- public PipeControlPoint getStart() {\r
- return start;\r
- }\r
- public void setStart(PipeControlPoint start) {\r
- this.start = start;\r
- }\r
- public int getType() {\r
- return type;\r
- }\r
- public void setType(int type) {\r
- this.type = type;\r
- }\r
- \r
- \r
- }\r
- \r
- private static void updatePathLegEndControlPoint(PipeControlPoint pcp) {\r
- if (DEBUG) System.out.println("PipingTools.updateRunEndControlPoint() " + pcp.getResource());\r
- if (pcp.getNext() != null) {\r
- updatePathLegNext(pcp,pcp,PathLegUpdateType.NEXT_S);\r
- }\r
- if (pcp.getPrevious() != null) {\r
- updatePathLegPrev(pcp,pcp,PathLegUpdateType.PREV_S);\r
- }\r
- \r
- }\r
- \r
- private static void updateInlineControlPoint(PipeControlPoint pcp) {\r
- if (DEBUG) System.out.println("PipingTools.updateInlineControlPoint() " + pcp.getResource());\r
- PipeControlPoint start = ControlPointTools.findPreviousEnd(pcp);\r
- updatePathLegNext(start,pcp,PathLegUpdateType.NONE);\r
- }\r
- \r
- private static PipeControlPoint insertElbow(PipeControlPoint pcp1 , PipeControlPoint pcp2, Point3d pos) {\r
- if (DEBUG) System.out.println("PipingRules.insertElbow() " + pcp1.getResource() + " " + pcp2.getResource()+ " " + pos);\r
- PipelineComponent elbow = PipingTools2.instantiatePipelineComponent(pcp1.getGraph(), ControlPointTools.getPipeRun(pcp1).getResource(), ProcessResource.plant3Dresource.Elbow);\r
- PipeControlPoint pcp = elbow.getControlPoint();\r
- \r
- ControlPointTools.insertControlPoint(pcp, pcp1,pcp2);\r
- \r
- ControlPointTools.setWorldPosition(pcp, pos);\r
-\r
- return pcp;\r
- }\r
- \r
- private static void updatePathLegNext(PipeControlPoint start, PipeControlPoint updated, PathLegUpdateType lengthChange){\r
- ArrayList<PipeControlPoint> list = new ArrayList<PipeControlPoint>();\r
- PipeControlPoint end = ControlPointTools.findNextEnd(start,list);\r
- // this is for inline cp that is also path leg end\r
- if (start.equals(updated))\r
- lengthChange = PathLegUpdateType.NEXT;\r
- else if (end.equals(updated))\r
- lengthChange = PathLegUpdateType.PREV; \r
- updatePathLegNext(start, list, end, updated, lengthChange);\r
- }\r
- \r
- private static void updatePathLegNext(PipeControlPoint start, ArrayList<PipeControlPoint> list, PipeControlPoint end, PipeControlPoint updated, PathLegUpdateType lengthChange) {\r
- updatePathLeg(start,list,end,false,0,new ArrayList<ExpandIterInfo>(),updated, lengthChange);\r
- }\r
- \r
- private static class UpdateStruct2 {\r
- public PipeControlPoint start;\r
- public Point3d startPoint;\r
- public ArrayList<PipeControlPoint> list;\r
- public PipeControlPoint end;\r
- public Point3d endPoint;\r
- public Vector3d dir;\r
- public Vector3d offset;\r
- public boolean hasOffsets;\r
- public int iter;\r
- public boolean reversed;\r
- public ArrayList<ExpandIterInfo> toRemove;\r
- public PipeControlPoint updated;\r
- public UpdateStruct2(PipeControlPoint start, Point3d startPoint, ArrayList<PipeControlPoint> list, PipeControlPoint end, Point3d endPoint, Vector3d dir, Vector3d offset, boolean hasOffsets, int iter, boolean reversed, ArrayList<ExpandIterInfo> toRemove, PipeControlPoint updated) {\r
- super();\r
- this.start = start;\r
- this.startPoint = startPoint;\r
- this.list = list;\r
- this.end = end;\r
- this.endPoint = endPoint;\r
- this.dir = dir;\r
- this.offset = offset;\r
- this.hasOffsets = hasOffsets;\r
- this.iter = iter;\r
- this.reversed = reversed;\r
- this.toRemove = toRemove;\r
- this.updated = updated;\r
- }\r
- \r
- public String toString() {\r
- return start.getResource() + " " + end.getResource() + " " + dir + " " + hasOffsets + " " + offset + " " + iter + " " + toRemove.size();\r
- }\r
- \r
- }\r
- \r
- private static boolean calculateOffset(Point3d startPoint, Point3d endPoint, ArrayList<PipeControlPoint> list, Vector3d dir, Vector3d offset) {\r
- boolean hasOffsets = false;\r
- dir.set(startPoint);\r
- dir.sub(endPoint);\r
- dir.normalize();\r
- offset.set(0.0,0.0,0.0);\r
- for (PipeControlPoint icp : list) {\r
- if (icp.isInstanceOf(ProcessResource.plant3Dresource.OffsettingPoint)) {\r
- hasOffsets = true;\r
- offset.add(ControlPointTools.getSizeChangeOffsetVector(icp,dir));\r
- }\r
- else if (icp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) \r
- ErrorLogger.defaultLogError("Updating pipe run, found offset controlpoint " + icp.getResource(), new Exception("ASSERT!"));\r
- }\r
- return hasOffsets;\r
- }\r
- \r
- /**\r
- * @param start starting point of the pipe run\r
- * @param list list of inline control points in the pipe run\r
- * @param end ending point of the pipe run\r
- * @param reversed boolean flag indicating wether start or end control point was modified (if true then end point was modified)\r
- * @throws TransactionException\r
- */\r
- private static void updatePathLeg(PipeControlPoint start, ArrayList<PipeControlPoint> list, PipeControlPoint end, boolean reversed, int iter, ArrayList<ExpandIterInfo> toRemove, PipeControlPoint updated, PathLegUpdateType lengthChange) {\r
- // FIXME: direction is calculated wrong way!\r
- boolean hasOffsets = false;\r
- Vector3d offset = new Vector3d();\r
- Point3d startPoint = G3DTools.getPoint(start.getWorldPosition());\r
- Point3d endPoint = G3DTools.getPoint(end.getWorldPosition());\r
- Vector3d dir = new Vector3d ();\r
- hasOffsets = calculateOffset(startPoint, endPoint, list, dir, offset);\r
- updatePathLeg(new UpdateStruct2(start, startPoint, list, end, endPoint, dir, offset, hasOffsets, iter, reversed, toRemove, updated), lengthChange);\r
- \r
- }\r
- \r
- private static void updatePathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange){\r
- int directed = 0;\r
- if (u.start.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint))\r
- directed ++;\r
- if (u.end.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint))\r
- directed++;\r
- switch (directed) {\r
- case 0:\r
- updateFreePathLeg(u,lengthChange);\r
- break;\r
- case 1:\r
- updateDirectedPathLeg(u,lengthChange);\r
- break;\r
- case 2:\r
- updateDualDirectedPathLeg(u,lengthChange);\r
- break;\r
- }\r
- \r
- }\r
- \r
- private static void updateFreePathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange) {\r
- if (DEBUG) System.out.println("PipingRules.updateFreePipeRun " + u + " " + lengthChange);\r
- checkExpandPathLeg(u, lengthChange);\r
- }\r
- \r
- private static void updateInlineControlPoints(UpdateStruct2 u, boolean checkSizes) {\r
- if (DEBUG) System.out.println("PipingTools.updateInlineControlPoints() " + u);\r
- \r
- if (!u.hasOffsets) {\r
- // FIXME : cache positions\r
- if (!checkSizes) {\r
- for (PipeControlPoint icp : u.list) {\r
- updateInlineControlPoint(icp, u.startPoint, u.endPoint,u.dir);\r
- }\r
- return;\r
- }\r
- \r
- ArrayList<PipeControlPoint> pathLegPoints = new ArrayList<PipeControlPoint>();\r
- pathLegPoints.add(u.start);\r
- for (PipeControlPoint icp : u.list) {\r
- //updateInlineControlPoint(icp, u.startPoint, u.endPoint,u.dir);\r
- updateBranchControlPointBranches(icp);\r
- pathLegPoints.add(icp);\r
- }\r
- pathLegPoints.add(u.end);\r
- \r
- // TODO : values can be cached in the loop\r
- for (int i = 1; i < pathLegPoints.size(); i++) {\r
- PipeControlPoint icp = pathLegPoints.get(i);\r
-\r
- PipeControlPoint prev;\r
- Point3d prevPos;\r
- prev = pathLegPoints.get(i-1);\r
- prevPos = G3DTools.getPoint(prev.getWorldPosition());\r
- Point3d currentPos = G3DTools.getPoint(icp.getWorldPosition());\r
- \r
- if (icp.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthControlPoint)) { \r
- if (i != pathLegPoints.size() - 1) {\r
- PipeControlPoint next;\r
- Point3d nextPos;\r
- next = pathLegPoints.get(i + 1);\r
- nextPos = G3DTools.getPoint(next.getWorldPosition());\r
- Vector3d dir = new Vector3d(nextPos);\r
- dir.sub(prevPos);\r
- double l = dir.lengthSquared(); // distance between control points (square)\r
- double l2prev = ControlPointTools.getInlineLength(prev); // distance taken by components\r
- double l2next = ControlPointTools.getInlineLength(next); \r
- double l2 = l2prev + l2next;\r
- double l2s = MathTools.square(l2);\r
- if (l2s < l) { // check if there is enough space for variable length component.\r
- // components fit\r
- dir.normalize();\r
- double length = Math.sqrt(l) - l2; // true length of the variable length component \r
- dir.scale(length*0.5 + l2prev); // calculate center position of the component\r
- dir.add(prevPos);\r
- ControlPointTools.setWorldPosition(icp,dir);\r
- icp.setRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength, length);\r
- } else {\r
- //components leave no space to the component and it must be removed\r
- ControlPointTools.removeControlPoint(icp);\r
- }\r
-\r
- } else {\r
- // this is variable length component at the end of the piperun.\r
- // the problem is that we want to keep unconnected end of the component in the same\r
- // place, but center of the component must be moved.\r
- double currentLength = icp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);\r
- Vector3d dir = new Vector3d();\r
- dir.sub(currentPos,prevPos);\r
- dir.normalize();\r
- Point3d endPos = new Point3d(dir);\r
- endPos.scale(currentLength * 0.5);\r
- endPos.add(currentPos); //this is the free end of the component\r
- \r
- double offset = ControlPointTools.getInlineLength(prev);\r
- Point3d beginPos = new Point3d(dir);\r
- beginPos.scale(offset);\r
- beginPos.add(prevPos); //this is the connected end of the component\r
- \r
- double l = beginPos.distance(endPos);\r
- \r
- dir.scale(l*0.5);\r
- beginPos.add(dir); //center position\r
- \r
- if (DEBUG) System.out.println("PipingRules.updateInlineControlPoints() setting variable length to " + l);\r
- icp.setRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength, l);\r
- \r
- ControlPointTools.setWorldPosition(icp, beginPos);\r
- }\r
- i++;\r
- \r
- } else if (!prev.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthControlPoint)){\r
- // If this and previous control point are not variable length pcps, we'll have to check if there is no empty space between them.\r
- // I there is, we'll have to create new variable length component between them.\r
- Vector3d dir = new Vector3d(currentPos);\r
- dir.sub(prevPos);\r
- double l = dir.lengthSquared();\r
- double l2prev = ControlPointTools.getInlineLength(prev);\r
- double l2next = ControlPointTools.getInlineLength(icp);\r
- double l2 = l2prev + l2next;\r
- double l2s = l2 * l2;\r
- if (l > l2s) {\r
- PipelineComponent component = PipingTools2.instantiatePipelineComponent(prev.getGraph(), ControlPointTools.getPipeRun(prev).getResource(), ProcessResource.plant3Dresource.Straight);\r
- PipeControlPoint scp = component.getControlPoint();\r
- ControlPointTools.insertControlPoint(scp, prev, icp);\r
- \r
- dir.normalize();\r
- double length = Math.sqrt(l) - l2; // true length of the variable length component \r
- dir.scale(length*0.5 + l2prev); // calculate center position of the component\r
- dir.add(prevPos);\r
- ControlPointTools.setWorldPosition(scp, dir);\r
- scp.setRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength, length);\r
- }\r
- }\r
- }\r
- } else {\r
- u.endPoint.sub(u.offset);\r
- // FIXME : straights\r
- for (PipeControlPoint icp : u.list) {\r
- updateInlineControlPoint(icp, u.startPoint, u.endPoint,u.dir);\r
- updateBranchControlPointBranches(icp);\r
- if (icp.isInstanceOf(ProcessResource.plant3Dresource.OffsettingPoint)) {\r
- // TODO : offset vector is already calculated and should be\r
- // cached\r
- u.offset = ControlPointTools.getSizeChangeOffsetVector(icp, u.dir);\r
- updateOffsetPoint( icp, u.offset);\r
- u.startPoint.add(u.offset);\r
- u.endPoint.add(u.offset);\r
- }\r
- }\r
- }\r
- }\r
- \r
- \r
- \r
- private static void ppNoOffset(UpdateStruct2 u) {\r
- if (DEBUG)System.out.println("PipingRules.ppNoOffset() " + u);\r
- Vector3d offset = new Vector3d();\r
- if (u.hasOffsets) {\r
- u.dir.normalize();\r
- for (PipeControlPoint icp : u.list) {\r
- if (icp.isInstanceOf(ProcessResource.plant3Dresource.OffsettingPoint)) {\r
- offset.add(ControlPointTools.getSizeChangeOffsetVector(icp,u.dir));\r
- }\r
- else if (icp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) \r
- ErrorLogger.defaultLogError("Updating pipe run, found offset controlpoint " + icp.getResource(), new Exception("ASSERT!"));\r
- }\r
- }\r
- u.offset = offset;\r
- checkExpandPathLeg(u,PathLegUpdateType.NONE);\r
- }\r
- \r
- private static void ppNoDir(PipeControlPoint start, Point3d startPoint,ArrayList<PipeControlPoint> list, PipeControlPoint end,Point3d endPoint, boolean hasOffsets,int iter,boolean reversed, ArrayList<ExpandIterInfo> toRemove, PipeControlPoint updated) {\r
- if (DEBUG)System.out.println("PipingRules.ppNoDir() " + start.getResource() + " " + end.getResource() + " " + iter + " " + toRemove.size());\r
- // FIXME : extra loop (dir should be calculated here)\r
- Vector3d dir = new Vector3d();\r
- Vector3d offset = new Vector3d();\r
- hasOffsets = calculateOffset(startPoint, endPoint, list, dir, offset);\r
- ppNoOffset(new UpdateStruct2(start, startPoint, list, end, endPoint, dir, null, hasOffsets, iter, reversed, toRemove,updated));\r
- }\r
- \r
- private static void checkExpandPathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange) {\r
- if (DEBUG)System.out.println("PipingRules.checkExpandPathLeg() " + u + " " + lengthChange);\r
- if (lengthChange != PathLegUpdateType.NONE) {\r
- // FIXME : turns cannot be checked before inline cps are updated, since their position affects calculation of turns \r
- processPathLeg(u,false,false);\r
- int type = checkTurns(u,lengthChange);\r
- if (type == REMOVE_NONE) {\r
- processPathLeg(u,false,true);\r
- } else {\r
- expandPathLeg(u, type);\r
- }\r
- } else {\r
- processPathLeg(u,false,true);\r
- }\r
- }\r
- \r
- private static void updateDirectedPathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange) {\r
- if (DEBUG)System.out.println("PipingRules.updateDirectedPipeRun() " + u + " " + lengthChange);\r
- PipeControlPoint dcp;\r
- PipeControlPoint other;\r
- boolean canMoveOther = false;\r
- boolean dcpStart = false;\r
- Point3d position;\r
- if (u.start.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint)) {\r
- dcp = u.start;\r
- other = u.end;\r
- position = u.startPoint;\r
- dcpStart = true;\r
- if (!u.reversed)\r
- canMoveOther = true;\r
- } else {\r
- dcp = u.end;\r
- other = u.start;\r
- position = u.endPoint;\r
- if (u.reversed)\r
- canMoveOther = true;\r
- }\r
-\r
- Vector3d directedDirection = ControlPointTools.getDirectedControlPointDirection(dcp);\r
- Point3d directedEndPoint = new Point3d(u.endPoint);\r
- if (u.hasOffsets)\r
- directedEndPoint.add(u.offset);\r
-\r
- double mu[] = new double[2];\r
-\r
- Vector3d closest;\r
- Vector3d t = new Vector3d();\r
- \r
- if (dcpStart) {\r
- closest = MathTools.closestPointOnStraight(directedEndPoint, u.startPoint, directedDirection, mu);\r
- t.sub(closest, directedEndPoint);\r
- } else {\r
- closest = MathTools.closestPointOnStraight(u.startPoint, directedEndPoint, directedDirection, mu);\r
- t.sub(closest, u.startPoint);\r
- }\r
-\r
- \r
- double distance = t.lengthSquared();\r
- boolean aligned = (distance < 0.001);\r
- if (aligned) {\r
- checkExpandPathLeg(u,lengthChange);\r
- } else {\r
- if (u.iter > 0) {\r
- backIter(u);\r
- } else {\r
- PipeControlPoint nextToMoved;\r
- \r
- if (u.list.size() > 0)\r
- if (dcpStart)\r
- nextToMoved = u.list.get(0);\r
- else\r
- nextToMoved = u.list.get(u.list.size() - 1);\r
- else if (dcpStart)\r
- nextToMoved = u.end;\r
- else\r
- nextToMoved = u.start;\r
- if (other.isInstanceOf(ProcessResource.plant3Dresource.VariableAngleTurnControlPoint)) {\r
- \r
- // TODO calculate needed space from next run end.\r
- if (mu[0] < 1.0) {\r
- if (dcpStart) {\r
- closest.set(u.startPoint); \r
- } else {\r
- closest.set(u.endPoint);\r
- }\r
- closest.add(directedDirection);\r
- }\r
-\r
- if (canMoveOther) {\r
- if (DEBUG)System.out.println("PipingRules.updateDirectedPipeRun() moved end " + other.getResource() + " to " + closest);\r
- ControlPointTools.setWorldPosition(other, closest);\r
- if (dcpStart) {\r
- ppNoOffset(new UpdateStruct2(u.start, u.startPoint, u.list, u.end, new Point3d(closest), directedDirection,null, u.hasOffsets, u.iter, u.reversed, u.toRemove,u.updated));\r
- if (u.end.getNext() != null)\r
- updatePathLegNext(u.end,u.updated,PathLegUpdateType.NEXT);\r
- } else {\r
- ppNoOffset(new UpdateStruct2(u.start, new Point3d(closest), u.list, u.end, u.endPoint, directedDirection,null, u.hasOffsets, u.iter, u.reversed, u.toRemove,u.updated)); \r
- if (u.start.getPrevious() != null)\r
- updatePathLegPrev(u.start,u.updated,PathLegUpdateType.PREV);\r
- }\r
- } else {\r
- // TODO : calculate needed space from next run end.\r
- insertElbowUpdate(u, dcp, nextToMoved, dcpStart, position, directedDirection);\r
- }\r
- } else if (other.isInstanceOf(ProcessResource.plant3Dresource.UndirectedControlPoint) &&\r
- other.getSubPointOf() != null) {\r
- // FIXME : this code was for updating branches\r
- Vector3d bintersect = new Vector3d();\r
- PipeControlPoint bcp = other.getSubPointOf();\r
- if (bcp != null && canMoveOther) {\r
- Point3d bstart = new Point3d();\r
- Point3d bend = new Point3d();\r
- Vector3d bdir = new Vector3d();\r
- ControlPointTools.getInlineControlPointEnds(bcp, bstart, bend, bdir);\r
- Vector3d nintersect = new Vector3d();\r
- \r
- MathTools.intersectStraightStraight(position, directedDirection, bstart,\r
- bdir, nintersect, bintersect, mu);\r
- Vector3d dist = new Vector3d(nintersect);\r
- dist.sub(bintersect);\r
- canMoveOther = mu[1] > 0.0 && mu[1] < 1.0 && dist.lengthSquared() < 0.01;\r
- } else {\r
- // TODO : endControlPoints are undirected: calculcate correct position for it\r
- throw new UnsupportedOperationException("not implemented");\r
- }\r
- if (canMoveOther) { \r
- if (DEBUG) System.out.println("PipingRules.updateDirectedPipeRun() moved end " + other.getResource() + " to " + bintersect);\r
- // is required branch position is in possible range\r
- ControlPointTools.setWorldPosition(bcp, bintersect);\r
- if (dcpStart) {\r
- checkExpandPathLeg(new UpdateStruct2(u.start, u.startPoint, u.list, u.end, new Point3d(bintersect),directedDirection, u.offset, u.hasOffsets, u.iter, u.reversed, u.toRemove,u.updated),lengthChange);\r
- } else {\r
- checkExpandPathLeg(new UpdateStruct2(u.start, new Point3d(bintersect), u.list, u.end, u.endPoint,directedDirection, u.offset, u.hasOffsets, u.iter, u.reversed, u.toRemove,u.updated),lengthChange); \r
- }\r
- } else {\r
- // branch cannot be moved into right position, new turn\r
- // / elbow must be inserted\r
- insertElbowUpdate(u , dcp, nextToMoved, dcpStart, position, directedDirection);\r
- }\r
-\r
- } else { // assume that control point cannot be moved, but can be rotated\r
- insertElbowUpdate(u, dcp, nextToMoved, dcpStart, position, directedDirection);\r
- }\r
- }\r
- }\r
- }\r
- \r
- \r
- \r
- private static void updateDualDirectedPathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange) {\r
- if (DEBUG) System.out.println("PipingRules.updateDualDirectedPipeRun() " + u + " " + lengthChange);\r
-\r
- PipeControlPoint dcp1 = u.start;\r
- PipeControlPoint dcp2 = u.end;\r
- Point3d position1 = u.startPoint;\r
- Point3d position2 = u.endPoint;\r
- Point3d position1offset = new Point3d(position1);\r
- position1offset.sub(u.offset);\r
- Point3d position2offset = new Point3d(position2);\r
- position2offset.add(u.offset);\r
- Vector3d dir1 = ControlPointTools.getDirectedControlPointDirection(dcp1);\r
- Vector3d dir2 = ControlPointTools.getDirectedControlPointDirection(dcp2);\r
- Vector3d p1 = MathTools.closestPointOnStraight(position1offset, position2, dir2);\r
- Vector3d p2 = MathTools.closestPointOnStraight(position2offset, position1, dir1);\r
- double d1 = position1.distance(new Point3d(p1));\r
- double d2 = position2.distance(new Point3d(p2));\r
-\r
- boolean aligned = (d1 < 0.01 && d2 < 0.01);\r
- if (aligned) {\r
- processPathLeg(u);\r
- } else {\r
- if (u.iter > 0) {\r
- backIter(u);\r
- } else {\r
- PipeControlPoint dcp;\r
- PipeControlPoint next;\r
- if (!u.reversed) {\r
- dcp = dcp1;\r
- if (u.list.size() > 0)\r
- next = u.list.get(0);\r
- else\r
- next = dcp2;\r
- } else {\r
- dcp = dcp2;\r
- if (u.list.size() > 0)\r
- next = u.list.get(u.list.size() - 1);\r
- else\r
- next = dcp1;\r
- }\r
-\r
- PipeRun pipeline = ControlPointTools.getPipeRun(dcp1);\r
- PipelineComponent elbow1 = PipingTools2.instantiatePipelineComponent(u.start.getGraph(), pipeline.getResource(), ProcessResource.plant3Dresource.Elbow);\r
- PipelineComponent elbow2 = PipingTools2.instantiatePipelineComponent(u.start.getGraph(), pipeline.getResource(), ProcessResource.plant3Dresource.Elbow);\r
- \r
- PipeControlPoint tcp1 = elbow1.getControlPoint();\r
- PipeControlPoint tcp2 = elbow2.getControlPoint();\r
- \r
- // Straight s1 = getStraight(dcp, next);\r
- ControlPointTools.insertControlPoint(tcp1, dcp, next);\r
- // s1 = getStraight(tcp1, next);\r
- ControlPointTools.insertControlPoint(tcp2, tcp1, next);\r
- p1 = G3DTools.getVector(dcp.getLocalPosition());\r
- if (!u.reversed)\r
- p1.add(dir1);\r
- else\r
- p1.add(dir2);\r
- \r
- if (!u.reversed)\r
- p2 = MathTools.closestPointOnStraight(new Point3d(p1), position2, dir2);\r
- else\r
- p2 = MathTools.closestPointOnStraight(new Point3d(p1), position1, dir1);\r
- \r
- ControlPointTools.setWorldPosition(tcp1, p1);\r
- ControlPointTools.setWorldPosition(tcp2, p2);\r
- \r
- if (DEBUG) System.out.println("PipingRules.updateDualDirectedPipeRun() created two turns " + tcp1.getResource() + " " + tcp2.getResource());\r
-\r
- if (!u.reversed) {\r
- Vector3d dd = new Vector3d(p2);\r
- dd.sub(p1);\r
- dir2.negate();\r
- processPathLeg(new UpdateStruct2(u.start, u.startPoint,new ArrayList<PipeControlPoint>(), tcp1, new Point3d(p1),dir1, new Vector3d(), false, 0, false,new ArrayList<ExpandIterInfo>(), u.updated));\r
- processPathLeg(new UpdateStruct2(tcp1,new Point3d(p1), new ArrayList<PipeControlPoint>(),tcp2, new Point3d(p2), dd,new Vector3d(), false, 0, false,new ArrayList<ExpandIterInfo>(), u.updated));\r
- // offset is recalculated\r
- processPathLegNoOffset(new UpdateStruct2(tcp2, new Point3d(p2), u.list,u.end, u.endPoint, dir2, null, u.hasOffsets,u.iter, u.reversed, u.toRemove, u.updated));\r
- } else {\r
- Vector3d dd = new Vector3d(p1);\r
- dd.sub(p2);\r
- dir2.negate();\r
- processPathLeg(new UpdateStruct2(tcp1,new Point3d(p1), new ArrayList<PipeControlPoint>(),u.end, u.endPoint, dir2, new Vector3d(), false, 0,false, new ArrayList<ExpandIterInfo>(), u.updated));\r
- processPathLeg(new UpdateStruct2(tcp2,new Point3d(p2), new ArrayList<PipeControlPoint>(),tcp1, new Point3d(p1), dd,new Vector3d(), false, 0, false,new ArrayList<ExpandIterInfo>(), u.updated));\r
- // offset is recalculated\r
- processPathLegNoOffset(new UpdateStruct2(u.start, u.startPoint,u.list, tcp2, new Point3d(p2),dir1, null, u.hasOffsets, u.iter, u.reversed,u.toRemove, u.updated));\r
- }\r
- }\r
- }\r
- }\r
- \r
- private static void insertElbowUpdate(UpdateStruct2 u, PipeControlPoint dcp, PipeControlPoint next, boolean dcpStart, Point3d position, Vector3d directedDirection) {\r
- \r
- Vector3d closest = new Vector3d(position);\r
- closest.add(directedDirection);\r
- PipeControlPoint tcp = insertElbow(dcp, next, new Point3d(closest));\r
-\r
- if (DEBUG) System.out.println("PipingRules.updateDirectedPipeRun() inserted " + tcp.getResource());\r
- \r
- if (dcpStart) {\r
- // update pipe run from new turn to other end\r
- ppNoDir(tcp, new Point3d(closest), u.list, u.end, u.endPoint, u.hasOffsets, u.iter, u.reversed, u.toRemove, u.updated);\r
- // update pipe run from directed to new turn\r
- processPathLeg(new UpdateStruct2(u.start, u.startPoint, new ArrayList<PipeControlPoint>(), tcp, new Point3d(closest), directedDirection, new Vector3d(), false, 0, false, new ArrayList<ExpandIterInfo>(),u.updated)); \r
- } else {\r
- // update pipe run from other end to new turn\r
- ppNoDir(u.start, u.startPoint, u.list, tcp, new Point3d(closest), u.hasOffsets, u.iter, u.reversed, u.toRemove,u.updated);\r
- // update pipe run from new turn to directed\r
- processPathLeg(new UpdateStruct2(tcp, new Point3d(closest), new ArrayList<PipeControlPoint>(), u.end, u.endPoint, directedDirection, new Vector3d(), false, 0, false, new ArrayList<ExpandIterInfo>(),u.updated));\r
- }\r
- }\r
- \r
- /**\r
- * Checks if turns can be removed (turn angle near zero)\r
- */\r
- private static int checkTurns(UpdateStruct2 u, PathLegUpdateType lengthChange) {\r
- if (DEBUG)\r
- System.out.println("PipingRules.checkTurns() " + u.start.getResource()\r
- + " " + u.end.getResource());\r
- boolean startRemoved = false;\r
- boolean endRemoved = false;\r
- if (u.start.isInstanceOf(ProcessResource.plant3Dresource.VariableAngleTurnControlPoint)) {\r
- // this won't work properly if inline control points are not updated\r
- PipeControlPoint startPrev = u.start.getPrevious();\r
- if (startPrev != null) {\r
- double a;\r
- if (!u.hasOffsets) {\r
- a = updateTurnControlPointTurn( u.start, startPrev, u.end);\r
- } else {\r
- Point3d ep = new Point3d(u.endPoint);\r
- ep.add(u.offset);\r
- a = updateTurnControlPointTurn( u.start,u.startPoint, G3DTools.getPoint(startPrev.getLocalPosition()), ep);\r
-\r
- }\r
- if (a < MIN_TURN_ANGLE)\r
- startRemoved = true;\r
- else if (lengthChange == PathLegUpdateType.PREV || lengthChange == PathLegUpdateType.PREV_S){\r
- PathLegUpdateType type;\r
- if (lengthChange == PathLegUpdateType.PREV_S)\r
- type = PathLegUpdateType.PREV;\r
- else\r
- type = PathLegUpdateType.NONE;\r
- updatePathLegPrev(u.start, u.start, type);\r
- }\r
- }\r
- }\r
- if (u.end.isInstanceOf(ProcessResource.plant3Dresource.VariableAngleTurnControlPoint)) {\r
-\r
- PipeControlPoint endNext = u.end.getNext();\r
- if (endNext != null) {\r
- double a;\r
- if (!u.hasOffsets) {\r
- a = updateTurnControlPointTurn(u.end,u.start, endNext);\r
- } else {\r
- Point3d sp = new Point3d(u.startPoint);\r
- sp.sub(u.offset);\r
- a = updateTurnControlPointTurn(u.end, u.endPoint, sp, G3DTools.getPoint(endNext.getLocalPosition()));\r
- }\r
- if (a < MIN_TURN_ANGLE)\r
- endRemoved = true;\r
- else if (lengthChange == PathLegUpdateType.NEXT || lengthChange == PathLegUpdateType.NEXT_S){\r
- PathLegUpdateType type;\r
- if (lengthChange == PathLegUpdateType.NEXT_S)\r
- type = PathLegUpdateType.NEXT;\r
- else\r
- type = PathLegUpdateType.NONE;\r
- updatePathLegNext(u.end, u.end,type);\r
- }\r
- }\r
- }\r
- if (DEBUG)\r
- System.out.println("PipingRules.checkTurns() res " + startRemoved + " " + endRemoved);\r
- if (!startRemoved && !endRemoved)\r
- return REMOVE_NONE;\r
- if (startRemoved && endRemoved)\r
- return REMOVE_BOTH;\r
- if (startRemoved)\r
- return REMOVE_START;\r
- return REMOVE_END;\r
- }\r
- \r
- /**\r
- * Expands piperun search over turns that are going to be removed\r
- * \r
- */\r
- private static void expandPathLeg(UpdateStruct2 u, int type) {\r
- if (DEBUG) System.out.println("PipingRules.expandPipeline " + u.start.getResource() + " " + u.end.getResource());\r
- ArrayList<PipeControlPoint> newList = new ArrayList<PipeControlPoint> ();\r
- switch (type) {\r
- case REMOVE_NONE :\r
- throw new RuntimeException("Error in piping rules");\r
- case REMOVE_START :\r
- u.toRemove.add(new ExpandIterInfo(u.start,REMOVE_START));\r
- u.start = ControlPointTools.findPreviousEnd(u.start);\r
- u.startPoint = G3DTools.getPoint(u.start.getLocalPosition());\r
- ControlPointTools.findNextEnd(u.start,newList);\r
- newList.addAll(u.list);\r
- u.list = newList;\r
- break;\r
- case REMOVE_END :\r
- u.toRemove.add(new ExpandIterInfo(u.end,REMOVE_END));\r
- u.end = ControlPointTools.findNextEnd(u.end,newList);\r
- u.endPoint = G3DTools.getPoint(u.end.getLocalPosition());\r
- u.list.addAll(newList);\r
- break;\r
- case REMOVE_BOTH :\r
- u.toRemove.add(new ExpandIterInfo(u.start,u.end));\r
- u.start = ControlPointTools.findPreviousEnd(u.start);\r
- u.startPoint = G3DTools.getPoint(u.start.getLocalPosition());\r
- ControlPointTools.findNextEnd(u.start,newList);\r
- newList.addAll(u.list);\r
- u.list = newList;\r
- newList = new ArrayList<PipeControlPoint> ();\r
- u.end = ControlPointTools.findNextEnd(u.end,newList);\r
- u.endPoint = G3DTools.getPoint(u.end.getLocalPosition());\r
- u.list.addAll(newList);\r
- break;\r
- default:\r
- throw new RuntimeException("Error in piping rules");\r
- \r
- }\r
- u.offset = new Vector3d();\r
- if (u.hasOffsets) {\r
- u.dir.normalize();\r
- for (PipeControlPoint icp : u.list) {\r
- if (icp.isInstanceOf(ProcessResource.plant3Dresource.OffsettingPoint)) {\r
- u.offset.add(ControlPointTools.getSizeChangeOffsetVector(icp,u.dir));\r
- }\r
- else if (icp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) \r
- ErrorLogger.defaultLogError("Updating pipe run, found offset controlpoint " + icp.getResource(), new Exception("ASSERT!"));\r
- }\r
- }\r
- if (DEBUG) System.out.println("PipingRules.expandPipeline expanded " + u.start.getResource() + " " + u.end.getResource());\r
- u.iter++;\r
- updatePathLeg(u,PathLegUpdateType.NONE);\r
- }\r
- \r
- /**\r
- * reverts one iteration of turn removing back)\r
- */\r
- private static void backIter(UpdateStruct2 u) {\r
- \r
- if (DEBUG) System.out.println("PipingRules.backIter" + u.start.getResource() + " " + u.end.getResource()); \r
- if (u.iter == 0)\r
- throw new RuntimeException("Error in piping rules");\r
- ExpandIterInfo info = u.toRemove.get(u.toRemove.size()-1);\r
- u.toRemove.remove(u.toRemove.size()-1);\r
- if (info.getType() == REMOVE_START || info.getType() == REMOVE_BOTH) {\r
- while (u.list.size() > 0) {\r
- PipeControlPoint icp = u.list.get(0);\r
- if (icp.getPrevious().getResource().equals(info.getStart().getResource())) \r
- break;\r
- u.list.remove(icp);\r
- }\r
- u.start = info.getStart(); \r
- } \r
- if (info.getType() == REMOVE_END || info.getType() == REMOVE_BOTH) {\r
- while (u.list.size() > 0) {\r
- PipeControlPoint icp = u.list.get(u.list.size() - 1);\r
- if (icp.getNext().getResource().equals(info.getEnd().getResource())) \r
- break;\r
- u.list.remove(icp);\r
- }\r
- u.end = info.getEnd();\r
- }\r
- u.offset = new Vector3d();\r
- if (u.hasOffsets) {\r
- u.dir.normalize();\r
- for (PipeControlPoint icp : u.list) {\r
- if (icp.isInstanceOf(ProcessResource.plant3Dresource.OffsettingPoint)) {\r
- u.offset.add(ControlPointTools.getSizeChangeOffsetVector(icp,u.dir));\r
- }\r
- else if (icp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) \r
- ErrorLogger.defaultLogError("Updating pipe run, found offset controlpoint " + icp.getResource(), new Exception("ASSERT!"));\r
- }\r
- }\r
- processPathLeg(u);\r
- \r
- }\r
- \r
- /**\r
- * Processes pipe run (removes necessary turns and updates run ends)\r
- */\r
- // private static void processPathLeg(PipeControlPoint start, Point3d startPoint,ArrayList<InlineControlPoint> list, PipeControlPoint end,Point3d endPoint, Vector3d dir,Vector3d offset, boolean hasOffsets,int iter, boolean reversed, ArrayList<ExpandIterInfo> toRemove) throws TransactionException {\r
- \r
- private static void processPathLeg(UpdateStruct2 u) {\r
- if (DEBUG) System.out.println("PipingRules.processPathLeg " + u.start.getResource() + " " + u.end.getResource());\r
- processPathLeg(u, true, true);\r
- }\r
- \r
- \r
- private static void processPathLeg(UpdateStruct2 u, boolean updateEnds, boolean updateInline) {\r
- if (DEBUG) System.out.println("PipingRules.processPathLeg " + u.start.getResource() + " " + u.end.getResource());\r
- if (u.toRemove.size() > 0) {\r
- for (ExpandIterInfo info : u.toRemove) {\r
- if (info.getStart() != null) {\r
- ControlPointTools.removeControlPoint(info.getStart());\r
- }\r
- if (info.getEnd() != null) {\r
- ControlPointTools.removeControlPoint(info.getEnd());\r
- }\r
- }\r
- // ControlPointTools.removeControlPoint may remove mo0re than one CP;\r
- // we must populate inline CP list again.\r
- u.list.clear();\r
- ControlPointTools.findNextEnd(u.start, u.list);\r
- }\r
- // FIXME : inline CPs are update twice because their positions must be updated before and after ends. \r
- updateInlineControlPoints(u,false);\r
- if (updateEnds) {\r
- if (u.start.isInstanceOf(ProcessResource.plant3Dresource.TurnControlPoint)) {\r
- updateTurnControlPointTurn(u.start, u.start.getPrevious(), u.start.getNext());\r
- updatePathLegPrev(u.start, u.start, PathLegUpdateType.NONE);\r
- } else if (u.start.isInstanceOf(ProcessResource.plant3Dresource.EndComponentControlPoint)) {\r
- updateEndComponentControlPoint(u.start, u.startPoint, u.endPoint);\r
- }\r
- if (u.end.isInstanceOf(ProcessResource.plant3Dresource.TurnControlPoint)) {\r
- updateTurnControlPointTurn( u.end, u.end.getPrevious(), u.end.getNext());\r
- updatePathLegNext(u.end, u.end, PathLegUpdateType.NONE);\r
- } else if (u.end.isInstanceOf(ProcessResource.plant3Dresource.EndComponentControlPoint)) {\r
- updateEndComponentControlPoint(u.end, u.startPoint, u.endPoint);\r
- }\r
- \r
- } else {\r
- if (u.start.isInstanceOf(ProcessResource.plant3Dresource.EndComponentControlPoint)) {\r
- updateEndComponentControlPoint(u.start, u.startPoint, u.endPoint);\r
- }\r
- if (u.end.isInstanceOf(ProcessResource.plant3Dresource.EndComponentControlPoint)) {\r
- updateEndComponentControlPoint( u.end, u.startPoint, u.endPoint);\r
- }\r
- }\r
- if(updateInline)\r
- updateInlineControlPoints(u,true);\r
- \r
- }\r
- \r
- /**\r
- * Processes pipe run and recalculates offset\r
- */\r
- //private static void processPathLeg(PipeControlPoint start, Point3d startPoint,ArrayList<InlineControlPoint> list, PipeControlPoint end,Point3d endPoint, Vector3d dir, boolean hasOffsets,int iter, boolean reversed, ArrayList<ExpandIterInfo> toRemove) throws TransactionException {\r
- private static void processPathLegNoOffset(UpdateStruct2 u) {\r
- if (DEBUG) System.out.println("PipingRules.processPathLeg " + u.start.getResource() + " " + u.end.getResource());\r
- Vector3d offset = new Vector3d();\r
- if (u.hasOffsets) {\r
- u.dir.normalize();\r
- for (PipeControlPoint icp : u.list) {\r
- if (icp.isInstanceOf(ProcessResource.plant3Dresource.OffsetComponent)) {\r
- offset.add(ControlPointTools.getSizeChangeOffsetVector(icp,u.dir));\r
- } else if (icp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {\r
- ErrorLogger.defaultLogError("Updating pipe run, found offset controlpoint " + icp.getResource(), new Exception("ASSERT!"));\r
- }\r
- }\r
- } \r
- processPathLeg(u);\r
- }\r
- \r
- private static void updateOffsetPoint(PipeControlPoint sccp, Vector3d offset) {\r
- Point3d world = G3DTools.getPoint(sccp.getWorldPosition());\r
- world.add(offset);\r
- PipeControlPoint ocp = sccp.getSubPoint().iterator().next();\r
- ControlPointTools.setWorldPosition(ocp, world);\r
- }\r
- \r
- private static void updatePathLegPrev(PipeControlPoint start, PipeControlPoint updated, PathLegUpdateType lengthChange) {\r
- ArrayList<PipeControlPoint> list = new ArrayList<PipeControlPoint>();\r
- PipeControlPoint end = ControlPointTools.findPreviousEnd(start,list);\r
- updatePathLegPrev(start, list, end,updated,lengthChange);\r
- }\r
- \r
- private static void updatePathLegPrev(PipeControlPoint start, ArrayList<PipeControlPoint> list, PipeControlPoint end, PipeControlPoint updated, PathLegUpdateType lengthChange) {\r
- // reverses the list\r
- ArrayList<PipeControlPoint> nextList = new ArrayList<PipeControlPoint>();\r
- for (PipeControlPoint icp : list) {\r
- if (icp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {\r
- nextList.add(0, icp.getSubPointOf());\r
- } else {\r
- nextList.add(0,icp);\r
- }\r
- \r
- }\r
- updatePathLeg(end, nextList, start, true,0,new ArrayList<ExpandIterInfo>(),updated,lengthChange);\r
- \r
- }\r
-\r
- \r
- /**\r
- * Updates InlineControlPoints position when straight pipe's end(s) have\r
- * been changed)\r
- * \r
- * @param pipeline\r
- * @param icp\r
- * @param nextPoint\r
- * @param prevPoint\r
- */\r
- private static void updateInlineControlPoint( PipeControlPoint icp, Point3d nextPoint, Point3d prevPoint, Vector3d dir) {\r
- if (DEBUG) System.out.println("PipingRules.updateInlineControlPoint() " + icp.getResource());\r
- \r
- Point3d inlinePoint = G3DTools.getPoint(icp.getLocalPosition());\r
- if (DEBUG) System.out.print("InlineControlPoint update "+icp.getResource() + " " + inlinePoint + " " + prevPoint + " " + nextPoint);\r
- Vector3d newInlinePoint = null;\r
- boolean branchUpdate = false;\r
- PipeControlPoint becp = null;\r
- for (PipeControlPoint pcp : icp.getSubPoint())\r
- if (pcp.isInstanceOf(ProcessResource.plant3Dresource.UndirectedControlPoint)) {\r
- branchUpdate = true;\r
- becp = pcp;\r
- break;\r
- }\r
- \r
- if (DUMMY || !branchUpdate) {\r
- newInlinePoint = MathTools.closestPointOnEdge(new Vector3d(inlinePoint), new Vector3d(nextPoint), new Vector3d(prevPoint));\r
- } else {\r
- \r
- // FIXME : can only handle one branch\r
- PipeControlPoint p = null;\r
- if (becp.getNext() != null) {\r
- p = ControlPointTools.findNextEnd(becp);\r
- } else if (becp.getPrevious() != null) {\r
- p = ControlPointTools.findPreviousEnd(becp);\r
- } \r
- if (p == null) {\r
- newInlinePoint = MathTools.closestPointOnEdge(new Vector3d(inlinePoint), new Vector3d(nextPoint), new Vector3d(prevPoint));\r
- } else {\r
- Point3d branchLegEnd = G3DTools.getPoint(p.getLocalPosition());\r
- Vector3d dir2 = new Vector3d(inlinePoint);\r
- dir2.sub(branchLegEnd);\r
- Vector3d dir1 = new Vector3d(nextPoint);\r
- dir1.sub(prevPoint);\r
- newInlinePoint = new Vector3d();\r
- double mu[] = new double[2];\r
- MathTools.intersectStraightStraight(new Vector3d(prevPoint), dir1, new Vector3d(branchLegEnd), dir2, newInlinePoint, new Vector3d(),mu);\r
- if (DEBUG) System.out.println(mu[0]);\r
- // FIXME : reserve space \r
- if (mu[0] < 0.0) {\r
- newInlinePoint = new Vector3d(prevPoint);\r
- } else if (mu[0] > 1.0) {\r
- newInlinePoint = new Vector3d(nextPoint);\r
- }\r
- }\r
- }\r
- if (DEBUG) System.out.println(" " + newInlinePoint);\r
- \r
- ControlPointTools.setWorldPosition(icp, newInlinePoint);\r
- updateControlPointOrientation(icp);\r
- }\r
- \r
- /**\r
- * Updates InlineControlPoints position when straight pipe's end(s) have\r
- * been changed)\r
- * \r
- * @param pipeline\r
- * @param icp\r
- * @param nextPoint\r
- * @param prevPoint\r
- */\r
- private static void updateEndComponentControlPoint( PipeControlPoint ecp, Point3d start, Point3d end) {\r
- if (DEBUG) System.out.println("PipingRules.updateEndComponentControlPoint() " + ecp.getResource());\r
-// PipeControlPoint next = ecp.getNext();\r
-// PipeControlPoint prev = ecp.getPrevious();\r
-// if (next != null) {\r
-// end = G3DTools.getPoint(next.getLocalPosition());\r
-// start = G3DTools.getPoint(ecp.getLocalPosition());\r
-// } else if (prev != null) {\r
-// end = G3DTools.getPoint(ecp.getLocalPosition());\r
-// start = G3DTools.getPoint(prev.getLocalPosition());\r
-// } else {\r
-// // TODO : warning?\r
-// return;\r
-// }\r
- //Vector3d dir = new Vector3d (end);\r
- //dir.sub(start);\r
- //dir.normalize();\r
- //G3DTools.setTuple(ecp.getDirection(), dir);\r
- \r
- updateControlPointOrientation(ecp);\r
- \r
- for (PipeControlPoint pcp : ecp.getSubPoint()) {\r
- // TODO update position\r
- updatePathLegEndControlPoint(pcp);\r
- }\r
- }\r
- \r
- private static void updateControlPointOrientation(PipeControlPoint pcp) {\r
- // FIXME : hack to bypass variable length components orientation\r
- if (pcp.getAtMostOneRelatedObject(ProcessResource.g3dResource.HasWorldOrientation) == null)\r
- return;\r
- Double angleO = pcp.getAtMostOneRelatedScalarDouble(ProcessResource.plant3Dresource.HasRotationAngle);\r
- double angle = 0.0;\r
- if (angleO != null)\r
- angle = angleO;\r
- \r
- AxisAngle4d aa = ControlPointTools.getControlPointWorldRotation(pcp, angle);\r
- ControlPointTools.setWorldOrientation(pcp,aa);\r
- \r
- }\r
-\r
- /**\r
- * Updates all branches when branch's position has been changed\r
- * @param bcp\r
- */\r
- private static void updateBranchControlPointBranches(PipeControlPoint bcp) {\r
- if (DEBUG) System.out.println("PipingRules.updateBranchControlPointBranches() " + bcp.getResource());\r
- Collection<PipeControlPoint> branches = bcp.getSubPoint();\r
- if (branches.size() == 0) {\r
- if (DEBUG) System.out.println("No Branches found");\r
- return;\r
- }\r
- for (PipeControlPoint pcp : branches) {\r
- updatePathLegEndControlPoint(pcp);\r
- }\r
- }\r
- \r
- /**\r
- * Recalculates turn control point's internal data (turn angle and offset)\r
- * @param tcp\r
- * @param prev\r
- * @param next\r
- */\r
- private static double updateTurnControlPointTurn( PipeControlPoint tcp, PipeControlPoint prev, PipeControlPoint next) {\r
- if (DEBUG) System.out.println("PipingTools.updateTurnControlPointTurn()" + tcp.getResource());\r
- if (next == null || prev == null)\r
- return Math.PI; // FIXME : argh\r
- Point3d middlePoint = G3DTools.getPoint(tcp.getWorldPosition());\r
- Point3d nextPoint = G3DTools.getPoint(next.getWorldPosition()); \r
- Point3d prevPoint = G3DTools.getPoint(prev.getWorldPosition()); \r
- return updateTurnControlPointTurn(tcp, middlePoint, prevPoint, nextPoint);\r
- }\r
- \r
- /**\r
- * Recalculates turn control point's internal data (turn angle and offset)\r
- * @param tcp\r
- * @param middlePoint\r
- * @param nextPoint\r
- * @param prevPoint\r
- */\r
- private static double updateTurnControlPointTurn( PipeControlPoint tcp, Point3d middlePoint, Point3d prevPoint, Point3d nextPoint) {\r
- \r
- Vector3d dir1 = new Vector3d(middlePoint);\r
- dir1.sub(prevPoint);\r
- Vector3d dir2 = new Vector3d(nextPoint);\r
- dir2.sub(middlePoint);\r
- if (DEBUG) System.out.println("PipingTools.updateTurnControlPointTurn " + tcp.getResource() + " " + prevPoint + " " + middlePoint + " " + nextPoint);\r
- return updateTurnControlPointTurn(tcp, dir1, dir2);\r
- }\r
- \r
- private static double updateTurnControlPointTurn(PipeControlPoint tcp, Vector3d dir1, Vector3d dir2) {\r
- double turnAngle = dir1.angle(dir2);\r
- double angle = Math.PI - turnAngle;\r
- \r
- double elbowRadius = tcp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasTurnRadius);\r
- double R = elbowRadius / Math.tan(angle * 0.5);\r
- Vector3d turnAxis = new Vector3d();\r
- turnAxis.cross(dir1, dir2);\r
- turnAxis.normalize();\r
- tcp.setRelatedScalarDouble(ProcessResource.plant3Dresource.HasTurnAngle,turnAngle);\r
- tcp.setRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength, R);//setComponentOffsetValue(R);\r
- G3DTools.setTuple3(tcp.getSingleRelatedObject(ProcessResource.plant3Dresource.HasTurnAxis), turnAxis);\r
- if (DEBUG) System.out.println("PipingTools.updateTurnControlPointTurn " + dir1 + " " + dir2 + " " + turnAngle + " " + turnAxis);\r
- return turnAngle;\r
- }\r
- \r
-}\r