X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.plant3d%2Fsrc%2Forg%2Fsimantics%2Fplant3d%2Fscenegraph%2Fcontrolpoint%2FPipeControlPoint.java;h=8e3e6bbdc1c926d28270e3900f7d8648a7f01cf3;hb=refs%2Fchanges%2F27%2F3127%2F1;hp=ecaeb7ae7c41d2b70017d4de433dfac968270ecc;hpb=3b5c59eca31e9db10c1a1dc6d244d6fd4f3578a2;p=simantics%2F3d.git diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java index ecaeb7ae..8e3e6bbd 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/controlpoint/PipeControlPoint.java @@ -7,6 +7,7 @@ import java.util.List; import javax.vecmath.AxisAngle4d; import javax.vecmath.Matrix3d; +import javax.vecmath.Point3d; import javax.vecmath.Quat4d; import javax.vecmath.Tuple3d; import javax.vecmath.Vector3d; @@ -22,14 +23,16 @@ import vtk.vtkRenderer; public class PipeControlPoint extends G3DNode implements IP3DNode { + + private static boolean DEBUG = false; - public enum Type{INLINE,TURN,END}; + public enum PointType{INLINE,TURN,END}; public enum Direction{NEXT,PREVIOUS}; public enum PositionType {SPLIT,NEXT,PREVIOUS,PORT} private PipelineComponent component; - private Type type; + private PointType type; private boolean fixed = true; private boolean rotate = false; private boolean reverse = false; @@ -66,11 +69,11 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return component; } - public Type getType() { + public PointType getType() { return type; } - public void setType(Type type) { + public void setType(PointType type) { this.type = type; } @@ -116,19 +119,19 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } public boolean isPathLegEnd() { - return type != Type.INLINE; + return type != PointType.INLINE; } public boolean isEnd() { - return type == Type.END; + return type == PointType.END; } public boolean isTurn() { - return type == Type.TURN; + return type == PointType.TURN; } public boolean isInline() { - return type == Type.INLINE; + return type == PointType.INLINE; } public boolean isDirected() { @@ -186,8 +189,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public void setNext(PipeControlPoint next) { if (isEnd() && previous != null && next != null) throw new RuntimeException("End control points are allowed to have only one connection"); -// if (next != null && getPipeRun() == null) -// throw new RuntimeException("Cannot connect control point befor piperun has been set"); + if (this.next == next) + return; + if (DEBUG) System.out.println(this + " next " + next); this.next = next; if (component != null) { if (parent == null || sub) @@ -202,8 +206,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public void setPrevious(PipeControlPoint previous) { if (isEnd() && next != null && previous != null) throw new RuntimeException("End control points are allowed to have only one connection"); -// if (previous != null && getPipeRun() == null) -// throw new RuntimeException("Cannot connect control point befor piperun has been set"); + if (this.previous == previous) + return; + if (DEBUG) System.out.println(this + " previous " + previous); this.previous = previous; if (component != null) { if (parent == null || sub) @@ -225,14 +230,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public PipeControlPoint getParentPoint() { return parent; } - - - - - - private double length; private Double turnAngle; private Vector3d turnAxis; @@ -283,8 +282,14 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { return reversed; } + public boolean _getReversed() { + if (reversed == null) + return false; + return reversed; + } + public void setTurnAngle(Double turnAngle) { - if (Double.isInfinite(turnAngle) || Double.isNaN(turnAngle)) { + if (turnAngle == null || Double.isInfinite(turnAngle) || Double.isNaN(turnAngle)) { return; } if (this.turnAngle != null && Math.abs(this.turnAngle-turnAngle) < MathTools.NEAR_ZERO) @@ -294,7 +299,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } public void setTurnAxis(Vector3d turnAxis) { - this.turnAxis = turnAxis; + if (this.turnAxis != null && MathTools.equals(turnAxis, this.turnAxis)) + return; + this.turnAxis = turnAxis; firePropertyChanged("turnAxis"); } @@ -320,7 +327,7 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { public void setReversed(Boolean reversed) { this.reversed = reversed; - firePropertyChanged("rotationAngle"); + firePropertyChanged("reversed"); } public Vector3d getSizeChangeOffsetVector(Vector3d dir) { @@ -466,28 +473,63 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { 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(); + else + return null; + 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(); + else + return null; + 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); } @@ -623,14 +665,14 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { 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()) { @@ -645,6 +687,8 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { 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"); } @@ -658,8 +702,6 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { 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"); @@ -667,7 +709,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { 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); @@ -683,7 +727,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { 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"); } } @@ -750,9 +796,9 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { } public double getInlineLength() { - if (type == Type.TURN) + if (type == PointType.TURN) return length; - else if (type == Type.INLINE) + else if (type == PointType.INLINE) return length * 0.5; return 0; } @@ -968,7 +1014,19 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { if (currentNext.isVariableLength() && currentPrev.isVariableLength()) { // we have to join them into single variable length component. additionalRemove = currentPrev; - //currentPrev.remove(); + // combine lengths and set the location of remaining control point to the center. + Point3d ps = new Point3d(); + Point3d pe = new Point3d(); + Point3d ns = new Point3d(); + Point3d ne = new Point3d(); + currentPrev.getInlineControlPointEnds(ps, pe); + currentNext.getInlineControlPointEnds(ns, ne); + double l = currentPrev.getLength() + currentNext.getLength(); + Vector3d cp = new Vector3d(); + cp.add(ps, ne); + cp.scale(0.5); + currentNext.setLength(l); + currentNext.setWorldPosition(cp); } } else { // FIXME : pipe run must be split into two parts, since the control point structure is no more continuous. @@ -1108,18 +1166,34 @@ public class PipeControlPoint extends G3DNode implements IP3DNode { if (component == null) return; PipelineComponent next = component.getNext(); - PipelineComponent prev = component.getNext(); + PipelineComponent prev = component.getPrevious(); + PipelineComponent br0 = component.getBranch0(); + component.setNext(null); + component.setPrevious(null); + component.setBranch0(null); if (next != null) { if (next.getNext() == component) next.setNext(null); else if (next.getPrevious() == component) next.setPrevious(null); + else if (next.getBranch0() == component) + next.setBranch0(null); } if (prev != null) { if (prev.getNext() == component) prev.setNext(null); else if (prev.getPrevious() == component) prev.setPrevious(null); + else if (prev.getBranch0() == component) + prev.setBranch0(null); + } + if (br0 != null) { + if (br0.getNext() == component) + prev.setNext(null); + else if (br0.getPrevious() == component) + prev.setPrevious(null); + else if (br0.getBranch0() == component) + br0.setBranch0(null); } PipelineComponent comp = component; component = null;