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