private PipelineComponent component;
private PointType type;
- private boolean isFixed = true;
- private boolean isRotate = false;
- private boolean isReverse = false;
- private boolean isDeletable = true;
- private boolean isSizeChange = false;
- private boolean isSub = false;
+ private boolean isFixed = true; // In-line: fixed-length Turn: fixed-angle
+ private boolean isRotate = false; // rotates around path leg axis.
+ private boolean isReverse = false; // definition direction can be swapped
+ private boolean isDeletable = true; // can be removed by rules
+ private boolean isSizeChange = false; // changes size of the pipe. The next control point / component is on different PipeRun
+ private boolean isSub = false; // child point
public PipeControlPoint(PipelineComponent component) {
this.component = component;
return isFixed;
}
-
public void setFixed(boolean fixed) {
this.isFixed = fixed;
}
return type == PointType.INLINE;
}
+ /**
+ * True for end components, if control point defines absolute position direction, which rules cannot modify.
+ * This is typical for nozzles.
+ * @return
+ */
public boolean isDirected() {
return isFixed && isEnd();
}
+ /**
+ * True for end components, if control is opposite to directed, and rules can modify position and orientation.
+ * This is typical for caps, and other end components.
+ * @return
+ */
public boolean isNonDirected() {
return !isFixed && isEnd();
}
public boolean isVariableLength() {
return !isFixed && isInline();
}
+
+ /**
+ * Fixed length in-line component is such that piping rules cannot modify the length.
+ * @return
+ */
+ public boolean isFixedLength() {
+ return isFixed && isInline();
+ }
public boolean isVariableAngle() {
return !isFixed && isTurn();
}
+
+ /**
+ * Fixed angle turn component is such that piping rules cannot modify the angle.
+ * @return
+ */
+ public boolean isFixedAngle() {
+ return isFixed && isTurn();
+ }
+
+ /**
+ * Does the turn behave like fixed angle?
+ * For variable angle turns, the turn angle is defined by connected components, and without them, we must handle the component as fixed angle.
+ * @return
+ */
+ public boolean asFixedAngle() {
+ return isTurn() && (isFixed || next == null || previous == null);
+ }
public boolean isBranchEnd() {
return isDeletable && isEnd();
if (this.next == next)
return;
if (DEBUG) System.out.println(this + " next " + next);
+ if (next == null && isVariableAngle() && previous != null && !isRemoved()) {
+ convertVariableAngleToFixed(Direction.NEXT);
+ }
this.next = next;
if (component != null) {
if (parent == null || isSub)
component.setBranch0(next != null ? next.component : null);
updateSubPoint();
}
-
}
public void setPrevious(PipeControlPoint previous) {
if (this.previous == previous)
return;
if (DEBUG) System.out.println(this + " previous " + previous);
+ if (previous == null && isVariableAngle() && next != null && !isRemoved()) {
+ convertVariableAngleToFixed(Direction.PREVIOUS);
+ }
this.previous = previous;
if (component != null) {
if (parent == null || isSub)
component.setBranch0(previous != null ? previous.component : null);
updateSubPoint();
}
-
+ }
+
+ private void convertVariableAngleToFixed(Direction direction) {
+ // We are removing reference, which transforms variable angle to fixed angle.
+ // Since fixed angle is defined differently, we need to calculate fixed angle parameters based on current data
+ // We need to calculate turnAngle and rotationAngle
+ Vector3d dirOut = getPathLegDirection(direction == Direction.NEXT ? Direction.NEXT : Direction.PREVIOUS);
+ Vector3d dir = getPathLegDirection(direction == Direction.NEXT ? Direction.PREVIOUS : Direction.NEXT);
+ dir.negate();
+ dirOut.normalize();
+ dir.normalize();
+ double angle = dir.angle(dirOut);
+ //super._setNext(null);
+ if (direction == Direction.NEXT)
+ next = null;
+ else
+ previous = null;
+ setRotationAngle(0.0);
+ setReversed(direction == Direction.NEXT ? false : true);
+ Vector3d dirOutN = getPathLegDirection(direction == Direction.NEXT ? Direction.NEXT : Direction.PREVIOUS);
+ dirOutN.normalize();
+ AxisAngle4d aa = new AxisAngle4d();
+ if (MathTools.createRotation(dirOutN, dirOut, dir, aa)) {
+ setRotationAngle(aa.angle);
+ setTurnAngle(angle);
+ }
}
public PipeControlPoint parent;
@GetPropertyValue(name="Rotation Angle",tabId="Debug",value="rotationAngle")
public Double getRotationAngle() {
- return rotationAngle;
+ if (asFixedAngle())
+ return rotationAngle;
+ return null;
}
@GetPropertyValue(name="Reversed",tabId="Debug",value="reversed")
public Vector3d getDirection(Direction direction) {
if (isDirected())
return getDirectedControlPointDirection();
- if (isTurn() && isFixed()) {
+ if (isTurn() && asFixedAngle()) {
if (direction == Direction.NEXT) {
if (previous != null) {
PipeControlPoint pcp = this;
return getDirectedControlPointDirection();
} else {
- if (isVariableAngle())
+ if (isVariableAngle() && !asFixedAngle())
throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + this);
if (isInline()) {
PipeControlPoint pcp = this;
Vector3d v = new Vector3d();
v.sub(getWorldPosition(),previous.getWorldPosition());
return v;
- } else if (isTurn() && isFixed() && !_getReversed()) {
+ } else if (isTurn() && asFixedAngle() && !_getReversed()) {
return getDirection(Direction.NEXT);
}
throw new RuntimeException("Missing implementation " + this);
v.negate();
return v;
} else {
- if (isVariableAngle())
+ if (isVariableAngle() && !asFixedAngle())
throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + this);
if (isInline()) {
PipeControlPoint pcp = this;
Vector3d v = new Vector3d();
v.sub(getWorldPosition(),next.getWorldPosition());
return v;
- } else if (isTurn() && isFixed() && _getReversed()) {
+ } else if (isTurn() && asFixedAngle() && _getReversed()) {
return getDirection(Direction.PREVIOUS);
}
throw new RuntimeException("Missing implementation " + this);
}
public void getControlPointEnds(Tuple3d p1, Tuple3d p2) {
- PipeControlPoint sub = isAxial() ? this : getSubPoint().get(0);
+ PipeControlPoint sub = isAxial() || isDirected() || isTurn() ? this : getSubPoint().get(0);
Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition();
Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS);
PipeControlPoint additionalRemove = null;
if (!PipingRules.isEnabled()) {
+ component = null;
setPrevious(null);
setNext(null);
} else {
PipeRun previousRun = previous.getPipeRun();
nextPipeRun.setPipeDiameter(previousRun.getPipeDiameter());
- nextPipeRun.setTurnRadius(previousRun.getTurnRadius());
+ nextPipeRun.setTurnRadiusArray(previousRun.getTurnRadiusArray());
PipelineComponent n = next.getPipelineComponent();
while (n != null) {
private void removeParentPoint() {
throw new RuntimeException("Child points cannot be removed directly");
}
+
+ public boolean isRemoved() {
+ return component == null;
+ }
private void removeComponent() {
if (component == null)