updatePathLeg(new UpdateStruct2(start, startPoint, list, end, endPoint, dir, offset, hasOffsets, iter, reversed, toRemove, updated), lengthChange);
}
-
+
+ private static boolean asDirected(PipeControlPoint pcp, Direction direction) {
+ if (pcp.isDirected())
+ return true;
+ if (pcp.isTurn() && pcp.isFixed()) {
+ 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:
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.isFixed() || u.end.isFixed())
processPathLeg(u, true, false);
}
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) {
- 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);
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);
+ if (prev != null && next != null) {
+
recalcline = recalcline | updateVariableLength(icp, prev, next);
} else {
// 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.
}
}
} else { // with offset
- Vector3d sp = new Vector3d(u.startPoint);
- Vector3d ep = new Vector3d(u.endPoint);
+ Vector3d sp = new Vector3d(start);
+ Vector3d ep = new Vector3d(end);
ep.sub(u.offset);
ArrayList<PipeControlPoint> pathLegPoints = new ArrayList<PipeControlPoint>();
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);
+ if (prev != null && next != null) {
recalcline = recalcline | updateVariableLength(icp, prev, next);
} else {
// 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.
}
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;
- }
-
- 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));
+ Vector3d currentPos = icp.getWorldPosition();
+ Vector3d prevPos = prev.getWorldPosition();
+
+ Vector3d dir = new Vector3d();
+ dir.sub(currentPos, prevPos);
+
+ boolean simple = true;
+ if (simple) {
+ double currentLength = (dir.length() - prev.getInlineLength()) * 2.0;
+ icp.setLength(currentLength);
+ } else {
+ 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));
+ }
}
private static void ppNoOffset(UpdateStruct2 u) throws Exception {
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;
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());
+ 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);
double distance = t.length();
boolean aligned = (distance < ALLOWED_OFFSET);
if (aligned) {
+ if (u.start.isInline() || u.end.isInline() || u.start.isFixed() || u.end.isFixed())
+ processPathLeg(u, true, false);
checkExpandPathLeg(u, lengthChange, inlineEnd);
} else {
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));
}
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);
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);
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);
}
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);
+
+ if (!tcp.isFixed()) {
+ if (next == null || prev == null)
+ return tcp.getTurnAngle();
+ Vector3d middlePoint = tcp.getWorldPosition();
+ Vector3d nextPoint = next.getWorldPosition();
+ Vector3d prevPoint = prev.getWorldPosition();
+ return updateTurnControlPointTurn(tcp, middlePoint, prevPoint, nextPoint);
+ } else {
+ // Verify that fixed turn is properly defined.
+ // TODO : when reversed flag is changed, rotation angle should be recalculated, otherwise the orientation will change.
+ // TODO : should reverse flag toggle to be done already when we are removing defining side?
+ 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;
+ if (!tcp._getReversed()) {
+ if (prev == null)
+ return Math.PI; // FIXME : argh
+
+ Vector3d middlePoint = tcp.getWorldPosition();
+ Vector3d prevPoint = prev.getWorldPosition();
+ dir = new Vector3d();
+ dir.sub(middlePoint, prevPoint);
+
+ } else {
+ if (next == null)
+ return Math.PI; // FIXME : argh
+
+ Vector3d middlePoint = tcp.getWorldPosition();
+ Vector3d nextPoint = next.getWorldPosition();
+ dir = new Vector3d();
+ dir.sub(middlePoint, nextPoint);
+ }
+ dir.normalize();
+
+ 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);
+ return tcp.getTurnAngle();
+ }
}
/**
turnAngle = 0.0;
tcp.setTurnAngle(0.0);
tcp.setLength(0.0);
- tcp.setTurnAxis(MathTools.Y_AXIS);
+ tcp.setTurnAxis(new Vector3d(MathTools.Y_AXIS));
}
updateControlPointOrientation(tcp);
if (DEBUG)
}
}
+ if (current.isTurn() && current.isFixed()) {
+ current.setReversed(!current._getReversed());
+ }
+ if (current.isInline() && current.isReverse()) {
+ current.setReversed(!current._getReversed());
+ }
}
}
return;
Collection<PipeControlPoint> 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<PipeControlPoint> runPcps = getControlPoints(pipeRun);
if (runPcps.size() != count) {
- System.out.println("Run is not connected");
+ System.out.println("Run " + pipeRun.getName() + " contains unconnected control points");
}
for (PipeControlPoint pcp : pcps) {
if (!pcp.isDirected() && pcp.getNext() == null && pcp.getPrevious() == null)