X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.plant3d%2Fsrc%2Forg%2Fsimantics%2Fplant3d%2Fscenegraph%2Fcontrolpoint%2FPipingRules.java;h=f5c6f876a98d507eca60c31bcd809dd8f25bb37d;hb=ebfe6b0245b5cf9231cecedf0aaacd891eb5d344;hp=5f52c52521ac8ad4b56b78be49741547225ea920;hpb=5c3e9116d5e5aefa51ec3caa3b0e42a4e983281f;p=simantics%2F3d.git diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipingRules.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipingRules.java index 5f52c525..f5c6f876 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipingRules.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipingRules.java @@ -25,18 +25,14 @@ 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 double MIN_TURN_ANGLE = 0.001; // Threshold for removing turn components. + private static double ALLOWED_OFFSET = 0.001; // Allowed offset for directed path legs 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 P3DRootNode root; - -// public PipingRules(P3DRootNode root) { -// this.root = root; -// } private enum PathLegUpdateType { NONE, PREV, NEXT, PREV_S, NEXT_S @@ -48,29 +44,46 @@ public class PipingRules { private static boolean triedIR = false; - private static List updates = new ArrayList(); + private static List requestUpdates = new ArrayList(); + private static List currentUpdates = new ArrayList(); - private static Object mutex = new Object(); + private static Object updateMutex = new Object(); + private static Object ruleMutex = new Object(); public static void requestUpdate(PipeControlPoint pcp) { + if (!PipingRules.enabled) + return; if (DEBUG) System.out.println("PipingRules request " + pcp); - synchronized (mutex) { - if (!updates.contains(pcp)) - updates.add(pcp); + synchronized (updateMutex) { + if (!requestUpdates.contains(pcp)) + requestUpdates.add(pcp); } } - public static synchronized boolean update() throws Exception { - if (updates.size() == 0) + public static boolean update() throws Exception { + if (!PipingRules.enabled) + return false; + + if (requestUpdates.size() == 0) return false; - List temp = new ArrayList(updates.size()); - synchronized(mutex) { - temp.addAll(updates); - updates.clear(); + + List temp = new ArrayList(requestUpdates.size()); + synchronized(updateMutex) { + temp.addAll(requestUpdates); + requestUpdates.clear(); + } + synchronized (ruleMutex) { + currentUpdates.clear(); + currentUpdates.addAll(temp); + // TODO : we should remove already processed control points from currentUpdates after each _positionUpdate call. + for (PipeControlPoint pcp : currentUpdates) + _positionUpdate(pcp, true); + currentUpdates.clear(); + } + synchronized(updateMutex) { + requestUpdates.removeAll(temp); } - for (PipeControlPoint pcp : temp) - positionUpdate(pcp); return true; } @@ -80,6 +93,16 @@ public class PipingRules { } public static boolean positionUpdate(PipeControlPoint pcp, boolean allowIR) throws Exception { + synchronized (ruleMutex) { + currentUpdates.add(pcp); + boolean b = _positionUpdate(pcp, allowIR); + currentUpdates.clear(); + return b; + } + + } + + private static boolean _positionUpdate(PipeControlPoint pcp, boolean allowIR) throws Exception { if (updating || !enabled) return true; if (pcp.getPipeRun() == null) @@ -91,7 +114,7 @@ public class PipingRules { triedIR = false; validate(pcp.getPipeRun()); if (pcp.isPathLegEnd()) { - updatePathLegEndControlPoint(pcp); // FXIME: Rules won't work properly, if they are not run twice. + updatePathLegEndControlPoint(pcp); // FIXME: Rules won't work properly, if they are not run twice. updatePathLegEndControlPoint(pcp); } else { updateInlineControlPoint(pcp); @@ -110,7 +133,7 @@ public class PipingRules { public static void setEnabled(boolean enabled) { PipingRules.enabled = enabled; if(!enabled) - updates.clear(); + currentUpdates.clear(); } public static boolean isEnabled() { @@ -278,18 +301,35 @@ public class PipingRules { } private static void updatePathLegNext(PipeControlPoint start, PipeControlPoint updated, PathLegUpdateType lengthChange) throws Exception { - ArrayList list = new ArrayList(); - PipeControlPoint end = start.findNextEnd(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) throws Exception { - updatePathLeg(start, list, end, false, 0, new ArrayList(), updated, lengthChange); + UpdateStruct2 us = createUS(start, Direction.NEXT, 0, new ArrayList(), updated); + if (lengthChange == PathLegUpdateType.NONE) { + if (start.equals(updated)) + lengthChange = PathLegUpdateType.NEXT; + else if (us.end.equals(updated)) + lengthChange = PathLegUpdateType.PREV; + } + if (us == null) { + System.out.println("Null update struct " + start); + return; + } + updatePathLeg(us, lengthChange); + } + + private static void updatePathLegPrev(PipeControlPoint start, PipeControlPoint updated, PathLegUpdateType lengthChange) throws Exception { + // TODO: this method is not symmetric with updatePathLegNext, which may alter lengthChange parameter? + UpdateStruct2 us = createUS(start, Direction.PREVIOUS, 0, new ArrayList(), updated); +// if (lengthChange == PathLegUpdateType.NONE) { +// if (start.equals(updated)) +// lengthChange = PathLegUpdateType.NEXT; +// else if (us.end.equals(updated)) +// lengthChange = PathLegUpdateType.PREV; +// } + if (us == null) { + System.out.println("Null update struct " + start); + return; + } + updatePathLeg(us, lengthChange); } private static class UpdateStruct2 { @@ -335,6 +375,7 @@ public class PipingRules { } + @SuppressWarnings("unused") private static boolean calculateOffset(Vector3d startPoint, Vector3d endPoint, ArrayList list, Vector3d dir, Vector3d offset) { boolean hasOffsets = false; List offsets = new ArrayList(list.size()); @@ -384,51 +425,61 @@ public class PipingRules { hasOffsets = true; } -// for (PipeControlPoint icp : list) { -// if (icp.isOffset()) { -// icp.setOffset(((InlineComponent)icp.getPipelineComponent()).getOffset()); -// hasOffsets = true; -// Vector3d v = icp.getSizeChangeOffsetVector(dir); -// offset.add(v); -// } else if (icp.isDualSub()) -// ErrorLogger.defaultLogError("Updating pipe run, found offset controlpoint " + icp, new Exception("ASSERT!")); -// } if (DEBUG && hasOffsets) System.out.println("calcOffset s:"+ startPoint + " e:" + endPoint + " d:" + dir + " o:"+offset) ; 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) throws Exception { + + private static UpdateStruct2 createUS(PipeControlPoint start, Direction direction, int iter, ArrayList toRemove, PipeControlPoint updated) { + ArrayList list = new ArrayList(); + PipeControlPoint end = null; + if (direction == Direction.NEXT) { + end = start.findNextEnd(list); + } else { + ArrayList prevList = new ArrayList(); + PipeControlPoint tend = start.findPreviousEnd(prevList); + for (PipeControlPoint icp : prevList) { + if (icp.isDualSub()) { + list.add(0, icp.getParentPoint()); + } else { + list.add(0, icp); + } + } + end = start; + start = tend; + } if (start == end) - return; - // FIXME: direction is calculated wrong way! + return null; boolean hasOffsets = false; Vector3d offset = new Vector3d(); Vector3d startPoint = start.getWorldPosition(); Vector3d endPoint = 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); - + return new UpdateStruct2(start, startPoint, list, end, endPoint, dir, offset, hasOffsets, iter, direction == Direction.PREVIOUS, toRemove, updated); } - + + private static boolean asDirected(PipeControlPoint pcp, Direction direction) { + if (pcp.isDirected()) + return true; + if (pcp.asFixedAngle()) { + if (!pcp._getReversed()) + return direction == Direction.NEXT; + else + return direction == Direction.PREVIOUS; + } + return false; + } + + private static Vector3d direction(PipeControlPoint pcp, Direction direction) { + return pcp.getDirection(direction); + } + private static void updatePathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange) throws Exception { int directed = 0; - if (u.start.isDirected()) + if (asDirected(u.start, Direction.NEXT)) directed++; - if (u.end.isDirected()) + if (asDirected(u.end, Direction.PREVIOUS)) directed++; switch (directed) { case 0: @@ -448,7 +499,7 @@ public class PipingRules { if (DEBUG) System.out.println("PipingRules.updateFreePipeRun " + u + " " + lengthChange); checkExpandPathLeg(u, lengthChange); - if (u.start.isInline() || u.end.isInline()) + if (u.start.isInline() || u.end.isInline() || u.start.asFixedAngle()|| u.end.asFixedAngle()) processPathLeg(u, true, false); } @@ -456,26 +507,30 @@ public class PipingRules { if (DEBUG) System.out.println("PipingRules.updateInlineControlPoints() " + u); + Vector3d start = new Vector3d(u.startPoint); + Vector3d end = new Vector3d(u.endPoint); + + if (checkSizes) { + // create offsets for leg ends. + MathTools.mad(start, u.dir, u.start.getInlineLength()); + MathTools.mad(end, u.dir, -u.end.getInlineLength()); + } + + boolean recalcline = false; if (!u.hasOffsets) { - // FIXME : cache positions - if (!checkSizes) { - Vector3d start = new Vector3d(u.startPoint); - Vector3d end = new Vector3d(u.endPoint); - // create offsets. - MathTools.mad(start, u.dir, 0.1); - MathTools.mad(end, u.dir, -0.1); - for (PipeControlPoint icp : u.list) { - updateInlineControlPoint(icp, start, end, u.dir); - - if (icp.isOffset()) { - // TODO : offset vector is already calculated and should be - // cached - Vector3d off = icp.getSizeChangeOffsetVector(u.dir); - updateOffsetPoint(icp, off); - } + + + for (PipeControlPoint icp : u.list) { + updateInlineControlPoint(icp, start, end, u.dir); + + if (icp.isOffset()) { + // TODO : offset vector is already calculated and should be cached + Vector3d off = icp.getSizeChangeOffsetVector(u.dir); + updateOffsetPoint(icp, off); } - return; } + if (!checkSizes) + return; ArrayList pathLegPoints = new ArrayList(); pathLegPoints.add(u.start); @@ -488,16 +543,16 @@ public class PipingRules { pathLegPoints.add(u.end); // TODO : values can be cached in the loop - for (int i = 1; i < pathLegPoints.size(); i++) { + for (int i = 0; i < pathLegPoints.size(); i++) { PipeControlPoint icp = pathLegPoints.get(i); - PipeControlPoint prev = pathLegPoints.get(i - 1); - + PipeControlPoint prev = i > 0 ? pathLegPoints.get(i - 1) : null; + PipeControlPoint next = i < pathLegPoints.size() - 1 ? pathLegPoints.get(i + 1) : null; if (icp.isVariableLength()) { - if (i != pathLegPoints.size() - 1) { - PipeControlPoint next = pathLegPoints.get(i + 1); - updateVariableLength(icp, prev, next); + if (prev != null && next != null) { + + recalcline = recalcline | updateVariableLength(icp, prev, next); } else { // this is variable length component at the end of the @@ -505,45 +560,22 @@ public class PipingRules { // 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. - updateVariableLengthEnd(icp, prev); + updateVariableLengthEnd(icp, prev != null ? prev : next); } - } else if (!prev.isVariableLength()) { + } else if (prev != null && !prev.isVariableLength()) { // 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 currentPos = icp.getWorldPosition(); - Vector3d prevPos = prev.getWorldPosition(); - Vector3d dir = new Vector3d(currentPos); - dir.sub(prevPos); - double l = dir.lengthSquared(); - double l2prev = prev.getInlineLength(); - double l2next = icp.getInlineLength(); - double l2 = l2prev + l2next; - double l2s = l2 * l2; - if (l > l2s) { - if (allowInsertRemove) { - 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); - PipeControlPoint scp = insertStraight(prev, icp, dir, length); - } else { - triedIR = true; - } - } + recalcline = recalcline | possibleVaribleLengthInsert(icp, prev); } } - } else { - Vector3d sp = new Vector3d(u.startPoint); - Vector3d ep = new Vector3d(u.endPoint); + } else { // with offset + Vector3d sp = new Vector3d(start); + Vector3d ep = new Vector3d(end); ep.sub(u.offset); ArrayList pathLegPoints = new ArrayList(); @@ -564,23 +596,26 @@ public class PipingRules { } pathLegPoints.add(u.end); + if (!checkSizes) + return; + sp = new Vector3d(u.startPoint); ep = new Vector3d(u.endPoint); ep.sub(u.offset); - for (int i = 1; i < pathLegPoints.size(); i++) { + for (int i = 0; i < pathLegPoints.size(); i++) { PipeControlPoint icp = pathLegPoints.get(i); - PipeControlPoint prev = pathLegPoints.get(i - 1); - if (prev.isDualInline()) + PipeControlPoint prev = i > 0 ? pathLegPoints.get(i - 1) : null; + PipeControlPoint next = i < pathLegPoints.size() - 1 ? pathLegPoints.get(i + 1) : null; + + if (prev != null && prev.isDualInline()) prev = prev.getSubPoint().get(0); if (icp.isVariableLength()) { - if (i != pathLegPoints.size() - 1) { - PipeControlPoint next; - next = pathLegPoints.get(i + 1); - updateVariableLength(icp, prev, next); + if (prev != null && next != null) { + recalcline = recalcline | updateVariableLength(icp, prev, next); } else { // this is variable length component at the end of the @@ -588,9 +623,17 @@ public class PipingRules { // 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. - updateVariableLengthEnd(icp, prev); + updateVariableLengthEnd(icp, prev != null ? prev : next); } - } else if (icp.isOffset()) { + } else if (prev != null && !prev.isVariableLength()) { + // 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. + recalcline = recalcline | possibleVaribleLengthInsert(icp, prev); + } + if (icp.isOffset()) { // TODO : offset vector is already calculated and should be // cached Vector3d offset = icp.getSizeChangeOffsetVector(u.dir); @@ -599,9 +642,13 @@ public class PipingRules { } } } + if (recalcline) { + u.list.clear(); + u.start.findNextEnd(u.list); + } } - private static void updateVariableLength(PipeControlPoint icp, PipeControlPoint prev, PipeControlPoint next) { + private static boolean updateVariableLength(PipeControlPoint icp, PipeControlPoint prev, PipeControlPoint next) { Vector3d prevPos = prev.getWorldPosition(); Vector3d nextPos = next.getWorldPosition(); @@ -632,52 +679,99 @@ public class PipingRules { dir.add(prevPos); icp.setWorldPosition(dir); icp.setLength(length); + return false; } else { // components leave no space to the component and it // must be removed - if (icp.isDeletable()) + + if (icp.isDeletable()) { + if (!allowInsertRemove) { + icp.setLength(0.0001); + triedIR = true; + return false; + } + if (DEBUG) + System.out.println("PipingRules.updateVariableLength removing " + icp); icp._remove(); + return true; + } + return false; } } + private static boolean possibleVaribleLengthInsert(PipeControlPoint icp, PipeControlPoint prev) throws Exception{ + Vector3d currentPos = icp.getWorldPosition(); + Vector3d prevPos = prev.getWorldPosition(); + Vector3d dir = new Vector3d(currentPos); + dir.sub(prevPos); + double l = dir.lengthSquared(); + double l2prev = prev.getInlineLength(); + double l2next = icp.getInlineLength(); + double l2 = l2prev + l2next; + double l2s = l2 * l2; + if (l > l2s) { + if (allowInsertRemove) { + 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); + insertStraight(prev, icp, dir, length); + return true; + } else { + triedIR = true; + } + } + return false; + } + private static void updateVariableLengthEnd(PipeControlPoint icp, PipeControlPoint prev) { - double currentLength = icp.getLength(); Vector3d currentPos = icp.getWorldPosition(); Vector3d prevPos = prev.getWorldPosition(); Vector3d dir = new Vector3d(); dir.sub(currentPos, prevPos); - if (currentLength < MathTools.NEAR_ZERO) { - currentLength = (dir.length() - prev.getInlineLength()) * 2.0; + boolean simple = currentUpdates.contains(icp); + if (simple) { + // Update based on position -> adjust length + double currentLength = (dir.length() - prev.getInlineLength()) * 2.0; + icp.setLength(currentLength); + } else { + // Update based on neighbour movement -> adjust length and position, so that free end stays in place. + double currentLength = icp.getLength(); + if (currentLength < MathTools.NEAR_ZERO) { + currentLength = (dir.length() - prev.getInlineLength()) * 2.0; + } + + if (dir.lengthSquared() > MathTools.NEAR_ZERO) + 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 = prev.getInlineLength(); + Point3d beginPos = new Point3d(dir); + beginPos.scale(offset); + beginPos.add(prevPos); // this is the connected end of the component + + double l = beginPos.distance(endPos); + + if (Double.isNaN(l)) + System.out.println("Length for " + icp + " is NaN"); + + dir.scale(l * 0.5); + beginPos.add(dir); // center position + + if (DEBUG) + System.out.println("PipingRules.updateInlineControlPoints() setting variable length to " + l); + icp.setLength(l); + + icp.setWorldPosition(new Vector3d(beginPos)); } - - if (dir.lengthSquared() > MathTools.NEAR_ZERO) - 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 = prev.getInlineLength(); - Point3d beginPos = new Point3d(dir); - beginPos.scale(offset); - beginPos.add(prevPos); // this is the connected end of - // the component - - double l = beginPos.distance(endPos); - - if (Double.isNaN(l)) - System.out.println(); - - dir.scale(l * 0.5); - beginPos.add(dir); // center position - - if (DEBUG) - System.out.println("PipingRules.updateInlineControlPoints() setting variable length to " + l); - icp.setLength(l); - - icp.setWorldPosition(new Vector3d(beginPos)); } private static void ppNoOffset(UpdateStruct2 u) throws Exception { @@ -708,24 +802,24 @@ public class PipingRules { } private static void checkExpandPathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange) throws Exception { - checkExpandPathLeg(u, lengthChange, false); + checkExpandPathLeg(u, lengthChange, u.updated.isInline() && u.updated.isOffset()); } - private static void checkExpandPathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange, boolean forceUpdate) throws Exception { + private static void checkExpandPathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange, boolean updateEnds) throws Exception { 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, forceUpdate, false); + processPathLeg(u, updateEnds, false); int type = checkTurns(u, lengthChange); if (type == REMOVE_NONE) { - processPathLeg(u, forceUpdate, true); + processPathLeg(u, updateEnds, true); } else { expandPathLeg(u, type); } } else { - processPathLeg(u, forceUpdate, true); + processPathLeg(u, updateEnds, true); } } @@ -738,7 +832,7 @@ public class PipingRules { boolean dcpStart = false; boolean inlineEnd = false; Vector3d position; - if (u.start.isDirected()) { + if (asDirected(u.start, Direction.NEXT)) { dcp = u.start; other = u.end; position = u.startPoint; @@ -756,7 +850,15 @@ public class PipingRules { inlineEnd = u.start.isInline(); } - Vector3d directedDirection = dcp.getDirection(); + Vector3d directedDirection = direction(dcp, dcpStart ? Direction.NEXT : Direction.PREVIOUS); + if (directedDirection == null) { + //updateTurnControlPointTurn(dcp, dcp.getPrevious(), dcp.getNext()); + updateTurnControlPointTurn(dcp, null, null); + directedDirection = direction(dcp, dcpStart ? Direction.NEXT : Direction.PREVIOUS); + if (directedDirection == null) { + return; + } + } Point3d directedEndPoint = new Point3d(u.endPoint); if (u.hasOffsets) directedEndPoint.add(u.offset); @@ -774,9 +876,11 @@ public class PipingRules { t.sub(closest, u.startPoint); } - double distance = t.lengthSquared(); - boolean aligned = (distance < 0.002); + double distance = t.length(); + boolean aligned = (distance < ALLOWED_OFFSET); if (aligned) { + if (u.start.isInline() || u.end.isInline() || u.start.asFixedAngle() || u.end.asFixedAngle()) + processPathLeg(u, true, false); checkExpandPathLeg(u, lengthChange, inlineEnd); } else { @@ -797,13 +901,16 @@ public class PipingRules { if (other.isVariableAngle()) { // TODO calculate needed space from next run end. - if (mu[0] < 1.0) { + double space = spaceForTurn(other); + if (mu[0] < space) { if (dcpStart) { closest.set(u.startPoint); } else { closest.set(u.endPoint); } - closest.add(directedDirection); + Vector3d v = new Vector3d(directedDirection); + v.scale(space); + closest.add(v); } if (canMoveOther) { @@ -891,14 +998,14 @@ public class PipingRules { position1offset.sub(u.offset); Point3d position2offset = new Point3d(position2); position2offset.add(u.offset); - Vector3d dir1 = dcp1.getDirection(); - Vector3d dir2 = dcp2.getDirection(); + Vector3d dir1 = direction(dcp1, Direction.NEXT); + Vector3d dir2 = direction(dcp2, Direction.PREVIOUS); 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); + boolean aligned = (d1 < ALLOWED_OFFSET && d2 < ALLOWED_OFFSET); if (aligned) { processPathLeg(u); } else { @@ -922,17 +1029,27 @@ public class PipingRules { } p1 = dcp.getWorldPosition(); - // FIXME: calculate position of the elbows properly. + Vector3d v = new Vector3d(); if (!u.reversed) - p1.add(dir1); + v.set(dir1); else - p1.add(dir2); + v.set(dir2); + + // Reserve space for 90 deg elbow + double off = dcp1.getPipeRun().getTurnRadius(); + v.scale(off); + p1.add(v); if (!u.reversed) p2 = MathTools.closestPointOnStraight(new Point3d(p1), position2, dir2); else p2 = MathTools.closestPointOnStraight(new Point3d(p1), position1, dir1); + // By default, the elbows are placed next to each other, by using 90 deg angles. + // If the distance between elbows is not enough, we must move the other elbow (and create more shallow angle elbows) + if (MathTools.distance(p1, p2) < off*2.05) { + p2.add(v); + } PipeControlPoint tcp1 = insertElbow(dcp, next, p1); PipeControlPoint tcp2 = insertElbow(tcp1, next, p2); @@ -967,16 +1084,42 @@ public class PipingRules { } } + + private static double spaceForTurn(PipeControlPoint tcp) { + // TODO : this returns now space for 90 deg turn. + // The challenge: position of tcp affects the turn angle, which then affects the required space. Perhaps we need to iterate... + // Additionally, if the path legs contain offset, using just positions of opposite path leg ends is not enough, + return ((TurnComponent)tcp.getPipelineComponent()).getTurnRadius(); + } private static void insertElbowUpdate(UpdateStruct2 u, PipeControlPoint dcp, PipeControlPoint next, boolean dcpStart, Vector3d position, Vector3d directedDirection) throws Exception{ - Vector3d closest = new Vector3d(position); - closest.add(directedDirection); + +// Vector3d closest = new Vector3d(position); +// closest.add(directedDirection); + PipeControlPoint tcp = null; - if (dcpStart) - tcp = insertElbow(dcp, next, new Vector3d(closest)); - else - tcp = insertElbow(next, dcp, new Vector3d(closest)); + Vector3d closest; + if (dcpStart) { + closest = MathTools.closestPointOnStraight(next.getWorldPosition(), position, directedDirection); + tcp = insertElbow(dcp, next, closest); + } else { + closest = MathTools.closestPointOnStraight(dcp.getWorldPosition(), position, directedDirection); + tcp = insertElbow(next, dcp, closest); + } + // TODO properly calculate required distance between start and inserted elbow. + double d = MathTools.distance(position, closest); + double s = spaceForTurn(tcp); + if (d < s) { + d = s - d; + Vector3d p = new Vector3d(directedDirection); + p.scale(d); + p.add(closest); + tcp.setPosition(p); + closest = p; + } + + if (DEBUG) System.out.println("PipingRules.updateDirectedPipeRun() inserted " + tcp); @@ -1006,15 +1149,7 @@ public class PipingRules { // 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 { - Vector3d ep = new Vector3d(u.endPoint); - ep.sub(u.offset); - a = updateTurnControlPointTurn(u.start, u.startPoint, startPrev.getPosition(), ep); - - } + double a = updateTurnControlPointTurn(u.start, null, u.dir); if (a < MIN_TURN_ANGLE && u.start.isDeletable()) startRemoved = true; else if (lengthChange == PathLegUpdateType.PREV || lengthChange == PathLegUpdateType.PREV_S) { @@ -1031,14 +1166,8 @@ public class PipingRules { PipeControlPoint endNext = u.end.getNext(); if (endNext != null) { - double a; - if (!u.hasOffsets) { - a = updateTurnControlPointTurn(u.end, u.start, endNext); - } else { - Vector3d sp = new Vector3d(u.startPoint); - sp.add(u.offset); - a = updateTurnControlPointTurn(u.end, u.endPoint, sp, endNext.getPosition()); - } + // TODO: u.end, u.dir, null + double a = updateTurnControlPointTurn(u.end, null, null); if (a < MIN_TURN_ANGLE && u.end.isDeletable()) endRemoved = true; else if (lengthChange == PathLegUpdateType.NEXT || lengthChange == PathLegUpdateType.NEXT_S) { @@ -1184,14 +1313,17 @@ public class PipingRules { if (u.toRemove.size() > 0) { for (ExpandIterInfo info : u.toRemove) { if (info.getStart() != null) { + if (DEBUG) + System.out.println("PipingRules.processPathLeg removing start " + info.getStart()); info.getStart()._remove(); } if (info.getEnd() != null) { + if (DEBUG) + System.out.println("PipingRules.processPathLeg removing end " + info.getEnd()); info.getEnd()._remove(); } } - // ControlPointTools.removeControlPoint may remove mo0re than one - // CP; + // ControlPointTools.removeControlPoint may remove more than one CP; // we must populate inline CP list again. u.list.clear(); u.start.findNextEnd( u.list); @@ -1202,7 +1334,8 @@ public class PipingRules { if (updateEnds) { if (u.start.isTurn()) { - updateTurnControlPointTurn(u.start, u.start.getPrevious(), u.start.getNext()); + //updateTurnControlPointTurn(u.start, u.start.getPrevious(), u.start.getNext()); + updateTurnControlPointTurn(u.start, null, null); // updatePathLegPrev(u.start, u.start, PathLegUpdateType.NONE); } else if (u.start.isEnd()) { updateEndComponentControlPoint(u.start, u.startPoint, u.endPoint); @@ -1210,7 +1343,8 @@ public class PipingRules { updateControlPointOrientation(u.start); } if (u.end.isTurn()) { - updateTurnControlPointTurn(u.end, u.end.getPrevious(), u.end.getNext()); + //updateTurnControlPointTurn(u.end, u.end.getPrevious(), u.end.getNext()); + updateTurnControlPointTurn(u.end, null, null); // updatePathLegNext(u.end, u.end, PathLegUpdateType.NONE); } else if (u.end.isEnd()) { updateEndComponentControlPoint(u.end, u.startPoint, u.endPoint); @@ -1239,6 +1373,7 @@ public class PipingRules { // end,Point3d endPoint, Vector3d dir, boolean hasOffsets,int iter, boolean // reversed, ArrayList toRemove) throws TransactionException // { + @SuppressWarnings("unused") private static void processPathLegNoOffset(UpdateStruct2 u) throws Exception { if (DEBUG) System.out.println("PipingRules.processPathLeg " + u.start + " " + u.end); @@ -1263,27 +1398,6 @@ public class PipingRules { ocp.setWorldPosition(world); } - private static void updatePathLegPrev(PipeControlPoint start, PipeControlPoint updated, PathLegUpdateType lengthChange) throws Exception { - ArrayList list = new ArrayList(); - PipeControlPoint end = start.findPreviousEnd(list); - updatePathLegPrev(start, list, end, updated, lengthChange); - } - - private static void updatePathLegPrev(PipeControlPoint start, ArrayList list, PipeControlPoint end, PipeControlPoint updated, PathLegUpdateType lengthChange) throws Exception { - // reverses the list - ArrayList nextList = new ArrayList(); - for (PipeControlPoint icp : list) { - if (icp.isDualSub()) { - nextList.add(0, icp.getParentPoint()); - } 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) @@ -1293,54 +1407,72 @@ public class PipingRules { * @param nextPoint * @param prevPoint */ - private static void updateInlineControlPoint(PipeControlPoint icp, Vector3d nextPoint, Vector3d prevPoint, Vector3d dir) { + private static void updateInlineControlPoint(PipeControlPoint icp, Vector3d prev, Vector3d next, Vector3d dir) { if (DEBUG) System.out.println("PipingRules.updateInlineControlPoint() " + icp); Vector3d inlinePoint = icp.getWorldPosition(); + Vector3d prevPoint = new Vector3d(prev); + Vector3d nextPoint = new Vector3d(next); + if (!icp.isVariableLength()) { + // Reserve space for fixed length components. + MathTools.mad(prevPoint, dir, icp.getInlineLength()); + MathTools.mad(nextPoint, dir, -icp.getInlineLength()); + if (MathTools.distance(prevPoint, nextPoint) < ALLOWED_OFFSET) { + prevPoint = prev; + nextPoint = next; + } + } + boolean canCalc = MathTools.distance(prevPoint, nextPoint) > ALLOWED_OFFSET; if (DEBUG) System.out.print("InlineControlPoint update " + icp + " " + inlinePoint + " " + prevPoint + " " + nextPoint); Vector3d newInlinePoint = null; - boolean branchUpdate = false; - PipeControlPoint becp = null; - for (PipeControlPoint pcp : icp.getSubPoint()) - if (pcp.isNonDirected()) { - 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 = becp.findNextEnd(); - } else if (becp.getPrevious() != null) { - p = becp.findPreviousEnd(); - } - if (p == null) { - newInlinePoint = MathTools.closestPointOnEdge(new Vector3d(inlinePoint), new Vector3d(nextPoint), new Vector3d(prevPoint)); + if (canCalc) { + boolean branchUpdate = false; + PipeControlPoint becp = null; + for (PipeControlPoint pcp : icp.getSubPoint()) + if (pcp.isNonDirected()) { + branchUpdate = true; + becp = pcp; + break; + } + + if (DUMMY || !branchUpdate) { + newInlinePoint = MathTools.closestPointOnEdge(new Vector3d(inlinePoint), prevPoint, nextPoint); + } else { - Vector3d branchLegEnd = p.getWorldPosition(); - 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); + + // FIXME : can only handle one branch + PipeControlPoint p = null; + if (becp.getNext() != null) { + p = becp.findNextEnd(); + } else if (becp.getPrevious() != null) { + p = becp.findPreviousEnd(); + } + if (p == null) { + newInlinePoint = MathTools.closestPointOnEdge(new Vector3d(inlinePoint), prevPoint, nextPoint); + } else if (canCalc){ + Vector3d branchLegEnd = p.getWorldPosition(); + 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); + } } } + } else { + // prevPoint == nextPoint + newInlinePoint = new Vector3d(prevPoint); } if (DEBUG) System.out.println(" " + newInlinePoint); @@ -1361,24 +1493,9 @@ public class PipingRules { private static void updateEndComponentControlPoint(PipeControlPoint ecp, Vector3d start, Vector3d end) throws Exception { if (DEBUG) System.out.println("PipingRules.updateEndComponentControlPoint() " + ecp); - // 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); - if (!ecp.isFixed()) - updateControlPointOrientation(ecp); + //FIXME : end control point cannot be fixed! + //if (!ecp.isFixed()) + updateControlPointOrientation(ecp); for (PipeControlPoint pcp : ecp.getSubPoint()) { // TODO update position @@ -1396,8 +1513,11 @@ public class PipingRules { double angle = 0.0; if (angleO != null) angle = angleO; - - Quat4d q = pcp.getControlPointOrientationQuat(angle); + Boolean reversedO = pcp.getReversed(); + boolean reversed = false; + if (reversedO != null) + reversed = reversedO; + Quat4d q = pcp.getControlPointOrientationQuat(angle, reversed); pcp.setWorldOrientation(q); } @@ -1423,69 +1543,88 @@ public class PipingRules { } } - /** - * 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); - if (next == null || prev == null) - return Math.PI; // FIXME : argh - Vector3d middlePoint = tcp.getWorldPosition(); - Vector3d nextPoint = next.getWorldPosition(); - Vector3d prevPoint = 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, Vector3d middlePoint, Vector3d prevPoint, Vector3d 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 + " " + 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; - - Vector3d turnAxis = new Vector3d(); - turnAxis.cross(dir1, dir2); - if (turnAxis.lengthSquared() > MathTools.NEAR_ZERO) { - double elbowRadius = tcp.getPipelineComponent().getPipeRun().getTurnRadius(); - double R = elbowRadius / Math.tan(angle * 0.5); + private static double updateTurnControlPointTurn(PipeControlPoint tcp, Vector3d prev, Vector3d next) { + if (next == null) { + UpdateStruct2 us = createUS(tcp, Direction.NEXT, 0, new ArrayList(), tcp); + if (us != null) + next = us.dir; + } + if (prev == null) { + UpdateStruct2 us = createUS(tcp, Direction.PREVIOUS, 0, new ArrayList(), tcp); + if (us != null) { + prev = us.dir; + } + } + + if (!tcp.asFixedAngle()) { + + + if (next == null || prev == null) { + if (tcp.getTurnAngle() != null) + return tcp.getTurnAngle(); + return Math.PI; // FIXME : argh + } + double turnAngle = prev.angle(next); + + double angle = Math.PI - turnAngle; + + Vector3d turnAxis = new Vector3d(); + turnAxis.cross(prev, next); + if (turnAxis.lengthSquared() > MathTools.NEAR_ZERO) { + double elbowRadius = ((TurnComponent)tcp.getPipelineComponent()).getTurnRadius(); + double R = elbowRadius / Math.tan(angle * 0.5); + + turnAxis.normalize(); + tcp.setTurnAngle(turnAngle); + tcp.setLength(R);// setComponentOffsetValue(R); + tcp.setTurnAxis(turnAxis); + // tcp.setPosition(tcp.getPosition()); + } else { + turnAngle = 0.0; + tcp.setTurnAngle(0.0); + tcp.setLength(0.0); + tcp.setTurnAxis(new Vector3d(MathTools.Y_AXIS)); + } - turnAxis.normalize(); - tcp.setTurnAngle(turnAngle); - tcp.setLength(R);// setComponentOffsetValue(R); - tcp.setTurnAxis(turnAxis); -// tcp.setPosition(tcp.getPosition()); + updateControlPointOrientation(tcp); + + if (DEBUG) + System.out.println("PipingTools.updateTurnControlPointTurn " + prev + " " + next + " " + turnAngle + " " + turnAxis); + return turnAngle; } else { - turnAngle = 0.0; - tcp.setTurnAngle(0.0); - tcp.setLength(0.0); - tcp.setTurnAxis(MathTools.Y_AXIS); + + if (prev != null && next != null) { + // Nothing to do + } else if (prev == null) { + if (!tcp._getReversed()) + tcp.setReversed(true); + } else if (next == null) { + if (tcp._getReversed()) + tcp.setReversed(false); + } + + Vector3d dir = null; + if (!tcp._getReversed()) { + dir = prev; + } else { + dir = next; + dir.negate(); + } + if (dir == null) { + return Math.PI; // FIXME : argh + } + + Quat4d q = PipeControlPoint.getControlPointOrientationQuat(dir, tcp.getRotationAngle() != null ? tcp.getRotationAngle() : 0.0); + Vector3d v = new Vector3d(); + MathTools.rotate(q, MathTools.Y_AXIS,v); + tcp.setTurnAxis(v); + tcp.setWorldOrientation(q); + if (tcp.getTurnAngle() != null) + return tcp.getTurnAngle(); + return Math.PI; // FIXME : argh } - updateControlPointOrientation(tcp); - if (DEBUG) - System.out.println("PipingTools.updateTurnControlPointTurn " + dir1 + " " + dir2 + " " + turnAngle + " " + turnAxis); - return turnAngle; + + } public static List getControlPoints(PipeRun pipeRun) { @@ -1495,8 +1634,9 @@ public class PipingRules { PipeControlPoint pcp = pipeRun.getControlPoints().iterator().next(); while (pcp.getPrevious() != null) { PipeControlPoint prev = pcp.getPrevious(); - if (prev.getPipeRun() != pipeRun) - break; + if (prev.getPipeRun() != pipeRun && prev.getPipeRun() != null) { // bypass possible corruption + break; + } pcp = prev; } if (pcp.isDualSub()) { @@ -1513,7 +1653,63 @@ public class PipingRules { } public static void reverse(PipeRun pipeRun) { - List list = getControlPoints(pipeRun); + + while (true) { + List points = getControlPoints(pipeRun); + PipeControlPoint pcp = points.get(0); + if (pcp.isSizeChange() && pcp.getSubPoint().size() > 0) { + pipeRun = pcp.getPipeRun(); + } else { + break; + } + } + List all = new ArrayList(); + List> pcps = new ArrayList>(); + while (true) { + all.add(pipeRun); + List points = getControlPoints(pipeRun); + pcps.add(points); + PipeControlPoint pcp = points.get(points.size()-1); + if (pcp.getSubPoint().size() > 0) { + pipeRun = pcp.getSubPoint().get(0).getPipeRun(); + } else { + break; + } + } + for (int i = 0 ; i < all.size(); i++) { + List list = pcps.get(i); + _reverse(list); + } + for (int i = 0 ; i < all.size(); i++) { + boolean last = i == all.size() - 1; + List list = pcps.get(i); + + if (!last) { + List list2 = pcps.get(i+1); + PipeControlPoint prev = list.get(list.size()-1); + PipeControlPoint next = list2.get(0); + System.out.println(); + if (prev == next) { + // Reverse the component on the boundary. + InlineComponent ic = (InlineComponent)prev.getPipelineComponent(); + PipeRun r1 = ic.getPipeRun(); + PipeRun r2 = ic.getAlternativePipeRun(); + if (r1 == null || r2 == null) + throw new RuntimeException("Components on PipeRun changes should refer to bot PipeRuns"); + ic.deattach(); + r2.addChild(ic); + ic.setPipeRun(r2); + ic.setAlternativePipeRun(r1); + } else { + throw new RuntimeException("PipeRun changes should contain shared control points"); + } + + } + } + + } + + private static void _reverse(List list) { if (list.size() <= 1) return; // nothing to do. @@ -1528,21 +1724,25 @@ public class PipingRules { PipeControlPoint next = list.get(i+1); if (next.isDualInline()) next = next.getSubPoint().get(0); - current.setNext(null); + if (current.getNext() == next) + current.setNext(null); current.setPrevious(next); if (currentSub != null) { - currentSub.setNext(null); - currentSub.setPrevious(next); + if (currentSub.getNext() == next) + currentSub.setNext(null); + currentSub.setPrevious(next); } } else if (last) { PipeControlPoint prev = list.get(i-1); - current.setPrevious(null); + if (current.getPrevious() == prev) + current.setPrevious(null); current.setNext(prev); if (currentSub != null) { - currentSub.setPrevious(null); - currentSub.setNext(prev); + if (currentSub.getPrevious() == prev) + currentSub.setPrevious(null); + currentSub.setNext(prev); } } else { PipeControlPoint prev = list.get(i-1); @@ -1556,10 +1756,17 @@ public class PipingRules { if (currentSub != null) { currentSub.setPrevious(next); - currentSub.setNext(prev); + currentSub.setNext(prev); } } + //if (current.isTurn() && current.isFixed()) { + if (current.asFixedAngle()) { + current.setReversed(!current._getReversed()); + } + if (current.isInline() && current.isReverse()) { + current.setReversed(!current._getReversed()); + } } } @@ -1593,13 +1800,26 @@ public class PipingRules { return; Collection pcps = pipeRun.getControlPoints(); int count = 0; + //System.out.println("Validate " + pipeRun.getName()); for (PipeControlPoint pcp : pcps) { if (pcp.getParentPoint() == null || pcp.getParentPoint().getPipeRun() != pipeRun) count++; } List runPcps = getControlPoints(pipeRun); if (runPcps.size() != count) { - System.out.println("Run is not connected"); + System.out.println("Run " + pipeRun.getName() + " contains unconnected control points, found " + runPcps.size() + " connected, " + pcps.size() + " total."); + for (PipeControlPoint pcp : pcps) { + if (!runPcps.contains(pcp)) { + System.out.println("Unconnected " + pcp + " " + pcp.getPipelineComponent()); + } + } + } + for (PipeControlPoint pcp : pcps) { + if (pcp.getPipeRun() == null) { + System.out.println("PipeRun ref missing " + pcp + " " + pcp.getPipelineComponent()); + } + if (!pcp.isDirected() && pcp.getNext() == null && pcp.getPrevious() == null) + System.out.println("Orphan undirected " + pcp + " " + pcp.getPipelineComponent()); } for (PipeControlPoint pcp : pcps) { if (pcp.getParentPoint() == null) { @@ -1629,8 +1849,8 @@ public class PipingRules { } public static void splitVariableLengthComponent(PipelineComponent newComponent, InlineComponent splittingComponent, boolean assignPos) throws Exception{ - assert(!splittingComponent.getControlPoint().isFixed()); - assert(!(newComponent instanceof InlineComponent && !newComponent.getControlPoint().isFixed())); + assert(!splittingComponent.getControlPoint().isFixedLength()); + assert(!(newComponent instanceof InlineComponent && !newComponent.getControlPoint().isFixedLength())); PipeControlPoint newCP = newComponent.getControlPoint(); PipeControlPoint splittingCP = splittingComponent.getControlPoint(); PipeControlPoint nextCP = splittingCP.getNext(); @@ -1638,19 +1858,19 @@ public class PipingRules { /* there are many different cases to insert new component when it splits existing VariableLengthinlineComponent. - - 1. VariableLengthComponet is connected from both sides: - - insert new component between VariableLength component and component connected to it - - insert new VariableLengthComponent between inserted component and component selected in previous step + + 1. VariableLengthComponet is connected from both sides: + - insert new component between VariableLength component and component connected to it + - insert new VariableLengthComponent between inserted component and component selected in previous step 2. VariableLengthComponent is connected from one side - - Use previous case or: - - Insert new component to empty end - - Insert new VariableLength component to inserted components empty end - + - Use previous case or: + - Insert new component to empty end + - Insert new VariableLength component to inserted components empty end + 3. VariableLength is not connected to any component. - - Should not be possible, at least in current implementation. - - Could be done using second case + - Should not be possible, at least in current implementation. + - Could be done using second case */ @@ -1658,7 +1878,6 @@ public class PipingRules { // this should not be possible throw new RuntimeException("VariableLengthComponent " + splittingComponent + " is not connected to anything."); } - double reservedLength = splittingComponent.getControlPoint().getLength(); double newLength = newComponent.getControlPoint().getLength(); @@ -1694,21 +1913,20 @@ public class PipingRules { vn.interpolate(next, 0.5); - PipeControlPoint newVariableLengthCP = null;//insertStraight(pcp1, pcp2, pos, length); if (nextCP == null) { newCP.insert(splittingCP, Direction.NEXT); - newVariableLengthCP = insertStraight(newCP, Direction.NEXT, new Vector3d(vn), ln); + insertStraight(newCP, Direction.NEXT, new Vector3d(vn), ln); splittingCP.setWorldPosition(new Vector3d(vp)); // ControlPointTools.setWorldPosition(splittingCP, vp); // splittingCP.setRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength, lp); } else if (prevCP == null) { newCP.insert(splittingCP, Direction.PREVIOUS); - newVariableLengthCP = insertStraight(newCP, Direction.PREVIOUS, new Vector3d(vp), lp); + insertStraight(newCP, Direction.PREVIOUS, new Vector3d(vp), lp); splittingCP.setWorldPosition(new Vector3d(vn)); // splittingCP.setRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength, ln); } else { newCP.insert(splittingCP, nextCP); - newVariableLengthCP = insertStraight(newCP, nextCP, new Vector3d(vn), ln); + insertStraight(newCP, nextCP, new Vector3d(vn), ln); splittingCP.setWorldPosition(new Vector3d(vp)); // splittingCP.setRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength, lp); }