if (!PipingRules.enabled)
return false;
- if (requestUpdates.size() == 0)
- return false;
-
- List<PipeControlPoint> temp = new ArrayList<PipeControlPoint>(requestUpdates.size());
- synchronized(updateMutex) {
+ List<PipeControlPoint> temp;
+ synchronized(updateMutex) {
+ if (requestUpdates.size() == 0)
+ return false;
+
+ temp = new ArrayList<PipeControlPoint>(requestUpdates.size());
temp.addAll(requestUpdates);
requestUpdates.clear();
}
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);
public static void setEnabled(boolean enabled) {
PipingRules.enabled = enabled;
- if(!enabled)
- currentUpdates.clear();
+ if(!enabled) {
+ synchronized (ruleMutex) {
+ currentUpdates.clear();
+ }
+ }
}
public static boolean isEnabled() {
System.out.println("PipingRules.updateInlineControlPoint() " + pcp);
PipeControlPoint start = pcp.findPreviousEnd();
updatePathLegNext(start, pcp, PathLegUpdateType.NONE);
+
+ if (pcp.isOffset()) {
+ // Adjusting the rotation angle of an offset component may change variable angle turns
+ PipeControlPoint end = pcp.findNextEnd();
+ if (end.isVariableAngle()) {
+ updatePathLegNext(end, end, PathLegUpdateType.NONE);
+ }
+ if (start.isVariableAngle()) {
+ updatePathLegPrev(start, start, PathLegUpdateType.NONE);
+ }
+ }
}
private static PipeControlPoint insertElbow(PipeControlPoint pcp1, PipeControlPoint pcp2, Vector3d pos) throws Exception{
scp.insert(pcp1, pcp2);
scp.setWorldPosition(pos);
+ Vector3d dir = new Vector3d();
+ dir.sub(pcp2.getWorldPosition(), pcp1.getWorldPosition());
+ scp.orientToDirection(dir);
scp.setLength(length);
validate(scp.getPipeRun());
return scp;
}
- @SuppressWarnings("unused")
- private static boolean calculateOffset(Vector3d startPoint, Vector3d endPoint, ArrayList<PipeControlPoint> list, Vector3d dir, Vector3d offset) {
- boolean hasOffsets = false;
- List<PipeControlPoint> offsets = new ArrayList<PipeControlPoint>(list.size());
- for (PipeControlPoint icp : list) {
- if (icp.isOffset()) {
- offsets.add(icp);
- } else if (icp.isDualSub())
- ErrorLogger.defaultLogError("Updating pipe run, found offset controlpoint " + icp, new Exception("ASSERT!"));
- }
+ /**
+ * Calculate offset based on a given fixed component direction.
+ *
+ * The desired component direction is provided as an input to this method,
+ * unlike the direction vector that is calculated by calculateOffset.
+ *
+ * The returned offset vector is always perpendicular to the given direction
+ * vector.
+ *
+ * @param startPoint Start point of leg
+ * @param endPoint End point of leg
+ * @param start Starting component of leg
+ * @param list Inline components between start and end
+ * @param end Ending component of leg
+ * @param dir Direction at which the offset is calculated
+ * @param offset A vector object to receive the offset vector values
+ * @return True if offsets are present
+ */
+ public static boolean calculateDirectedOffset(Vector3d startPoint, Vector3d endPoint, PipeControlPoint start, ArrayList<PipeControlPoint> list, PipeControlPoint end, Vector3d dir, Vector3d offset) {
+ return calculateOffset(startPoint, endPoint, start, list, end, dir, offset, true);
+ }
+
+ /**
+ * Calculate offset and direction vectors for a path leg so that the given chain
+ * of components starts and ends at the given coordinates
+ *
+ * The returned direction and offset vectors are perpendicular to each other.
+ *
+ * @param startPoint Start point of the leg
+ * @param endPoint End point of the leg
+ * @param start Starting component of the leg
+ * @param list Inline components between start and end
+ * @param end Ending component of the leg
+ * @param dir A vector object to receive the component direction vector
+ * @param offset A vector object to receive the offset vector
+ * @return True if offsets are present
+ */
+ public static boolean calculateOffset(Vector3d startPoint, Vector3d endPoint, PipeControlPoint start, ArrayList<PipeControlPoint> list, PipeControlPoint end, Vector3d dir, Vector3d offset) {
+ return calculateOffset(startPoint, endPoint, start, list, end, dir, offset, false);
+ }
+
+ private static boolean calculateOffset(Vector3d startPoint, Vector3d endPoint, PipeControlPoint start, ArrayList<PipeControlPoint> list, PipeControlPoint end, Vector3d dir, Vector3d offset, boolean directed) {
+ List<PipeControlPoint> offsets = getOffsetPoints(start, list);
if (offsets.size() == 0) {
- dir.set(endPoint);
- dir.sub(startPoint);
- double l = dir.lengthSquared();
- if (l > MathTools.NEAR_ZERO)
- dir.scale(1.0/Math.sqrt(l));
- offset.set(0.0, 0.0, 0.0);
+ setZeroOffset(startPoint, endPoint, dir, offset);
return false;
} else {
Vector3d sp = new Vector3d(startPoint);
Point3d ep = new Point3d(endPoint);
- dir.set(ep);
- dir.sub(sp);
+ if (!directed) {
+ dir.set(ep);
+ dir.sub(sp);
+ }
+
double l = dir.lengthSquared();
if (l > MathTools.NEAR_ZERO)
dir.scale(1.0/Math.sqrt(l));
+
int iter = 100;
- while (iter >= 0) {
+ while (true) {
iter--;
offset.set(0.0, 0.0, 0.0);
Vector3d v = icp.getSizeChangeOffsetVector(dir);
offset.add(v);
}
+
+ if (directed)
+ break;
+
Point3d nep = new Point3d(endPoint);
nep.sub(offset);
- if (nep.distance(ep) < 0.0000000001) {
+ if (nep.distance(ep) < 0.0000000001 || iter <= 0) {
break;
- }
+ }
+
ep = nep;
dir.set(ep);
dir.sub(sp);
if (l > MathTools.NEAR_ZERO)
dir.scale(1.0/Math.sqrt(l));
}
- hasOffsets = true;
+
+ if (DEBUG)
+ System.out.println("calcOffset s:"+ startPoint + " e:" + endPoint + " d:" + dir + " o:"+offset) ;
+
+ return true;
}
-
- if (DEBUG && hasOffsets)
- System.out.println("calcOffset s:"+ startPoint + " e:" + endPoint + " d:" + dir + " o:"+offset) ;
- return hasOffsets;
}
+ public static void setZeroOffset(Vector3d startPoint, Vector3d endPoint, Vector3d dir, Vector3d offset) {
+ dir.set(endPoint);
+ dir.sub(startPoint);
+ double l = dir.lengthSquared();
+ if (l > MathTools.NEAR_ZERO)
+ dir.scale(1.0/Math.sqrt(l));
+ offset.set(0.0, 0.0, 0.0);
+ }
+
+ public static List<PipeControlPoint> getOffsetPoints(PipeControlPoint start, ArrayList<PipeControlPoint> list) {
+ List<PipeControlPoint> offsets = new ArrayList<PipeControlPoint>(list.size());
+ // Only start offset affects the calculation
+ if (start.isOffset())
+ offsets.add(start);
+ for (PipeControlPoint icp : list) {
+ if (icp.isOffset()) {
+ offsets.add(icp);
+ } else if (icp.isDualSub())
+ ErrorLogger.defaultLogError("Updating pipe run, found offset controlpoint " + icp, new Exception("ASSERT!"));
+ }
+ return offsets;
+ }
+
private static UpdateStruct2 createUS(PipeControlPoint start, Direction direction, int iter, ArrayList<ExpandIterInfo> toRemove, PipeControlPoint updated) {
ArrayList<PipeControlPoint> list = new ArrayList<PipeControlPoint>();
PipeControlPoint end = null;
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);
}
+ private static Vector3d pathLegDirection(PipeControlPoint start) {
+ ArrayList<PipeControlPoint> list = new ArrayList<PipeControlPoint>();
+ PipeControlPoint end = start.findNextEnd(list);
+ if (start == end) {
+ return start.getDirection(Direction.NEXT);
+ }
+
+ Vector3d offset = new Vector3d();
+ Vector3d startPoint = start.getWorldPosition();
+ Vector3d endPoint = end.getWorldPosition();
+ Vector3d dir = new Vector3d();
+ calculateOffset(startPoint, endPoint, start, list, end, dir, offset);
+ return dir;
+ }
+
private static boolean asDirected(PipeControlPoint pcp, Direction direction) {
if (pcp.isDirected())
return true;
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()) {
continue;
double curr = gapObj.d;
int d = 1;
- while (curr < -MIN_INLINE_LENGTH) {
- GapObj next = i+d >= 0 ? gaps.get(i+d) : null;
+ while (d < gaps.size() && curr < -MIN_INLINE_LENGTH) {
+ GapObj next = i+d < gaps.size() ? gaps.get(i+d) : null;
GapObj prev = i-d >= 0 ? gaps.get(i-d) : null;
if (next != null && next.gap == Gap.SPACE) {
double move = Math.min(-curr, next.d);
pcp.first.setWorldPosition(p);
}
}
- if (curr < -MIN_INLINE_LENGTH && prev != null && prev.gap == Gap.SPACE) {
+ else if (prev != null && prev.gap == Gap.SPACE) {
double move = Math.min(-curr, prev.d);
curr+= move;
- next.d -= move;
- if (next.d < MIN_INLINE_LENGTH)
- next.gap = Gap.ATTACHED;
+ prev.d -= move;
+ if (prev.d < MIN_INLINE_LENGTH)
+ prev.gap = Gap.ATTACHED;
Vector3d mv = new Vector3d(dir);
mv.normalize();
mv.scale(-move);
pcp.first.setWorldPosition(p);
}
}
+ else {
+ d++;
+ }
}
}
} else {
double l2next = icp.getInlineLength();
double l2 = l2prev + l2next;
double l2s = l2 * l2;
- if (l > l2s) {
+ double diff = l - l2s;
+ if (diff >= MIN_INLINE_LENGTH) {
if (allowInsertRemove) {
dir.normalize();
double length = Math.sqrt(l) - l2; // true length of the variable length component
Vector3d dir = new Vector3d();
dir.sub(currentPos, prevPos);
- boolean simple = currentUpdates.contains(icp);
+ boolean simple;
+ synchronized (ruleMutex) {
+ simple = currentUpdates.contains(icp);
+ }
+
if (simple) {
// Update based on position -> adjust length
double currentLength = (dir.length() - prev.getInlineLength()) * 2.0;
}
}
- private static void ppNoOffset(UpdateStruct2 u) throws Exception {
+ /**
+ * Recalculates offset vector based on current direction, and calls checkExpandPathLeg
+ * @param u
+ * @param updateEnds
+ * @throws Exception
+ */
+ private static void ppNoOffset(UpdateStruct2 u, boolean updateEnds) throws Exception {
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.isOffset()) {
offset.add(icp.getSizeChangeOffsetVector(u.dir));
}
}
u.offset = offset;
- checkExpandPathLeg(u, PathLegUpdateType.NONE);
+ checkExpandPathLeg(u, PathLegUpdateType.NONE, updateEnds);
}
private static void ppNoDir(PipeControlPoint start, Vector3d startPoint, ArrayList<PipeControlPoint> list, PipeControlPoint end, Vector3d endPoint, boolean hasOffsets, int iter, boolean reversed, ArrayList<ExpandIterInfo> toRemove, PipeControlPoint updated) throws Exception {
// 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));
+ hasOffsets = calculateOffset(startPoint, endPoint, start, list, end, dir, offset);
+ ppNoOffset(new UpdateStruct2(start, startPoint, list, end, endPoint, dir, null, hasOffsets, iter, reversed, toRemove, updated),true);
}
private static void checkExpandPathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange) throws Exception {
position = u.startPoint;
dcpStart = true;
if (!u.reversed)
- canMoveOther = true;
+ canMoveOther = true;
inlineEnd = u.end.isInline();
} else {
other = u.start;
position = u.endPoint;
if (u.reversed)
- canMoveOther = true;
+ canMoveOther = true;
inlineEnd = u.start.isInline();
}
-
+
Vector3d directedDirection = direction(dcp, dcpStart ? Direction.NEXT : Direction.PREVIOUS);
if (directedDirection == null) {
//updateTurnControlPointTurn(dcp, dcp.getPrevious(), dcp.getNext());
return;
}
}
- Point3d directedEndPoint = new Point3d(u.endPoint);
- if (u.hasOffsets)
- directedEndPoint.add(u.offset);
+
+ Point3d otherPosition = new Point3d(dcpStart ? u.endPoint : u.startPoint);
+ if (u.hasOffsets) {
+ Vector3d dir = dcp.getDirection(dcpStart ? Direction.NEXT : Direction.PREVIOUS);
+ if (!dcpStart)
+ dir.negate();
+
+ Vector3d offset = new Vector3d();
+ calculateDirectedOffset(u.startPoint, u.endPoint, u.start, u.list, u.end, dir, offset);
+ u.dir = dir;
+ u.offset = offset;
+
+ if (dcpStart)
+ otherPosition.sub(offset);
+ else
+ otherPosition.add(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);
- }
+ closest = MathTools.closestPointOnStraight(otherPosition, position, directedDirection, mu);
+ t.sub(closest, otherPosition);
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);
- checkExpandPathLeg(u, lengthChange, inlineEnd);
-
+ //if (u.start.isInline() || u.end.isInline() || u.start.asFixedAngle() || u.end.asFixedAngle())
+ // processPathLeg(u, true, false);
+ checkExpandPathLeg(u, lengthChange, inlineEnd || u.start.isInline() || u.end.isInline() || u.start.asFixedAngle() || u.end.asFixedAngle());
} else {
if (u.iter > 0) {
backIter(u);
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);
}
if (canMoveOther) {
if (DEBUG)
System.out.println("PipingRules.updateDirectedPipeRun() moved end " + other + " to " + closest);
+
+ // Not aligned - we need to recalculate the offset to reflect new end points.
+ Vector3d offset;
+ if (u.hasOffsets) {
+ offset = new Vector3d();
+ Vector3d newDir = new Vector3d();
+ calculateDirectedOffset(position, closest, u.start, u.list, u.end, newDir, offset);
+ closest.add(offset);
+ } else {
+ offset = new Vector3d();
+ }
+
other.setWorldPosition(closest);
+
if (dcpStart) {
- ppNoOffset(new UpdateStruct2(u.start, u.startPoint, u.list, u.end, new Vector3d(closest), directedDirection, null, u.hasOffsets, u.iter, u.reversed, u.toRemove, u.updated));
+ checkExpandPathLeg(new UpdateStruct2(u.start, u.startPoint, u.list, u.end, new Vector3d(closest), directedDirection, offset, u.hasOffsets, u.iter, u.reversed, u.toRemove, u.updated), PathLegUpdateType.NONE, true);
if (u.end.getNext() != null)
updatePathLegNext(u.end, u.updated, PathLegUpdateType.NEXT);
} else {
- ppNoOffset(new UpdateStruct2(u.start, new Vector3d(closest), u.list, u.end, u.endPoint, directedDirection, null, u.hasOffsets, u.iter, u.reversed, u.toRemove, u.updated));
+ checkExpandPathLeg(new UpdateStruct2(u.start, new Vector3d(closest), u.list, u.end, u.endPoint, directedDirection, offset, u.hasOffsets, u.iter, u.reversed, u.toRemove, u.updated), PathLegUpdateType.NONE, true);
if (u.start.getPrevious() != null)
updatePathLegPrev(u.start, u.updated, PathLegUpdateType.PREV);
}
// TODO : calculate needed space from next run end.
if (allowInsertRemove)
insertElbowUpdate(u, dcp, nextToMoved, dcpStart, position, directedDirection);
-
else
triedIR = true;
}
}
}
}
-
-
}
private static void updateDualDirectedPathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange) throws Exception {
PipeControlPoint dcp2 = u.end;
Point3d position1 = new Point3d(u.startPoint);
Point3d position2 = new Point3d(u.endPoint);
+
+ Vector3d dir = u.start.getDirection(Direction.NEXT), offset = new Vector3d();
+ calculateDirectedOffset(new Vector3d(position1), new Vector3d(position2), u.start, u.list, u.end, dir, offset);
+
Point3d position1offset = new Point3d(position1);
- position1offset.sub(u.offset);
+ position1offset.add(offset);
Point3d position2offset = new Point3d(position2);
- position2offset.add(u.offset);
+ position2offset.sub(offset);
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);
+
+ Vector3d p1 = MathTools.closestPointOnStraight(position1, position2offset, dir2);
+ Vector3d p2 = MathTools.closestPointOnStraight(position2, position1offset, dir1);
double d1 = position1.distance(new Point3d(p1));
double d2 = position2.distance(new Point3d(p2));
p1.add(v);
if (!u.reversed)
- p2 = MathTools.closestPointOnStraight(new Point3d(p1), position2, dir2);
+ p2 = MathTools.closestPointOnStraight(new Point3d(p1), position2offset, dir2);
else
- p2 = MathTools.closestPointOnStraight(new Point3d(p1), position1, dir1);
+ p2 = MathTools.closestPointOnStraight(new Point3d(p1), position1offset, 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)
}
- 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 dir2;
+ if (other == ne) {
+ dir2 = pathLegDirection(tcp);
+ } else {
+ dir2 = pathLegDirection(pe);
+ dir2.negate();
+ }
+
+ double d = dir.dot(dir2);
+ if (d > 0.9999)
+ return 0.0; // point following turn is directly in the front of the nozzle.
+ else if (d < -0.9999)
+ return tr*2.0; // point following turn is directly behind the nozzle, in theory, we should return Double.Inf...
+
+ double curr = 0.0;
+ int iter = 10;
+ Vector3d tp0 = tcp.getPosition();
+ try {
+ Vector3d dp = dcp.getWorldPosition();
+ while (iter > 0) {
+ Vector3d tp = new Vector3d(dir);
+ tp.scaleAdd(curr, dp);
+ tcp._setPosition(tp); // no firing of listeners here
+ if (other == ne) {
+ dir2 = pathLegDirection(tcp);
+ } else {
+ dir2 = pathLegDirection(pe);
+ dir2.negate();
+ }
+
+ double a = dir.angle(dir2);
+
+ // other is directly between dcp and tcp, a zero angle turn should do
+ if (Math.PI - a <= MathTools.NEAR_ZERO)
+ return 0.0;
+
+ double R = tr * Math.tan(a * 0.5);
+ if (R <= curr)
+ break;
+ curr = R*1.001;
+ iter--;
+ }
+ }
+ finally {
+ tcp._setPosition(tp0); // return the original value
+ }
+ return curr;
}
private static void insertElbowUpdate(UpdateStruct2 u, PipeControlPoint dcp, PipeControlPoint next, boolean dcpStart, Vector3d position, Vector3d directedDirection) throws Exception{
// closest.add(directedDirection);
PipeControlPoint tcp = null;
- Vector3d closest;
+ Vector3d closest = new Vector3d(directedDirection);
+ closest.scaleAdd(dcp.getPipeRun().getTurnRadius(), position);
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;
- }
-
+ double s = spaceForTurn(tcp,dcp);
+ Vector3d p = new Vector3d(directedDirection);
+ p.scaleAdd(s, position);
+ tcp.setPosition(p);
+ closest = p;
if (DEBUG)
System.out.println("PipingRules.updateDirectedPipeRun() inserted " + tcp);
} else if (u.start.isEnd()) {
updateEndComponentControlPoint(u.start, u.dir);
} else if (u.start.isInline()) {
- updateControlPointOrientation(u.start, u.dir);
+ u.start.orientToDirection(u.dir);
}
if (u.end.isTurn()) {
//updateTurnControlPointTurn(u.end, u.end.getPrevious(), u.end.getNext());
} else if (u.end.isEnd()) {
updateEndComponentControlPoint(u.end, u.dir);
} else if (u.end.isInline()) {
- updateControlPointOrientation(u.end, u.dir);
+ u.end.orientToDirection(u.dir);
}
} else {
System.out.println(" " + newInlinePoint);
icp.setWorldPosition(newInlinePoint);
- updateControlPointOrientation(icp, dir);
+ icp.orientToDirection(dir);
}
/**
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..
+ ecp.orientToDirection(dir);
for (PipeControlPoint pcp : ecp.getChildPoints()) {
// TODO update position
}
}
- private static void updateControlPointOrientation(PipeControlPoint pcp, Vector3d dir) {
- Double angleO = pcp.getRotationAngle();
- double angle = 0.0;
- if (angleO != null)
- angle = angleO;
- boolean reversed = pcp._getReversed();
- Quat4d q = null;
- if (dir != null) {
- q = pcp.getControlPointOrientationQuat(dir, angle, reversed);
- } else {
- q = pcp.getControlPointOrientationQuat(angle, reversed);
- }
- pcp.setWorldOrientation(q);
- }
-
/**
* Updates all branches when branch's position has been changed
*
return tcp.getTurnAngle();
return Math.PI; // FIXME : argh
}
- double turnAngle = prev.angle(next);
-
- double angle = Math.PI - turnAngle;
+
+ final boolean isDegenerate = prev.lengthSquared() < MathTools.NEAR_ZERO || next.lengthSquared() < MathTools.NEAR_ZERO;
+ double turnAngle = isDegenerate ? 0.0 : prev.angle(next);
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);
+ double R = elbowRadius * Math.tan(turnAngle * 0.5);
turnAxis.normalize();
tcp.setTurnAngle(turnAngle);
tcp.setTurnAxis(new Vector3d(MathTools.Y_AXIS));
}
- updateControlPointOrientation(tcp,prev);
+ tcp.orientToDirection(prev);
if (DEBUG)
System.out.println("PipingTools.updateTurnControlPointTurn " + prev + " " + next + " " + turnAngle + " " + turnAxis);
return Math.PI; // FIXME : argh
}
- Quat4d q = PipeControlPoint.getControlPointOrientationQuat(dir, tcp.getRotationAngle() != null ? tcp.getRotationAngle() : 0.0);
+ Quat4d q = tcp.getControlPointOrientationQuat(dir, tcp.getRotationAngle() != null ? tcp.getRotationAngle() : 0.0);
Vector3d v = new Vector3d();
MathTools.rotate(q, MathTools.Y_AXIS,v);
tcp.setTurnAxis(v);
List<PipeControlPoint> 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;
}
List<PipeControlPoint> 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();
public static void validate(PipeRun pipeRun) {
if (pipeRun == null)
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 " + pipeRun.getName() + " contains unconnected control points, found " + runPcps.size() + " connected, " + pcps.size() + " total.");
+ synchronized (ruleMutex) {
+ Collection<PipeControlPoint> pcps = pipeRun.getControlPoints();
+ int count = 0;
+ //System.out.println("Validate " + pipeRun.getName());
for (PipeControlPoint pcp : pcps) {
- if (!runPcps.contains(pcp)) {
- System.out.println("Unconnected " + pcp + " " + pcp.getPipelineComponent());
- }
+ if (pcp.getParentPoint() == null || pcp.getParentPoint().getPipeRun() != pipeRun)
+ count++;
}
- }
- 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) {
- PipeControlPoint sub = null;
- if (pcp.isDualInline())
- sub = pcp.getDualSub();
- PipeControlPoint next = pcp.getNext();
- PipeControlPoint prev = pcp.getPrevious();
- if (next != null) {
- if (!(next.getPrevious() == pcp || next.getPrevious() == sub)) {
- System.out.println("Inconsistency between " + pcp + " -> " +next );
- }
+ List<PipeControlPoint> runPcps = getControlPoints(pipeRun);
+ if (runPcps.size() != count) {
+ 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());
+ }
}
- if (prev != null) {
- PipeControlPoint prevParent = null;
- if (prev.isDualSub()) {
- prevParent = prev.getParentPoint();
- } else if (prev.isDualInline()) {
- System.out.println("Inconsistency between " + pcp + " <-- " +prev );
+ }
+ 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) {
+ PipeControlPoint sub = null;
+ if (pcp.isDualInline())
+ sub = pcp.getDualSub();
+ PipeControlPoint next = pcp.getNext();
+ PipeControlPoint prev = pcp.getPrevious();
+ if (next != null) {
+ if (!(next.getPrevious() == pcp || next.getPrevious() == sub)) {
+ System.out.println("Inconsistency between " + pcp + " -> " +next );
+ }
}
- if (!(prev.getNext() == pcp && (prevParent == null || prevParent.getNext() == pcp))) {
- System.out.println("Inconsistency between " + pcp + " <-- " +prev );
+ if (prev != null) {
+ PipeControlPoint prevParent = null;
+ if (prev.isDualSub()) {
+ prevParent = prev.getParentPoint();
+ } else if (prev.isDualInline()) {
+ System.out.println("Inconsistency between " + pcp + " <-- " +prev );
+ }
+ if (!(prev.getNext() == pcp && (prevParent == null || prevParent.getNext() == pcp))) {
+ System.out.println("Inconsistency between " + pcp + " <-- " +prev );
+ }
}
}
}