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 isMod = false; // Can user modify fixed value manually
+ 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 for offset / size change
public PipeControlPoint(PipelineComponent component) {
this.component = component;
return isFixed;
}
-
public void setFixed(boolean fixed) {
this.isFixed = fixed;
}
+
+ @GetPropertyValue(name="Mod",tabId="Debug",value="mod")
+ public boolean isMod() {
+ return isMod;
+ }
+
+ public void setMod(boolean isMod) {
+ this.isMod = isMod;
+ }
@GetPropertyValue(name="Rotate",tabId="Debug",value="rotate")
public boolean isRotate() {
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();
}
public void setNext(PipeControlPoint next) {
+ if (isSub) {
+ getParentPoint().setNext(next);
+ return;
+ }
+ if (next != null && next.isDualSub())
+ next = next.parent;
+ if (_setNext(next)) {
+ for (PipeControlPoint pcp : children) {
+ if (pcp.isSub)
+ pcp._setNext(next);
+ }
+ updateSubPoint();
+ }
+ }
+
+ public void setPrevious(PipeControlPoint prev) {
+ if (isSub) {
+ getParentPoint().setPrevious(prev);
+ return;
+ }
+ if (prev != null && prev.isDualInline())
+ prev = prev.children.get(0);
+ if (_setPrevious(prev)) {
+ for (PipeControlPoint pcp : children) {
+ if (pcp.isSub)
+ pcp._setPrevious(prev);
+ }
+ updateSubPoint();
+ }
+ }
+
+ protected boolean _setNext(PipeControlPoint next) {
if (isEnd() && previous != null && next != null)
throw new RuntimeException("End control points are allowed to have only one connection");
if (next == this)
throw new RuntimeException("Cannot connect to self");
if (this.next == next)
- return;
+ return false;
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.setNext(next != null ? next.component : null);
else
component.setBranch0(next != null ? next.component : null);
- updateSubPoint();
+
}
-
+ return true;
}
- public void setPrevious(PipeControlPoint previous) {
+ protected boolean _setPrevious(PipeControlPoint previous) {
if (isEnd() && next != null && previous != null)
throw new RuntimeException("End control points are allowed to have only one connection");
if (previous == this)
throw new RuntimeException("Cannot connect to self");
if (this.previous == previous)
- return;
+ return false;
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();
}
-
+ return true;
+ }
+
+ 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;
public List<PipeControlPoint> children = new ArrayList<PipeControlPoint>();
- public List<PipeControlPoint> getSubPoint() {
+ public List<PipeControlPoint> getChildPoints() {
return children;
}
this.length = l;
firePropertyChanged("length");
if (isDualInline())
- getSubPoint().get(0).setLength(l);
+ getDualSub().setLength(l);
}
@GetPropertyValue(name="Turn Angle",tabId="Debug",value="turnAngle")
@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")
PipeControlPoint offsetCP = null;
if (isOffset()) {
- offsetCP = getSubPoint().get(0);
+ offsetCP = getDualSub();
}
if (previousNext != null && previousNext == next) {
if (previous.isDualInline()) {
}
if (next.isDualInline()) {
- next.getSubPoint().get(0).setPrevious(this);
+ next.getDualSub().setPrevious(this);
}
} else if (previousPrevious != null && previousPrevious == next) {
// control point were given in reverse order
offsetCP.setPrevious(next);
}
if (previous.isDualInline()) {
- previous.getSubPoint().get(0).setPrevious(this);
+ previous.getDualSub().setPrevious(this);
}
this.setPrevious(next);
next.setNext(this);
pcp.getParentPoint().setNext(this);
}
if (isDualInline()) {
- getSubPoint().get(0).setPrevious(this);
+ getDualSub().setPrevious(this);
}
} else {
// if direction is previous, user must have given sizechange
// we must link pcp to newCP's OffsetPoint
PipeControlPoint nocp = null;
if (isDualInline()) {
- nocp = getSubPoint().get(0);
+ nocp = getDualSub();
nocp.setNext(pcp);
}
if (nocp == null) {
}
this.setNext(pcp);
if (pcp.isDualInline()) {
- PipeControlPoint ocp = pcp.getSubPoint().get(0);
+ PipeControlPoint ocp = pcp.getDualSub();
if (nocp == null)
ocp.setPrevious(this);
else
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;
if (next != null) {
PipeControlPoint pcp = this;
if (pcp.isDualInline()) {
- pcp = pcp.getSubPoint().get(0);
+ pcp = pcp.getDualSub();
}
Vector3d v = new Vector3d();
v.sub(next.getWorldPosition(),pcp.getWorldPosition());
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;
if (pcp.isDualInline()) {
- pcp = pcp.getSubPoint().get(0);
+ pcp = pcp.getDualSub();
}
Vector3d v = new Vector3d();
v.sub(pcp.getWorldPosition(),next.getWorldPosition());
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 getInlineControlPointEnds(Tuple3d p1, Tuple3d p2) {
assert (isInline());
- PipeControlPoint sub = isAxial() ? this : getSubPoint().get(0);
+ PipeControlPoint sub = isAxial() ? this : getDualSub();
Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition();
Vector3d dir = sub.getPathLegDirection(Direction.NEXT);
}
public void getControlPointEnds(Tuple3d p1, Tuple3d p2) {
- PipeControlPoint sub = isAxial() || isDirected() || isTurn() ? this : getSubPoint().get(0);
+ PipeControlPoint sub = isAxial() || isDirected() || isTurn() ? this : getChildPoints().get(0);
Vector3d pos = getWorldPosition(), pos2 = sub == this ? pos : sub.getWorldPosition();
Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS);
}
public void getEndDirections(Tuple3d v1, Tuple3d v2) {
- PipeControlPoint sub = isAxial() ? this : getSubPoint().get(0);
+ PipeControlPoint sub = isAxial() ? this : getDualSub();
Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS);
dir1.normalize();
public void _remove() {
_remove(true);
}
+
+
+ public PipeControlPoint getDualSub() {
+ if (isDualInline())
+ return getChildPoints().get(0);
+ else
+ throw new IllegalStateException("Current control point is not dual inline");
+ }
+
public void _remove(boolean renconnect) {
if (component == null && next == null && previous == null)
return;
if (DEBUG) System.out.println(this + " Remove " + renconnect);
- if (isDualInline() || isDualSub()) {
- removeDualPoint();
- return;
- }
+
if (getParentPoint() != null) {
getParentPoint()._remove(renconnect);
+ return;
}
PipeRun pipeRun = getPipeRun();
if (pipeRun == null)
PipeControlPoint additionalRemove = null;
if (!PipingRules.isEnabled()) {
+ component = null;
setPrevious(null);
setNext(null);
} else {
if (currentNext == null && currentPrev == null) {
removeComponent();
pipeRun.remChild(this);
+ checkRemove(pipeRun);
return;
}
if (currentNext != null && currentPrev != null) {
boolean link = renconnect;
if (currentNext.isBranchEnd()) {
link = false;
- // currentNext.setPrevious(null);
- // currentNext.setNext(null);
currentNext.remove();
currentNext = null;
setNext(null);
}
if (currentPrev.isBranchEnd()) {
link = false;
- // currentPrev.setPrevious(null);
- // currentPrev.setNext(null);
currentPrev.remove();
currentPrev = null;
setPrevious(null);
}
- if (link && currentPrev.isDirected() && currentNext.isDirected()) {
- link = false;
+ if (link) {
+ if (currentPrev.isDirected() && currentNext.isDirected())
+ link = false;
+ else if (this.isDualInline()) {
+ link = false;
+ } else if (this.isDualSub()) {
+ throw new RuntimeException("_remove() is called for parent point, somehow got to child point. " + this);
+ }
}
if (currentNext == null) {
// Nothing to do
} else if (currentNext.isDualInline()) {
PipeControlPoint sccp = currentNext;
- PipeControlPoint ocp = sccp.getSubPoint().get(0);
+ PipeControlPoint ocp = currentNext.getDualSub();
if (ocp == null) {
throw new RuntimeException("Removing PipeControlPoint " + this+ " structure damaged, no offset control point");
}
if (link) {
sccp.setPrevious(currentPrev);
- ocp.setPrevious(currentPrev);
+ //ocp.setPrevious(currentPrev);
+ assert(ocp.getPrevious() == currentPrev);
} else {
sccp.setPrevious(null);
- ocp.setPrevious(null);
+ //ocp.setPrevious(null);
+ assert(ocp.getPrevious() == null);
}
setNext(null);
} else if (currentNext.isDualSub()) {
currentNext.setPrevious(null);
}
setNext(null);
+ } else if (isDualInline()) {
+ if (currentNext.previous != getDualSub()) {
+ throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
+ }
+ if (link) {
+ currentNext.setPrevious(currentPrev);
+ } else {
+ currentNext.setPrevious(null);
+ }
+ setNext(null);
} else {
throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
}
throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, previous control point is size change control point");
} else if (currentPrev.isDualSub()) {
PipeControlPoint ocp = currentPrev;
- PipeControlPoint sccp = ocp.getParentPoint();
+ PipeControlPoint sccp = currentPrev.getParentPoint();
if (sccp == null)
throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, no size change control point");
if (link) {
- ocp.setNext(currentNext);
+ //ocp.setNext(currentNext);
sccp.setNext(currentNext);
+ assert(ocp.getNext() == currentNext);
} else {
- ocp.setNext(null);
+ //ocp.setNext(null);
sccp.setNext(null);
+ assert(ocp.getNext() == null);
}
setPrevious(null);
} else if (currentPrev.next == this) {
} else {
// FIXME : pipe run must be split into two parts, since the control point structure is no more continuous.
}
- } else if (next != null) {
- if (next.isDualInline()) {
- PipeControlPoint sccp = next;
- PipeControlPoint ocp = sccp.getSubPoint().get(0);
+ } else if (currentNext != null) {
+ if (currentNext.isDualInline()) {
+ PipeControlPoint sccp = currentNext;
+ PipeControlPoint ocp = getDualSub();
if (ocp == null) {
throw new RuntimeException("Removing PipeControlPoint " + this+ " structure damaged, no offset control point");
}
sccp.setPrevious(null);
- ocp.setPrevious(null);
- } else if (next.isDualSub()) {
+ assert(ocp.getPrevious() == null);
+ //ocp.setPrevious(null);
+ } else if (currentNext.isDualSub()) {
throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, next control point is offset control point");
- } else if (next.previous == this) {
- next.setPrevious(null);
+ } else if (currentNext.previous == this) {
+ currentNext.setPrevious(null);
+ } else if (isDualInline()) {
+ if (currentNext.previous != getDualSub()) {
+ throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
+ }
+ currentNext.setPrevious(null);
} else {
throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
}
setNext(null);
} else { //(previous != null)
- if(previous.isDualInline()) {
+ if(currentPrev.isDualInline()) {
throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, previous control point is size change control point");
- } else if (previous.isDualSub()) {
- PipeControlPoint ocp = previous;
- PipeControlPoint sccp = ocp.getParentPoint();
+ } else if (currentPrev.isDualSub()) {
+ PipeControlPoint ocp = currentPrev;
+ PipeControlPoint sccp = currentPrev.getParentPoint();
if (sccp == null) {
throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, no size change control point");
}
- ocp.setNext(null);
sccp.setNext(null);
- } else if (previous.next == this) {
- previous.setNext(null);
+ assert(ocp.getNext() == null);
+ } else if (currentPrev.next == this) {
+ currentPrev.setNext(null);
} else {
throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
}
if (getPipelineComponent() == null)
return true; // already removed
if (getPipelineComponent().getType().equals("Plant3D.URIs.Builtin_BranchSplitComponent")) {
- if (getSubPoint().get(0).getNext() == null && getSubPoint().get(0).getPrevious() == null) {
+ if (getChildPoints().get(0).getNext() == null && getChildPoints().get(0).getPrevious() == null) {
remove();
return true;
}
}
- return false;
+ return checkRemove(getPipeRun());
}
}
- private void checkRemove(PipeRun pipeRun) {
+ private boolean checkRemove(PipeRun pipeRun) {
Collection<PipeControlPoint> points = pipeRun.getControlPoints();
if (points.size() == 0) {
pipeRun.remove();
+ return true;
} else if (points.size() == 1) {
PipeControlPoint pcp = points.iterator().next();
- if (pcp.isDeletable())
- pcp._remove();
- }
- }
-
- private void removeDualPoint() {
- if (previous != null)
- previous.setNext(null);
- if (next != null)
- next.setPrevious(null);
- PipeControlPoint ocp;
- PipeControlPoint sccp;
- if (isDualInline()) {
- sccp = this;
- ocp = getSubPoint().get(0);
- } else {
- ocp = this;
- sccp = getParentPoint();
+ if (pcp.isDeletable() && pcp.getNext() == null && pcp.getPrevious() == null) {
+ pcp._remove(); // This call will recursively call also this method...
+ return true;
+ }
+ } else if (points.size() == 2) {
+
}
- PipeRun p1 = ocp.getPipeRun();
- PipeRun p2 = sccp.getPipeRun();
-
- ocp.removeComponent();
- sccp.removeComponent();
-
- if (p1 != null)
- p1.remChild(ocp);
- if (p2 != null)
- p2.remChild(sccp);
-
- // TODO : now we assume that this is size change, and we do
- if (ocp.next != null)
- ocp.next.setPrevious(null);
- if (ocp.previous != null)
- ocp.previous.setNext(null);
- if (sccp.next != null)
- sccp.next.setPrevious(null);
- if (sccp.previous != null)
- sccp.previous.setNext(null);
- ocp.setNext(null);
- ocp.setPrevious(null);
- sccp.setNext(null);
- sccp.setPrevious(null);
-
- if (p1 != null)
- checkRemove(p1);
- if (p2 != null)
- checkRemove(p2);
+ return false;
}
private void removeSubPoints() {
for (PipeControlPoint p : children) {
- // TODO : this may affect delete routine, since classification of the point changes.
p.parent = null;
- p._remove();
+ p.component = null;
+ //p._remove();
+ PipeControlPoint currentNext = p.getNext();
+ PipeControlPoint currentPrev = p.getPrevious();
+ p._setNext(null);
+ p._setPrevious(null);
+ PipeRun run = p.getPipeRun();
+ if (run != null) {
+ run.remChild(p);
+ checkRemove(run);
+ }
+ if (currentNext != null)
+ if (!currentNext.checkRemove())
+ PipingRules.requestUpdate(currentNext);
+ if (currentPrev != null)
+ if (!currentPrev.checkRemove())
+ PipingRules.requestUpdate(currentPrev);
+
}
children.clear();
}
private void removeParentPoint() {
throw new RuntimeException("Child points cannot be removed directly");
}
+
+ public boolean isRemoved() {
+ return component == null;
+ }
private void removeComponent() {
if (component == null)
private void updateSubPoint() {
if (isOffset()) {
if (next == null && previous == null) {
- for (PipeControlPoint sub : getSubPoint()) {
+ for (PipeControlPoint sub : getChildPoints()) {
sub.setWorldPosition(getWorldPosition());
sub.setWorldOrientation(getWorldOrientation());
}
return;
}
- for (PipeControlPoint sub : getSubPoint()) {
+ for (PipeControlPoint sub : getChildPoints()) {
Vector3d wp = getWorldPosition();
wp.add(getSizeChangeOffsetVector());
sub.setWorldPosition(wp);
sub.setWorldOrientation(getWorldOrientation());
}
} else {
- for (PipeControlPoint sub : getSubPoint()) {
+ for (PipeControlPoint sub : getChildPoints()) {
sub.setWorldPosition(getWorldPosition());
sub.setWorldOrientation(getWorldOrientation());
}