+ if (recalcline) {
+ u.list.clear();
+ u.start.findNextEnd(u.list);
+ }
+ if (checkSizes) {
+ double pathLegLength = MathTools.distance(u.startPoint, u.endPoint);
+ double availableLength = pathLegLength;
+ if (u.start.isTurn())
+ availableLength -= u.start.getInlineLength();
+ if (u.end.isTurn())
+ availableLength -= u.end.getInlineLength();
+ for (PipeControlPoint pcp : u.list) {
+ if (!pcp.isVariableLength())
+ availableLength-= pcp.getLength();
+ }
+ if (availableLength < 0.0) {
+ u.start.getPipelineComponent().setError("Not enough available space");
+ u.end.getPipelineComponent().setError("Not enough available space");
+ for (PipeControlPoint pcp : u.list)
+ pcp.getPipelineComponent().setError("Not enough available space");
+ }
+// System.out.println(u.start.getPipelineComponent().toString() + " " + pathLegLength + " " + availableLength + " " + u.end.getPipelineComponent().toString() + " " + u.start.getInlineLength() + " " + u.end.getInlineLength());
+ }
+ }
+
+ private static void updateFixedLength(PipeControlPoint icp, PipeControlPoint prev, PipeControlPoint next, Vector3d s, Vector3d e, Vector3d dir) {
+ if (prev != null) {
+ checkOverlap(icp, prev);
+ }
+ if (next != null)
+ checkOverlap(icp, next);
+ }
+
+ private static void checkOverlap(PipeControlPoint icp, PipeControlPoint prev) {
+ double d = MathTools.distance(prev.getWorldPosition(), icp.getWorldPosition());
+ double r = icp.getInlineLength() + prev.getInlineLength();
+ if (d < r) {
+ if (icp.getPipelineComponent().getError() == null)
+ icp.getPipelineComponent().setError("Overlapping");
+ if (prev.getPipelineComponent().getError() == null)
+ prev.getPipelineComponent().setError("Overlapping");
+ }
+ }
+
+ private static boolean updateVariableLength(PipeControlPoint icp, PipeControlPoint prev, PipeControlPoint next) {
+ Vector3d prevPos = prev.getWorldPosition();
+ Vector3d nextPos = next.getWorldPosition();
+
+ Vector3d dir = new Vector3d(nextPos);
+ dir.sub(prevPos);
+ double l = dir.length(); // distance between control points
+ double l2prev = prev.getInlineLength(); // distance taken by components
+ double l2next = next.getInlineLength();
+ double l2 = l2prev + l2next;
+ double length = l - l2; // true length of the variable length component
+ if (length >= MIN_INLINE_LENGTH) { // check if there is enough space for variable length component.
+ // components fit
+ dir.normalize();
+ dir.scale(length * 0.5 + l2prev); // calculate center position of the component
+ dir.add(prevPos);
+ icp.setWorldPosition(dir);
+ icp.setLength(length);
+ return false;
+ } else {
+ // components leave no space to the component and it must be removed
+ if (icp.isDeletable()) {
+ if (!allowInsertRemove) {
+ icp.setLength(MIN_INLINE_LENGTH);
+ icp.getPipelineComponent().setError("Not enough available space");
+ triedIR = true;
+ return false;
+ }
+ if (DEBUG)
+ System.out.println("PipingRules.updateVariableLength removing " + icp);
+ icp._remove();
+ return true;
+ } else {
+ icp.setLength(MIN_INLINE_LENGTH);
+ icp.getPipelineComponent().setError("Not enough available space");
+ }
+ return false;
+ }
+ }
+
+ private static boolean possibleVaribleLengthInsert(PipeControlPoint icp, PipeControlPoint prev) throws Exception{
+ Vector3d currentPos = icp.getWorldPosition();
+ Vector3d prevPos = prev.getWorldPosition();
+ Vector3d dir = new Vector3d(currentPos);
+ dir.sub(prevPos);
+ double l = dir.lengthSquared();
+ double l2prev = prev.getInlineLength();
+ double l2next = icp.getInlineLength();
+ double l2 = l2prev + l2next;
+ double l2s = l2 * l2;
+ if (l > l2s) {
+ if (allowInsertRemove) {
+ dir.normalize();
+ double length = Math.sqrt(l) - l2; // true length of the variable length component
+ dir.scale(length * 0.5 + l2prev); // calculate center position of the component
+ dir.add(prevPos);
+ insertStraight(prev, icp, dir, length);
+ return true;
+ } else {
+ triedIR = true;
+ }
+ }
+ return false;
+ }
+
+ private static void updateVariableLengthEnd(PipeControlPoint icp, PipeControlPoint prev) {
+ Vector3d currentPos = icp.getWorldPosition();
+ Vector3d prevPos = prev.getWorldPosition();
+
+ Vector3d dir = new Vector3d();
+ dir.sub(currentPos, prevPos);
+
+ boolean simple = currentUpdates.contains(icp);
+ if (simple) {
+ // Update based on position -> adjust length
+ double currentLength = (dir.length() - prev.getInlineLength()) * 2.0;
+ icp.setLength(currentLength);
+ } else {
+ // Update based on neighbour movement -> adjust length and position, so that free end stays in place.
+ 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));
+ }