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
triedIR = false;
validate(pcp.getPipeRun());
if (pcp.isPathLegEnd()) {
- updatePathLegEndControlPoint(pcp); // FXIME: Rules won't work properly, if they are not run twice.
- //updatePathLegEndControlPoint(pcp);
+ updatePathLegEndControlPoint(pcp); // FIXME: Rules won't work properly, if they are not run twice.
+ updatePathLegEndControlPoint(pcp);
} else {
updateInlineControlPoint(pcp);
- //updateInlineControlPoint(pcp);
+ updateInlineControlPoint(pcp);
}
validate(pcp.getPipeRun());
if (!allowInsertRemove)
ArrayList<PipeControlPoint> list = new ArrayList<PipeControlPoint>();
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;
+ if (lengthChange == PathLegUpdateType.NONE) {
+ 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<PipeControlPoint> list, PipeControlPoint end, PipeControlPoint updated, PathLegUpdateType lengthChange) throws Exception {
updatePathLeg(start, list, end, false, 0, new ArrayList<ExpandIterInfo>(), updated, lengthChange);
}
+
+ private static void updatePathLegPrev(PipeControlPoint start, PipeControlPoint updated, PathLegUpdateType lengthChange) throws Exception {
+ ArrayList<PipeControlPoint> list = new ArrayList<PipeControlPoint>();
+ PipeControlPoint end = start.findPreviousEnd(list);
+ // TODO: this method is not symmetric with updatePathLegNext, which may alter lengthChange parameter?
+ updatePathLegPrev(start, list, end, updated, lengthChange);
+ }
+
+ private static void updatePathLegPrev(PipeControlPoint start, ArrayList<PipeControlPoint> list, PipeControlPoint end, PipeControlPoint updated, PathLegUpdateType lengthChange) throws Exception {
+ // reverses the list
+ ArrayList<PipeControlPoint> nextList = new ArrayList<PipeControlPoint>();
+ 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<ExpandIterInfo>(), updated, lengthChange);
+
+ }
private static class UpdateStruct2 {
public PipeControlPoint start;
System.out.println("PipingRules.updateInlineControlPoints() " + u);
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);
- }
+
+ Vector3d start = new Vector3d(u.startPoint);
+ Vector3d end = new Vector3d(u.endPoint);
+ // create offsets.
+ MathTools.mad(start, u.dir, u.start.getInlineLength());
+ MathTools.mad(end, u.dir, -u.end.getInlineLength());
+ 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<PipeControlPoint> pathLegPoints = new ArrayList<PipeControlPoint>();
pathLegPoints.add(u.start);
}
}
}
- } else {
+ } else { // with offset
Vector3d sp = new Vector3d(u.startPoint);
Vector3d ep = new Vector3d(u.endPoint);
ep.sub(u.offset);
} else {
// components leave no space to the component and it
// must be removed
- if (icp.isDeletable())
+
+ if (icp.isDeletable()) {
+ if (DEBUG)
+ System.out.println("PipingRules.updateVariableLength removing " + icp);
icp._remove();
+ }
}
}
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) {
checkExpandPathLeg(u, lengthChange, inlineEnd);
} else {
closest.set(u.endPoint);
}
- closest.add(directedDirection);
+ Vector3d v = new Vector3d(directedDirection);
+ v.scale(spaceForTurn(other));
+ closest.add(v);
}
if (canMoveOther) {
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 {
}
}
+
+ 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 tcp.getPipeRun().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);
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();
}
}
ocp.setWorldPosition(world);
}
- private static void updatePathLegPrev(PipeControlPoint start, PipeControlPoint updated, PathLegUpdateType lengthChange) throws Exception {
- ArrayList<PipeControlPoint> list = new ArrayList<PipeControlPoint>();
- PipeControlPoint end = start.findPreviousEnd(list);
- updatePathLegPrev(start, list, end, updated, lengthChange);
- }
-
- private static void updatePathLegPrev(PipeControlPoint start, ArrayList<PipeControlPoint> list, PipeControlPoint end, PipeControlPoint updated, PathLegUpdateType lengthChange) throws Exception {
- // reverses the list
- ArrayList<PipeControlPoint> nextList = new ArrayList<PipeControlPoint>();
- 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<ExpandIterInfo>(), updated, lengthChange);
-
- }
-
/**
* Updates InlineControlPoints position when straight pipe's end(s) have
* been changed)
* @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);