P3D.HasPipeDiameter <R G3D.hasNonTransformation
L0.HasRange L0.Double
-//P3D.HasLength <R G3D.hasNonTransformation
-// L0.HasRange L0.Double
-//P3D.HasTurnAngle <R G3D.hasNonTransformation
-// L0.HasRange L0.Double
P3D.HasRotationAngle <R G3D.hasTransformation
L0.HasRange L0.Double
+P3D.HasLength <R G3D.hasNonTransformation
+ L0.HasRange L0.Double
+P3D.HasTurnAngle <R G3D.hasNonTransformation
+ L0.HasRange L0.Double
+
//P3D.HasOffset <R L0.HasProperty
// L0.HasRange L0.Double
//HasRelativePosition <R HasProperty
L0.HasName "radius" : L0.String
P3D.hasParameterValue 0.1 : L0.Double
+P3D.Builtin.Elbow90 <T P3D.TurnComponent : P3D.TurnComponent
+ @L0.tag P3D.FixedAngleTurnComponent
+ @L0.tag P3D.DualConnectedComponent
+ @L0.assert P3D.hasGeometry P3D.Builtin.ElbowGeometryProvider
+ @L0.assert P3D.hasParameter
+ _ :P3D.Parameter
+ L0.HasName "turnAngle" : L0.String
+ P3D.hasParameterValue 90.0 : L0.Double
+ @L0.assert P3D.HasTurnAngle
+ 1.5707963267948966192313216916398 : L0.Double
+
+P3D.Builtin.Elbow45 <T P3D.TurnComponent : P3D.TurnComponent
+ @L0.tag P3D.FixedAngleTurnComponent
+ @L0.tag P3D.DualConnectedComponent
+ @L0.assert P3D.hasGeometry P3D.Builtin.ElbowGeometryProvider
+ @L0.assert P3D.hasParameter
+ _ :P3D.Parameter
+ L0.HasName "turnAngle" : L0.String
+ P3D.hasParameterValue 45.0 : L0.Double
+ @L0.assert P3D.HasTurnAngle
+ 0.78539816339744830961566084581988 : L0.Double
\ No newline at end of file
PipeControlPoint newPcp = newComponent.getControlPoint();
PipeControlPoint toPcp = component.getControlPoint();
+ PipeRun pipeRun = toPcp.getPipeRun();
+ Vector3d dir = null;
+ Vector3d pos = null;
+
- switch (position) {
- case NEXT:
- if (toPcp.isDualInline())
- toPcp = toPcp.getSubPoint().get(0);
-
- break;
- case PREVIOUS:
- if (toPcp.isDualSub())
- toPcp = toPcp.parent;
+ if (toPcp.isInline()) {
+ switch (position) {
+ case NEXT:
+ if (toPcp.isDualInline())
+ toPcp = toPcp.getSubPoint().get(0);
+
+ break;
+ case PREVIOUS:
+ if (toPcp.isDualSub())
+ toPcp = toPcp.parent;
+ }
+ Vector3d start = new Vector3d();
+ Vector3d end = new Vector3d();
+ dir = new Vector3d();
+ toPcp.getInlineControlPointEnds(start, end, dir);
+ dir.normalize();
+ switch (position) {
+ case NEXT:
+ pos = new Vector3d(end);
+ break;
+ case PREVIOUS:
+ pos = new Vector3d(start);
+ break;
+ case SPLIT:
+ break;
+ }
+
+ } else if (toPcp.isDirected()) {
+ dir = new Vector3d(toPcp.getDirection(Direction.NEXT));
+ pos = new Vector3d(toPcp.getWorldPosition());
+ } else if (toPcp.isTurn() && toPcp.isFixed()) {
+ dir = new Vector3d(toPcp.getDirection(position == PositionType.NEXT ? Direction.NEXT : Direction.PREVIOUS));
+ pos = new Vector3d(toPcp.getWorldPosition());
+ Vector3d v = new Vector3d(dir);
+ v.scale(toPcp.getInlineLength());
+ pos.add(v);
}
- Vector3d start = new Vector3d();
- Vector3d end = new Vector3d();
- Vector3d dir = new Vector3d();
- toPcp.getInlineControlPointEnds(start, end, dir);
- dir.normalize();
-
- PipeRun pipeRun = toPcp.getPipeRun();
if (!toAdd.isSizeChange()) {
String name = component.getPipeRun().getUniqueName(toAdd.getName());
}
}
newComponent.updateParameters();
-
- dir.scale(newComponent.getControlPoint().getLength()*0.5);
- start.sub(dir);
- end.add(dir);
+
+ Vector3d v = new Vector3d(dir);
+ v.scale(newComponent.getControlPoint().getInlineLength());
+ switch (position) {
+ case NEXT:
+ pos.add(v);
+ break;
+ case PREVIOUS:
+ pos.sub(v);
+ break;
+ case SPLIT:
+ break;
+ }
+
switch (position) {
case NEXT:
if (toPcp.isDualInline())
toPcp = toPcp.getSubPoint().get(0);
newPcp.insert(toPcp, Direction.NEXT);
- newPcp.setWorldPosition(end);
+ newPcp.setWorldPosition(pos);
break;
case PREVIOUS:
if (toPcp.isDualSub())
toPcp = toPcp.parent;
newPcp.insert(toPcp, Direction.PREVIOUS);
- newPcp.setWorldPosition(start);
+ newPcp.setWorldPosition(pos);
break;
case SPLIT:
PipingRules.splitVariableLengthComponent(newComponent, (InlineComponent)component, true);
}
} else {
-
-
PipeRun other = new PipeRun();
String n = root.getUniqueName("PipeRun");
other.setName(n);
root.addChild(other);
-
if (position == PositionType.NEXT) {
PipingRules.addSizeChange(false, pipeRun, other, (InlineComponent)newComponent, toPcp, null);
- newPcp.setWorldPosition(end);
} else if (position == PositionType.PREVIOUS){
PipingRules.addSizeChange(true, pipeRun, other, (InlineComponent)newComponent, toPcp, null);
- newPcp.setWorldPosition(start);
}
+ newPcp.setWorldPosition(pos);
// TODO : chicken-egg problem
newComponent.updateParameters();
- dir.scale(newComponent.getControlPoint().getLength()*0.5);
- start.sub(dir);
- end.add(dir);
- if (position == PositionType.NEXT) {
- newPcp.setWorldPosition(end);
- } else if (position == PositionType.PREVIOUS){
- newPcp.setWorldPosition(start);
- }
+ Vector3d v = new Vector3d(dir);
+ v.scale(newComponent.getControlPoint().getLength()*0.5);
+ switch (position) {
+ case NEXT:
+ pos.add(v);
+ break;
+ case PREVIOUS:
+ pos.sub(v);
+ break;
+ case SPLIT:
+ break;
+ }
+ newPcp.setWorldPosition(pos);
+
}
if (radius < MathTools.NEAR_ZERO)
radius = MathTools.NEAR_ZERO;
}
+
+ @Override
+ public void updateCalculatedProperties(Map<String, Object> returnProps) {
+ double t = Math.tan((Math.PI - turnAngle) * 0.5);
+ double R = 0.0;
+ if (t > MathTools.NEAR_ZERO)
+ R = turnRadius / t;
+ returnProps.put("length", R);
+ }
}
import org.simantics.g3d.math.MathTools;
import org.simantics.g3d.property.annotations.GetPropertyValue;
+import org.simantics.g3d.property.annotations.SetPropertyValue;
import org.simantics.g3d.scenegraph.base.ParentNode;
import org.simantics.objmap.graph.annotations.DynamicGraphType;
import org.simantics.objmap.graph.annotations.GetType;
+import org.simantics.objmap.graph.annotations.RelatedGetValue;
+import org.simantics.objmap.graph.annotations.RelatedSetValue;
import org.simantics.objmap.graph.annotations.SetType;
import org.simantics.plant3d.ontology.Plant3D;
import org.simantics.plant3d.scenegraph.controlpoint.ControlPointFactory;
import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
+import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
@DynamicGraphType(Plant3D.URIs.TurnComponent)
public class TurnComponent extends PipelineComponent {
return map;
}
+ public boolean isVariableAngle() {
+ return !controlPoint.isFixed();
+ }
+ @Override
+ public void updateParameters() {
+ super.updateParameters();
+ if (!isVariableAngle()) {
+ Map<String,Object> calculated = getCalculatedParameters();
+ if (calculated.containsKey("length")) {
+ controlPoint.setLength((Double)calculated.get("length"));
+ }
+ }
+ }
+
+ @RelatedGetValue(Plant3D.URIs.HasTurnAngle)
public Double getTurnAngle() {
return getControlPoint().getTurnAngle();
}
+ @RelatedSetValue(Plant3D.URIs.HasTurnAngle)
+ public void setTurnAngle(Double a) {
+ if (!getControlPoint().isFixed())
+ return;
+ getControlPoint().setTurnAngle(a);
+ }
+
@GetPropertyValue(name="Turn Angle", value="turn angle", tabId = "Default")
public Double getTurnAngleDeg() {
Double d = getControlPoint().getTurnAngle();
return getTurnAxis();
}
+ @RelatedGetValue(Plant3D.URIs.HasRotationAngle)
+ @GetPropertyValue(name="Rotation Angle", value=Plant3D.URIs.HasRotationAngle, tabId = "Default")
+ public Double getRotationAngle() {
+ if (!controlPoint.isFixed())
+ return null;
+ Double d = controlPoint.getRotationAngle();
+ if (d == null)
+ return 0.0;
+ return MathTools.radToDeg(d);
+ }
+ @RelatedSetValue(Plant3D.URIs.HasRotationAngle)
+ @SetPropertyValue(value=Plant3D.URIs.HasRotationAngle)
+ public void setRotationAngle(Double angle) {
+ if (!controlPoint.isFixed())
+ return;
+
+ if (angle == null || Double.isInfinite(angle) || Double.isNaN(angle)) {
+ return;
+ }
+ angle = MathTools.degToRad(angle);
+ if (controlPoint.getRotationAngle() != null && Math.abs(controlPoint.getRotationAngle()-angle) < MathTools.NEAR_ZERO)
+ return;
+ controlPoint.setRotationAngle(angle);
+ try {
+ PipingRules.requestUpdate(getControlPoint());
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
@Override
protected double[] getColor() {
if (getControlPoint() == null || !getControlPoint().isFixed())
return reversed;
}
+ public boolean _getReversed() {
+ if (reversed == null)
+ return false;
+ return reversed;
+ }
+
public void setTurnAngle(Double turnAngle) {
if (Double.isInfinite(turnAngle) || Double.isNaN(turnAngle)) {
return;
public void setReversed(Boolean reversed) {
this.reversed = reversed;
- firePropertyChanged("rotationAngle");
+ firePropertyChanged("reversed");
}
public Vector3d getSizeChangeOffsetVector(Vector3d dir) {
return q1;
}
- public Vector3d getDirection() {
- return getDirectedControlPointDirection();
+ public Vector3d getDirection(Direction direction) {
+ if (isDirected())
+ return getDirectedControlPointDirection();
+ if (isTurn() && isFixed()) {
+ if (direction == Direction.NEXT) {
+ if (previous != null) {
+ PipeControlPoint pcp = this;
+ Vector3d dir = new Vector3d();
+ dir.sub(pcp.getWorldPosition(),previous.getWorldPosition());
+ if (dir.lengthSquared() > MathTools.NEAR_ZERO)
+ dir.normalize();
+ Quat4d q = getControlPointOrientationQuat(dir, pcp.getRotationAngle() != null ? pcp.getRotationAngle() : 0.0);
+ AxisAngle4d aa = new AxisAngle4d(MathTools.Y_AXIS,pcp.getTurnAngle() == null ? 0.0 : pcp.getTurnAngle());
+ Quat4d q2 = MathTools.getQuat(aa);
+ Vector3d v = new Vector3d(1.,0.,0.);
+ Vector3d offset = new Vector3d();
+ MathTools.rotate(q2, v, offset);
+ MathTools.rotate(q, offset, dir);
+ return dir;
+ }
+ } else {
+ if (next != null) {
+ PipeControlPoint pcp = this;
+ Vector3d dir = new Vector3d();
+ dir.sub(next.getWorldPosition(),pcp.getWorldPosition());
+ if (dir.lengthSquared() > MathTools.NEAR_ZERO)
+ dir.normalize();
+ Quat4d q = getControlPointOrientationQuat(dir, pcp.getRotationAngle() != null ? pcp.getRotationAngle() : 0.0);
+ AxisAngle4d aa = new AxisAngle4d(MathTools.Y_AXIS,pcp.getTurnAngle() == null ? 0.0 : pcp.getTurnAngle());
+ Quat4d q2 = MathTools.getQuat(aa);
+ Vector3d v = new Vector3d(1.,0.,0.);
+ Vector3d offset = new Vector3d();
+ MathTools.rotate(q2, v, offset);
+ MathTools.rotate(q, offset, dir);
+ return dir;
+ }
+ }
+ }
+ return null;
}
-
-
-
-
-
-
public void insert(PipeControlPoint previous, PipeControlPoint next) {
// inserting an offsetpoint is error,
if (isDualSub())
- throw new RuntimeException();
+ throw new RuntimeException("Dual sub points cannot be inserted.");
// size change control point cannot be inserted this way, because it ends PipeRun
if (isSizeChange())
- throw new RuntimeException();
+ throw new RuntimeException("Size change points cannot be inserted.");
PipeRun piperun = previous.getPipeRun();
// and just to make sure that control point structure is not corrupted
if (getPipeRun() != null) {
if (piperun != getPipeRun() || piperun != next.getPipeRun())
- throw new RuntimeException();
+ throw new RuntimeException("All controls points must be located on the same pipe run");
} else {
piperun.addChild(this);
}
v.sub(next.getWorldPosition(),pcp.getWorldPosition());
return v;
} else {
- if (isVariableAngle())
- throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
if (previous == null) {
if (!isDirected())
throw new RuntimeException("Cannot calculate path leg direction for unconnected control point");
return getDirectedControlPointDirection();
} else {
+ if (isVariableAngle())
+ throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
if (isInline()) {
PipeControlPoint pcp = this;
if (pcp.isDualSub()) {
Vector3d v = new Vector3d();
v.sub(getWorldPosition(),previous.getWorldPosition());
return v;
+ } else if (isTurn() && isFixed() && !_getReversed()) {
+ return getDirection(Direction.NEXT);
}
throw new RuntimeException("Missing implementation");
}
v.sub(previous.getWorldPosition(),pcp.getWorldPosition());
return v;
} else {
- if (isVariableAngle())
- throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
if (next == null) {
if (!isDirected())
throw new RuntimeException("Cannot calculate path leg direction for unconnected control point");
v.negate();
return v;
} else {
- if (isInline()) {
+ if (isVariableAngle())
+ throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
+ if (isInline()) {
PipeControlPoint pcp = this;
if (pcp.isDualInline()) {
pcp = pcp.getSubPoint().get(0);
Vector3d v = new Vector3d();
v.sub(getWorldPosition(),next.getWorldPosition());
return v;
- }
+ } else if (isTurn() && isFixed() && _getReversed()) {
+ return getDirection(Direction.PREVIOUS);
+ }
throw new RuntimeException("Missing implementation");
}
}
updatePathLeg(new UpdateStruct2(start, startPoint, list, end, endPoint, dir, offset, hasOffsets, iter, reversed, toRemove, updated), lengthChange);
}
-
+
+ private static boolean asDirected(PipeControlPoint pcp, Direction direction) {
+ if (pcp.isDirected())
+ return true;
+ if (pcp.isTurn() && pcp.isFixed()) {
+ if (!pcp._getReversed())
+ return direction == Direction.NEXT;
+ else
+ return direction == Direction.PREVIOUS;
+ }
+ return false;
+ }
+
+ private static Vector3d direction(PipeControlPoint pcp, Direction direction) {
+ return pcp.getDirection(direction);
+ }
+
private static void updatePathLeg(UpdateStruct2 u, PathLegUpdateType lengthChange) throws Exception {
int directed = 0;
- if (u.start.isDirected())
+ if (asDirected(u.start, Direction.NEXT))
directed++;
- if (u.end.isDirected())
+ if (asDirected(u.end, Direction.PREVIOUS))
directed++;
switch (directed) {
case 0:
if (DEBUG)
System.out.println("PipingRules.updateFreePipeRun " + u + " " + lengthChange);
checkExpandPathLeg(u, lengthChange);
- if (u.start.isInline() || u.end.isInline())
+ if (u.start.isInline() || u.end.isInline() || u.start.isFixed() || u.end.isFixed())
processPathLeg(u, true, false);
}
boolean dcpStart = false;
boolean inlineEnd = false;
Vector3d position;
- if (u.start.isDirected()) {
+ if (asDirected(u.start, Direction.NEXT)) {
dcp = u.start;
other = u.end;
position = u.startPoint;
inlineEnd = u.start.isInline();
}
- Vector3d directedDirection = dcp.getDirection();
+ Vector3d directedDirection = direction(dcp, dcpStart ? Direction.NEXT : Direction.PREVIOUS);
Point3d directedEndPoint = new Point3d(u.endPoint);
if (u.hasOffsets)
directedEndPoint.add(u.offset);
double distance = t.length();
boolean aligned = (distance < ALLOWED_OFFSET);
if (aligned) {
+ if (u.start.isInline() || u.end.isInline() || u.start.isFixed() || u.end.isFixed())
+ processPathLeg(u, true, false);
checkExpandPathLeg(u, lengthChange, inlineEnd);
} else {
position1offset.sub(u.offset);
Point3d position2offset = new Point3d(position2);
position2offset.add(u.offset);
- Vector3d dir1 = dcp1.getDirection();
- Vector3d dir2 = dcp2.getDirection();
+ 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);
double d1 = position1.distance(new Point3d(p1));
private static double updateTurnControlPointTurn(PipeControlPoint tcp, PipeControlPoint prev, PipeControlPoint next) {
if (DEBUG)
System.out.println("PipingTools.updateTurnControlPointTurn()" + tcp);
- if (next == null || prev == null)
- return Math.PI; // FIXME : argh
- Vector3d middlePoint = tcp.getWorldPosition();
- Vector3d nextPoint = next.getWorldPosition();
- Vector3d prevPoint = prev.getWorldPosition();
- return updateTurnControlPointTurn(tcp, middlePoint, prevPoint, nextPoint);
+
+ if (!tcp.isFixed()) {
+ if (next == null || prev == null)
+ return Math.PI; // FIXME : argh
+ Vector3d middlePoint = tcp.getWorldPosition();
+ Vector3d nextPoint = next.getWorldPosition();
+ Vector3d prevPoint = prev.getWorldPosition();
+ return updateTurnControlPointTurn(tcp, middlePoint, prevPoint, nextPoint);
+ } else {
+ Vector3d dir;
+ if (!tcp._getReversed()) {
+ if (prev == null)
+ return Math.PI; // FIXME : argh
+
+ Vector3d middlePoint = tcp.getWorldPosition();
+ Vector3d prevPoint = prev.getWorldPosition();
+ dir = new Vector3d();
+ dir.sub(middlePoint, prevPoint);
+
+ } else {
+ if (next == null)
+ return Math.PI; // FIXME : argh
+
+ Vector3d middlePoint = tcp.getWorldPosition();
+ Vector3d nextPoint = next.getWorldPosition();
+ dir = new Vector3d();
+ dir.sub(nextPoint,middlePoint);
+ }
+ dir.normalize();
+
+ Quat4d q = PipeControlPoint.getControlPointOrientationQuat(dir, tcp.getRotationAngle() != null ? tcp.getRotationAngle() : 0.0);
+ Vector3d v = new Vector3d();
+ MathTools.rotate(q, MathTools.Y_AXIS,v);
+ tcp.setTurnAxis(v);
+ tcp.setWorldOrientation(q);
+ return tcp.getTurnAngle();
+ }
}
/**