private boolean useFullSyncWithUndo = false;
protected void update(ReadGraph graph) throws DatabaseException {
- synchronized (syncMutex) {
- if (DEBUG) System.out.println("Graph update start");
-
- if (runUndo && useFullSyncWithUndo) {
+ if (DEBUG) System.out.println("Graph update start");
+
+ if (runUndo && useFullSyncWithUndo) {
+ synchronized (syncMutex) {
reset(graph);
- } else {
+ }
+ } else {
+ synchronized (syncMutex) {
graphUpdates = true;
for (DBObject domainObject : mapping.getDomainModified()) {
@SuppressWarnings("unchecked")
if (rangeObject != null)
graphModified.add(rangeObject);
}
- mapping.updateRange(graph);
+
+ }
+
+ mapping.updateRange(graph);
+
+ synchronized (syncMutex) {
graphModified.clear();
syncDeletes();
- clearDeletes();
- graphUpdates = false;
- }
-
- if (mapping.isRangeModified() && !runUndo && !runRedo)
- commit((String)null);
+ }
- if (DEBUG) System.out.println("Graph update done");
+ clearDeletes();
+ graphUpdates = false;
}
+
+ if (mapping.isRangeModified() && !runUndo && !runRedo)
+ commit((String)null);
+
+ if (DEBUG) System.out.println("Graph update done");
}
@Override
* This code here synchronizes removed and added objects to collect deletable objects. (a deletable object is one which is removed but not added).
*
*/
- @SuppressWarnings("unused")
protected void syncDeletes() {
deleteUC.clear();
for (Pair<E, String> n : removed) {
/**
* Clears deletable objects from mapping cache.
*/
- @SuppressWarnings("unused")
protected void clearDeletes() {
if (DEBUG && delete.size() > 0) System.out.println("Delete");
for (E n : delete) {
allowed.add(PositionType.NEXT);
}
} else {
- if (component.getNext() == null) {
+ if (component.getNext() == null || component.getControlPoint().isVariableLength()) {
allowed.add(PositionType.NEXT);
}
- if (component.getPrevious() == null) {
+ if (component.getPrevious() == null || component.getControlPoint().isVariableLength()) {
allowed.add(PositionType.PREVIOUS);
}
- if (component instanceof InlineComponent && !component.getControlPoint().isFixedLength()){
+ if (component instanceof InlineComponent && component.getControlPoint().isVariableLength()){
allowed.add(PositionType.SPLIT);
}
}
dialogSettings = settings.getSection(DIALOG);
if (dialogSettings == null)
dialogSettings = settings.addNewSection(DIALOG);
+
+ if (component.getNext() != null && component.getPrevious() != null)
+ insertPosition = PositionType.PREVIOUS;
}
public void setLengthFactor(double lengthFactor) {
horizFillData.applyTo(buttonComposite);
GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite);
+ startButton.setSelection(insertPosition == PositionType.PREVIOUS);
+ middleButton.setSelection(insertPosition == PositionType.SPLIT);
+ endButton.setSelection(insertPosition == PositionType.NEXT);
+
startButton.setEnabled(false);
middleButton.setEnabled(false);
endButton.setEnabled(false);
updateInsertPosition(PositionType.NEXT);
}
});
- endButton.setSelection(true);
label = new Label(composite, SWT.NONE);
label.setText("Name");
private void updateInsertPosition(PositionType type) {
if (insertPosition == type)
return;
- endButton.setSelection(type == PositionType.NEXT);
- middleButton.setSelection(type == PositionType.SPLIT);
startButton.setSelection(type == PositionType.PREVIOUS);
+ middleButton.setSelection(type == PositionType.SPLIT);
+ endButton.setSelection(type == PositionType.NEXT);
insertPosition = type;
}
} else {
lenghtAdjustable = ((selected.getType() == Type.INLINE)
&& (selected.isVariable() || selected.isModifiable()));
- if (insertAdjustable) {
+
+ if (component.getNext() != null && component.getPrevious() != null) {
+ // We are inserting to a fully connected variable length component
+ // only allow insertion within the component
+ startButton.setEnabled(false);
+ middleButton.setEnabled(false);
+ endButton.setEnabled(false);
+ updateInsertPosition(PositionType.PREVIOUS);
+ } else if (insertAdjustable) {
switch (selected.getType()) {
case END:
startButton.setEnabled(false);
rotationAngleText.setEnabled(true);
if (angle == null) {
ok = false;
- if (msg == null) msg = "Please provide a rotation angle";
+ if (msg == null) msg = "Please provide a turn angle";
}
} else {
// this should not happen, since end components should not have variable, or
map.put("radius2", pipeRun2.getPipeDiameter() * 0.5);
}
if (controlPoint.isOffset() && !componentCalculatedOffset) {
+ if (getPipeRun() != null && getAlternativePipeRun() != null)
+ updateOffset();
map.put("offset", controlPoint.getOffset());
}
}
}
if (this.rotationAngle != null && Math.abs(this.rotationAngle-rotationAngle) < MathTools.NEAR_ZERO)
return;
- if (Objects.equals(rotationAngle, rotationAngle))
+ if (Objects.equals(this.rotationAngle, rotationAngle))
return;
this.rotationAngle = rotationAngle;
firePropertyChanged("rotationAngle");
}
/**
- * Returns direction vector.
+ * Returns direction vector pointing towards an adjacent component for
+ * directed control points or turn control points with one open end.
*
- * For directed control points, always returns outwards pointing vector.
+ * Always returns an outwards pointing vector.
+ *
+ * For any other type of component, the return value is null.
+ *
+ * For turn components this only return a non-null value for the unconnected
+ * end of the component.
*
* @param direction
* @return normalized vector, or null
Vector3d offset = new Vector3d();
MathTools.rotate(q2, v, offset);
MathTools.rotate(q, offset, dir);
+ dir.negate();
dir.normalize();
return dir;
}
*/
public Vector3d getPathLegDirection(Direction direction) {
if (direction == Direction.NEXT) {
- if (next != null) {
- PipeControlPoint pcp = this;
- if (pcp.isDualInline()) {
- pcp = pcp.getDualSub();
- }
- Vector3d v = new Vector3d();
- v.sub(next.getWorldPosition(),pcp.getWorldPosition());
- if (v.lengthSquared() > MathTools.NEAR_ZERO)
- v.normalize();
- else
- return null;
- return v;
- } else {
- if (previous == null) {
- if (!isDirected())
- throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + this);
- return getDirectedControlPointDirection();
+ return getPathLegDirectionNext();
+ } else {
+ return getPathLegDirectionPrevious();
+ }
+ }
- } else {
- 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.isDualSub()) {
- pcp = pcp.getParentPoint();
- }
- Vector3d v = new Vector3d();
- v.sub(pcp.getWorldPosition(),previous.getWorldPosition());
- if (v.lengthSquared() > MathTools.NEAR_ZERO)
- v.normalize();
- else
- return null;
- return v;
- } else if (isDirected()) {
- return getDirectedControlPointDirection();
- } else if (isEnd()) {
- Vector3d v = new Vector3d();
- v.sub(getWorldPosition(),previous.getWorldPosition());
- if (v.lengthSquared() > MathTools.NEAR_ZERO)
- v.normalize();
- else
- return null;
- return v;
- } else if (isTurn() && asFixedAngle() && !_getReversed()) {
- return getDirection(Direction.NEXT);
- }
- throw new RuntimeException("Missing implementation " + this);
- }
- }
+ public Vector3d getPathLegDirectionPrevious() {
+ if (previous != null) {
+ PipeControlPoint pcp = this;
+ if (isDualSub())
+ pcp = getParentPoint();
+ Vector3d v = new Vector3d();
+ v.sub(previous.getWorldPosition(),pcp.getWorldPosition());
+ if (v.lengthSquared() > MathTools.NEAR_ZERO)
+ v.normalize();
+ else
+ return null;
+ return v;
+ } else if (isDirected()) {
+ Vector3d v = getDirectedControlPointDirection();
+ v.negate();
+ return v;
+ } else if (next == null) {
+ throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + this);
+ } else if (isVariableAngle() && !asFixedAngle()) {
+ throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + this);
+ } else if (isInline() || isEnd()) {
+ Vector3d v = getPathLegDirectionNext();
+ if (v != null) v.negate();
+ return v;
+ } else if (isTurn() && asFixedAngle() && _getReversed()) {
+ return getDirection(Direction.PREVIOUS);
} else {
- if (previous != null) {
- PipeControlPoint pcp = this;
- if (isDualSub())
- pcp = getParentPoint();
- Vector3d v = new Vector3d();
- v.sub(previous.getWorldPosition(),pcp.getWorldPosition());
- if (v.lengthSquared() > MathTools.NEAR_ZERO)
- v.normalize();
- else
- return null;
- return v;
- } else {
- if (next == null) {
- if (!isDirected())
- throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + this);
- Vector3d v = getDirectedControlPointDirection();
- v.negate();
- return v;
- } else {
- 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.getDualSub();
- }
- Vector3d v = new Vector3d();
- v.sub(pcp.getWorldPosition(),next.getWorldPosition());
- if (v.lengthSquared() > MathTools.NEAR_ZERO)
- v.normalize();
- else
- return null;
- return v;
- } else if (isDirected()) {
- Vector3d v = getDirectedControlPointDirection();
- v.negate();
- return v;
- } else if (isEnd()) {
- Vector3d v = new Vector3d();
- v.sub(getWorldPosition(),next.getWorldPosition());
- if (v.lengthSquared() > MathTools.NEAR_ZERO)
- v.normalize();
- else
- return null;
- return v;
- } else if (isTurn() && asFixedAngle() && _getReversed()) {
- return getDirection(Direction.PREVIOUS);
- }
- throw new RuntimeException("Missing implementation " + this);
- }
+ throw new RuntimeException("Missing implementation " + this);
+ }
+ }
+
+ public Vector3d getPathLegDirectionNext() {
+ if (next != null) {
+ PipeControlPoint pcp = this;
+ if (pcp.isDualInline()) {
+ pcp = pcp.getDualSub();
}
+ Vector3d v = new Vector3d();
+ v.sub(next.getWorldPosition(),pcp.getWorldPosition());
+ if (v.lengthSquared() > MathTools.NEAR_ZERO)
+ v.normalize();
+ else
+ return null;
+ return v;
+ } else if (isDirected()) {
+ return getDirectedControlPointDirection();
+ } else if (previous == null) {
+ throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + this);
+ } else if (isVariableAngle() && !asFixedAngle()) {
+ throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + this);
+ } else if (isInline() || isEnd()) {
+ Vector3d v = getPathLegDirectionPrevious();
+ if (v != null) v.negate();
+ return v;
+ } else if (isTurn() && asFixedAngle() && !_getReversed()) {
+ return getDirection(Direction.NEXT);
+ } else {
+ throw new RuntimeException("Missing implementation " + this);
}
}
updateSubPoint();
}
+ public void orientToDirection(Vector3d dir) {
+ Double angleO = getRotationAngle();
+ double angle = 0.0;
+ if (angleO != null)
+ angle = angleO;
+ boolean reversed = _getReversed();
+ Quat4d q = null;
+ if (dir != null) {
+ q = getControlPointOrientationQuat(dir, angle, reversed);
+ } else {
+ q = getControlPointOrientationQuat(angle, reversed);
+ }
+ setWorldOrientation(q);
+ }
+
@Override
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
scp.setWorldPosition(pos);
Vector3d dir = new Vector3d();
dir.sub(pcp2.getWorldPosition(), pcp1.getWorldPosition());
- updateControlPointOrientation(scp, dir);
+ scp.orientToDirection(dir);
scp.setLength(length);
validate(scp.getPipeRun());
return scp;
}
+ /**
+ * 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);
}
} 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));
Point3d otherPosition = new Point3d(dcpStart ? u.endPoint : u.startPoint);
if (u.hasOffsets) {
- Vector3d dir = new Vector3d(), offset = new Vector3d();
+ 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.add(offset);
- else
otherPosition.sub(offset);
+ else
+ otherPosition.add(offset);
}
double mu[] = new double[2];
Point3d position1 = new Point3d(u.startPoint);
Point3d position2 = new Point3d(u.endPoint);
- Vector3d dir = new Vector3d(), offset = new Vector3d();
+ 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);
} 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);
}
/**
System.out.println("PipingRules.updateEndComponentControlPoint() " + ecp);
if (!ecp.isFixed()) // prevent overriding nozzle orientations..
- updateControlPointOrientation(ecp, dir);
+ 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
*
tcp.setTurnAxis(new Vector3d(MathTools.Y_AXIS));
}
- updateControlPointOrientation(tcp,prev);
+ tcp.orientToDirection(prev);
if (DEBUG)
System.out.println("PipingTools.updateTurnControlPointTurn " + prev + " " + next + " " + turnAngle + " " + turnAxis);
public static PipelineComponent addComponent(P3DRootNode root, PipelineComponent component, InsertInstruction inst) throws Exception {
PipelineComponent newComponent = ComponentUtils.createComponent(root, inst.typeUri);
- if (inst.name != null)
- newComponent.setName(inst.name);
-
PipeControlPoint newPcp = newComponent.getControlPoint();
PipeControlPoint toPcp = component.getControlPoint();
sizeChange = ((InlineComponent)newComponent).isSizeChange();
}
+ // Calculate component position and direction vectors
+ // 'dir' is a unit vector that represents the direction from 'component' to 'newComponent'
if (toPcp.isInline()) {
switch (position) {
case NEXT:
break;
case PREVIOUS:
pos = new Vector3d(start);
+ dir.negate();
break;
case SPLIT:
pos = new Vector3d(toPcp.getWorldPosition());
default:
break;
}
-
} else if (toPcp.isDirected()) {
- dir = new Vector3d(toPcp.getDirection(Direction.NEXT));
+ // 'dir' always points out of a nozzle regardless of insertion direction
+ dir = new Vector3d(toPcp.getDirectedControlPointDirection());
pos = new Vector3d(toPcp.getWorldPosition());
} else if (toPcp.isTurn() && toPcp.asFixedAngle()) {
dir = new Vector3d(toPcp.getDirection(position == PositionType.NEXT ? Direction.NEXT : Direction.PREVIOUS));
}
}
- String name = component.getPipeRun().getUniqueName(typeName);
- newComponent.setName(name);
+ if (inst.name != null) {
+ newComponent.setName(inst.name);
+ } else {
+ String name = component.getPipeRun().getUniqueName(typeName);
+ newComponent.setName(name);
+ }
pipeRun.addChild(newComponent);
if (newPcp.isSizeChange())
} else if (newComponent instanceof TurnComponent) {
TurnComponent turnComponent = (TurnComponent)newComponent;
if (turnComponent.isVariableAngle()) {
- newPcp.setTurnAngle(inst.angle);
+ newPcp.setTurnAngle(Math.toRadians(inst.angle));
newComponent.setParameter("turnAngle", inst.angle);
}
if (inst.rotationAngle != null)
((TurnComponent) newComponent).setRotationAngle(inst.rotationAngle);
}
-
newComponent.updateParameters();
Vector3d v = new Vector3d(dir);
if (insertAdjustable) {
+ // Prevent moving of adjacent components - always insert at end of a connected variable length component
+ if (position == PositionType.NEXT && component.getNext() != null ||
+ position == PositionType.PREVIOUS && component.getPrevious() != null)
+ insertPosition = PositionType.PREVIOUS;
+
if (insertPosition == PositionType.NEXT)
v.scale(newComponent.getControlPoint().getInlineLength());
else if (insertPosition == PositionType.SPLIT)
} else {
v.scale(newComponent.getControlPoint().getInlineLength());
}
+
switch (position) {
case NEXT:
- pos.add(v);
- break;
case PREVIOUS:
- pos.sub(v);
+ pos.add(v);
break;
case SPLIT:
break;
case NEXT:
if (toPcp.isDualInline())
toPcp = toPcp.getDualSub();
- newPcp.insert(toPcp, Direction.NEXT);
newPcp.setWorldPosition(pos);
+ if (toPcp.getNext() != null)
+ PipingRules.splitVariableLengthComponent(newComponent, (InlineComponent)component, false);
+ else
+ newPcp.insert(toPcp, Direction.NEXT);
break;
case PREVIOUS:
if (toPcp.isDualSub())
toPcp = toPcp.parent;
- newPcp.insert(toPcp, Direction.PREVIOUS);
newPcp.setWorldPosition(pos);
+ if (toPcp.getPrevious() != null)
+ PipingRules.splitVariableLengthComponent(newComponent, (InlineComponent)component, false);
+ else
+ newPcp.insert(toPcp, Direction.PREVIOUS);
break;
case SPLIT:
PipingRules.splitVariableLengthComponent(newComponent, (InlineComponent)component, true);