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=58873b0f1003d5f64156b3c16a42def1cb8cccd4;hb=a53efc63bed07331a3a2f9879f266e41cbe738cb;hp=b64a9e93cce04a303747931499753e76d002645b;hpb=aca223a1616159645710d7c9ee67ed1a6bd47b99;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 b64a9e93..58873b0f 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 @@ -117,6 +117,8 @@ public class PipingRules { allowInsertRemove = allowIR; triedIR = false; validate(pcp.getPipeRun()); + if (pcp.getParentPoint() != null) + pcp = pcp.getParentPoint(); if (pcp.asPathLegEnd()) { updatePathLegEndControlPoint(pcp); // FIXME: Rules won't work properly, if they are not run twice. //updatePathLegEndControlPoint(pcp); @@ -362,9 +364,12 @@ public class PipingRules { } @SuppressWarnings("unused") - private static boolean calculateOffset(Vector3d startPoint, Vector3d endPoint, ArrayList list, Vector3d dir, Vector3d offset) { + private static boolean calculateOffset(Vector3d startPoint, Vector3d endPoint, PipeControlPoint start, ArrayList list, PipeControlPoint end, Vector3d dir, Vector3d offset) { boolean hasOffsets = false; List offsets = new ArrayList(list.size()); + // Only start offset affects the calculation + if (start.isOffset()) + offsets.add(start); for (PipeControlPoint icp : list) { if (icp.isOffset()) { offsets.add(icp); @@ -441,7 +446,7 @@ public class PipingRules { Vector3d startPoint = start.getWorldPosition(); Vector3d endPoint = end.getWorldPosition(); Vector3d dir = new Vector3d(); - hasOffsets = calculateOffset(startPoint, endPoint, list, dir, offset); + hasOffsets = calculateOffset(startPoint, endPoint, start, list, end, dir, offset); return new UpdateStruct2(start, startPoint, list, end, endPoint, dir, offset, hasOffsets, iter, direction == Direction.PREVIOUS, toRemove, updated); } @@ -526,7 +531,13 @@ public class PipingRules { Vector3d ep = new Vector3d(end); ep.sub(u.offset); - + if (u.start.isOffset()) { + Vector3d offset = u.start.getSizeChangeOffsetVector(u.dir); + updateOffsetPoint(u.start, offset); + sp.add(offset); + ep.add(offset); + } + for (PipeControlPoint icp : u.list) { updateInlineControlPoint(icp, sp, ep, u.dir); if (icp.isOffset()) { @@ -937,7 +948,7 @@ public class PipingRules { // FIXME : extra loop (dir should be calculated here) Vector3d dir = new Vector3d(); Vector3d offset = new Vector3d(); - hasOffsets = calculateOffset(startPoint, endPoint, list, dir, offset); + hasOffsets = calculateOffset(startPoint, endPoint, start, list, end, dir, offset); ppNoOffset(new UpdateStruct2(start, startPoint, list, end, endPoint, dir, null, hasOffsets, iter, reversed, toRemove, updated)); } @@ -977,18 +988,15 @@ public class PipingRules { other = u.end; position = u.startPoint; dcpStart = true; - if (!u.reversed) - canMoveOther = true; inlineEnd = u.end.isInline(); } else { dcp = u.end; other = u.start; position = u.endPoint; - if (u.reversed) - canMoveOther = true; inlineEnd = u.start.isInline(); } + canMoveOther = !(other == u.updated); Vector3d directedDirection = direction(dcp, dcpStart ? Direction.NEXT : Direction.PREVIOUS); if (directedDirection == null) { @@ -1001,7 +1009,7 @@ public class PipingRules { } Point3d directedEndPoint = new Point3d(u.endPoint); if (u.hasOffsets) - directedEndPoint.add(u.offset); + directedEndPoint.sub(u.offset); double mu[] = new double[2]; @@ -1018,6 +1026,16 @@ public class PipingRules { double distance = t.length(); boolean aligned = (distance < ALLOWED_OFFSET); + double requiredSpace = 0.0; + if (other.isVariableAngle()) { + requiredSpace = spaceForTurn(other, dcp); + } + if (mu[0] < requiredSpace) { + // At the moment, if next component is directly behind the nozzle, we must force moving the other component. + // Trying to solve the situation by adding new turn creates infinite loop... + aligned = false; + canMoveOther = true; + } if (aligned) { if (u.start.isInline() || u.end.isInline() || u.start.asFixedAngle() || u.end.asFixedAngle()) processPathLeg(u, true, false); @@ -1041,15 +1059,14 @@ public class PipingRules { if (other.isVariableAngle()) { // TODO calculate needed space from next run end. - double space = spaceForTurn(other); - if (mu[0] < space) { + if (mu[0] < requiredSpace) { if (dcpStart) { closest.set(u.startPoint); } else { closest.set(u.endPoint); } Vector3d v = new Vector3d(directedDirection); - v.scale(space); + v.scale(requiredSpace); closest.add(v); } @@ -1225,11 +1242,54 @@ 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 double spaceForTurn(PipeControlPoint tcp, PipeControlPoint dcp) { + // TODO : if the path legs contain offset, using just positions of opposite path leg ends is not enough. + // TODO : current iterative way for calculating required space may return longer length that is required. + double tr = ((TurnComponent)tcp.getPipelineComponent()).getTurnRadius(); + if (dcp == null) + return tr; // space for 90 deg + PipeControlPoint ne = tcp.findNextEnd(); + PipeControlPoint pe = tcp.findPreviousEnd(); + PipeControlPoint other = null; + if (dcp == ne) + other = pe; + else if (dcp == pe) + other = ne; + else + return tr; // space for 90 deg + if (other == null) + return tr; // space for 90 deg + Vector3d dir = dcp.getDirectedControlPointDirection(); + Vector3d dp = dcp.getWorldPosition(); + Vector3d op = other.getWorldPosition(); + double u[] = new double[1]; + Vector3d closest = MathTools.closestPointOnStraight(op, dp, dir,u); + if (MathTools.distanceSquared(closest, op) <= MIN_INLINE_LENGTH) { + if (u[0] > -MIN_INLINE_LENGTH) + return 0.0; // point following turn is directly in the front of the nozzle. + else + return tr*2.0; // point following turn is directly behind the nozzle, in theory, we should return Double.Inf... + } + double curr = tr*0.1; + int iter = 10; + Vector3d v1 = new Vector3d(); + Vector3d v2 = new Vector3d(); + while (iter > 0) { + Vector3d tp = new Vector3d(dp); + MathTools.mad(tp, dir, curr); + v1.sub(tp, dp); // Vector from nozzle to turn + v2.sub(op,tp); // Vector from turn to other + double a = v1.angle(v2); + double t = Math.tan((Math.PI - a) * 0.5); + double R = 0.0; + if (t > MathTools.NEAR_ZERO) + R = tr / t; + if (R <= curr) + break; + curr = R*1.01; + iter--; + } + return curr; } private static void insertElbowUpdate(UpdateStruct2 u, PipeControlPoint dcp, PipeControlPoint next, boolean dcpStart, Vector3d position, Vector3d directedDirection) throws Exception{ @@ -1247,9 +1307,8 @@ public class PipingRules { 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); + double s = spaceForTurn(tcp,dcp); if (d < s) { d = s - d; Vector3d p = new Vector3d(directedDirection); @@ -1633,9 +1692,9 @@ public class PipingRules { private static void updateEndComponentControlPoint(PipeControlPoint ecp, Vector3d dir) throws Exception { if (DEBUG) System.out.println("PipingRules.updateEndComponentControlPoint() " + ecp); - //FIXME : end control point cannot be fixed! - //if (!ecp.isFixed()) - updateControlPointOrientation(ecp, dir); + + if (!ecp.isFixed()) // prevent overriding nozzle orientations.. + updateControlPointOrientation(ecp, dir); for (PipeControlPoint pcp : ecp.getChildPoints()) { // TODO update position @@ -1795,7 +1854,10 @@ public class PipingRules { List points = getControlPoints(pipeRun); PipeControlPoint pcp = points.get(0); if (pcp.isSizeChange() && pcp.getChildPoints().size() > 0) { - pipeRun = pcp.getPipeRun(); + PipeRun pr = pcp.getPipeRun(); + if (pr != pipeRun) + pipeRun = pr; + else break; } else { break; } @@ -1829,7 +1891,6 @@ public class PipingRules { 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();