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());
+ updateControlPointOrientation(scp, dir);
scp.setLength(length);
validate(scp.getPipeRun());
return scp;
dir.scale(1.0/Math.sqrt(l));
int iter = 100;
- while (iter >= 0) {
+ while (true) {
iter--;
offset.set(0.0, 0.0, 0.0);
Point3d nep = new Point3d(endPoint);
nep.sub(offset);
- if (nep.distance(ep) < 0.0000000001) {
+ if (nep.distance(ep) < 0.0000000001 || iter <= 0) {
break;
}
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 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;
return;
}
}
- Point3d directedEndPoint = new Point3d(u.endPoint);
- if (u.hasOffsets)
- directedEndPoint.sub(u.offset);
+
+ Point3d otherPosition = new Point3d(dcpStart ? u.endPoint : u.startPoint);
+ if (u.hasOffsets) {
+ Vector3d dir = new 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.add(offset);
+ else
+ otherPosition.sub(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);
// 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 = new Vector3d(), 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)
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...
+ 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 = 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.001;
- iter--;
+ Vector3d tp0 = tcp.getPosition();
+ try {
+ Vector3d dp = dcp.getWorldPosition();
+ while (iter > 0) {
+ Vector3d tp = new Vector3d(dir);
+ tp.scaleAdd(curr, dp);
+ tcp.setPosition(tp);
+ if (other == ne) {
+ dir2 = pathLegDirection(tcp);
+ } else {
+ dir2 = pathLegDirection(pe);
+ dir2.negate();
+ }
+
+ double a = dir.angle(dir2);
+ double t = Math.tan(a * 0.5);
+ double R = 0.0;
+ if (t > MathTools.NEAR_ZERO)
+ R = tr * t;
+ if (R <= curr)
+ break;
+ curr = R*1.001;
+ iter--;
+ }
+ }
+ finally {
+ tcp.setPosition(tp0);
}
return curr;
}
// 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);
}
- double d = MathTools.distance(position, closest);
- double s = spaceForTurn(tcp,dcp);
- 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);
}
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);
+ double R = elbowRadius * Math.tan(turnAngle * 0.5);
turnAxis.normalize();
tcp.setTurnAngle(turnAngle);
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);