1 package org.simantics.plant3d.scenegraph.controlpoint;
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collection;
8 import javax.vecmath.AxisAngle4d;
9 import javax.vecmath.Matrix3d;
10 import javax.vecmath.Quat4d;
11 import javax.vecmath.Tuple3d;
12 import javax.vecmath.Vector3d;
14 import org.simantics.g3d.math.MathTools;
15 import org.simantics.g3d.property.annotations.GetPropertyValue;
16 import org.simantics.g3d.scenegraph.G3DNode;
17 import org.simantics.plant3d.scenegraph.IP3DNode;
18 import org.simantics.plant3d.scenegraph.PipeRun;
19 import org.simantics.plant3d.scenegraph.PipelineComponent;
21 import vtk.vtkRenderer;
24 public class PipeControlPoint extends G3DNode implements IP3DNode {
26 public enum Type{INLINE,TURN,END};
27 public enum Direction{NEXT,PREVIOUS};
28 public enum PositionType {SPLIT,NEXT,PREVIOUS,PORT}
30 private PipelineComponent component;
33 private boolean fixed = true;
34 private boolean rotate = false;
35 private boolean deletable = true;
36 private boolean sub = false;
38 public PipeControlPoint(PipelineComponent component) {
39 this.component = component;
40 if (component.getPipeRun() != null)
41 component.getPipeRun().addChild(this);
45 public PipeControlPoint(PipelineComponent component, PipeRun piperun) {
46 this.component = component;
47 piperun.addChild(this);
51 public void update(vtkRenderer ren) {
53 PipingRules.requestUpdate(this);
54 } catch (Exception e) {
60 public PipeRun getPipeRun() {
61 return (PipeRun)getParent();
64 public PipelineComponent getPipelineComponent() {
68 public Type getType() {
72 public void setType(Type type) {
76 @GetPropertyValue(name="Fixed",tabId="Debug",value="fixed")
77 public boolean isFixed() {
82 public void setFixed(boolean fixed) {
86 @GetPropertyValue(name="Rotate",tabId="Debug",value="rotate")
87 public boolean isRotate() {
92 public void setRotate(boolean rotate) {
96 public void setSub(boolean sub) {
100 @GetPropertyValue(name="Deletable",tabId="Debug",value="deletable")
101 public boolean isDeletable() {
105 public void setDeletable(boolean deletable) {
106 this.deletable = deletable;
109 public boolean isPathLegEnd() {
110 return type != Type.INLINE;
113 public boolean isEnd() {
114 return type == Type.END;
117 public boolean isTurn() {
118 return type == Type.TURN;
121 public boolean isInline() {
122 return type == Type.INLINE;
125 public boolean isDirected() {
126 return fixed && isEnd();
129 public boolean isNonDirected() {
130 return !fixed && isEnd();
133 public boolean isVariableLength() {
134 return !fixed && isInline();
137 public boolean isVariableAngle() {
138 return !fixed && isTurn();
141 public boolean isBranchEnd() {
142 return deletable && isEnd();
145 public boolean isOffset() {
146 return offset != null;
149 public boolean isDualSub() {
150 return parent != null && sub;
153 public boolean isDualInline() {
154 return children.size() == 1 && children.get(0).isDualSub();
157 public boolean isSizeChange() {
158 if (children.size() == 0)
162 return getPipeRun() != children.get(0).getPipeRun();
166 private PipeControlPoint next;
167 private PipeControlPoint previous;
169 public PipeControlPoint getNext() {
173 public PipeControlPoint getPrevious() {
177 public void setNext(PipeControlPoint next) {
178 if (isEnd() && previous != null && next != null)
179 throw new RuntimeException("End control points are allowed to have only one connection");
180 // if (next != null && getPipeRun() == null)
181 // throw new RuntimeException("Cannot connect control point befor piperun has been set");
183 if (component != null) {
184 if (parent == null || sub)
185 component.setNext(next != null ? next.component : null);
187 component.setBranch0(next != null ? next.component : null);
193 public void setPrevious(PipeControlPoint previous) {
194 if (isEnd() && next != null && previous != null)
195 throw new RuntimeException("End control points are allowed to have only one connection");
196 // if (previous != null && getPipeRun() == null)
197 // throw new RuntimeException("Cannot connect control point befor piperun has been set");
198 this.previous = previous;
199 if (component != null) {
200 if (parent == null || sub)
201 component.setPrevious(previous != null ? previous.component : null);
203 component.setBranch0(previous != null ? previous.component : null);
209 public PipeControlPoint parent;
210 public List<PipeControlPoint> children = new ArrayList<PipeControlPoint>();
212 public List<PipeControlPoint> getSubPoint() {
216 public PipeControlPoint getParentPoint() {
227 private double length;
228 private Double turnAngle;
229 private Vector3d turnAxis;
231 private Double offset;
232 private Double rotationAngle;
234 @GetPropertyValue(name="Length",tabId="Debug",value="length")
235 public double getLength() {
239 public void setLength(double l) {
240 if (Double.isInfinite(l) || Double.isNaN(l)) {
243 if (Math.abs(this.length-l) < MathTools.NEAR_ZERO)
246 firePropertyChanged("length");
248 getSubPoint().get(0).setLength(l);
251 @GetPropertyValue(name="Turn Angle",tabId="Debug",value="turnAngle")
252 public Double getTurnAngle() {
256 @GetPropertyValue(name="Turn Axis",tabId="Debug",value="turnAxis")
257 public Vector3d getTurnAxis() {
261 @GetPropertyValue(name="Offset",tabId="Debug",value="offset")
262 public Double getOffset() {
266 @GetPropertyValue(name="Rotation Angle",tabId="Debug",value="rotationAngle")
267 public Double getRotationAngle() {
268 return rotationAngle;
271 public void setTurnAngle(Double turnAngle) {
272 if (Double.isInfinite(turnAngle) || Double.isNaN(turnAngle)) {
275 if (this.turnAngle != null && Math.abs(this.turnAngle-turnAngle) < MathTools.NEAR_ZERO)
277 this.turnAngle = turnAngle;
278 firePropertyChanged("turnAngle");
281 public void setTurnAxis(Vector3d turnAxis) {
282 this.turnAxis = turnAxis;
283 firePropertyChanged("turnAxis");
286 public void setOffset(Double offset) {
287 if (Double.isInfinite(offset) || Double.isNaN(offset)) {
290 if (this.offset != null && Math.abs(this.offset-offset) < MathTools.NEAR_ZERO)
292 this.offset = offset;
293 firePropertyChanged("offset");
296 public void setRotationAngle(Double rotationAngle) {
297 if (Double.isInfinite(rotationAngle) || Double.isNaN(rotationAngle)) {
300 if (this.rotationAngle != null && Math.abs(this.rotationAngle-rotationAngle) < MathTools.NEAR_ZERO)
302 this.rotationAngle = rotationAngle;
303 firePropertyChanged("rotationAngle");
306 public Vector3d getSizeChangeOffsetVector(Vector3d dir) {
308 if (rotationAngle == null)
309 q = getControlPointOrientationQuat(dir, 0.0);
311 q = getControlPointOrientationQuat(dir, rotationAngle);
312 Vector3d v = new Vector3d(0.0,offset,0.0);
313 Vector3d offset = new Vector3d();
314 MathTools.rotate(q, v, offset);
318 public Vector3d getSizeChangeOffsetVector() {
320 if (rotationAngle == null)
321 q = getControlPointOrientationQuat(0.0);
323 q = getControlPointOrientationQuat(rotationAngle);
324 Vector3d v = new Vector3d(0.0,offset,0.0);
325 Vector3d offset = new Vector3d();
326 MathTools.rotate(q, v, offset);
330 @GetPropertyValue(name="Next",tabId="Debug",value="next")
331 private String getNextString() {
334 return next.toString();
337 @GetPropertyValue(name="Previous",tabId="Debug",value="previous")
338 private String getPrevString() {
339 if (previous == null)
341 return previous.toString();
344 @GetPropertyValue(name="Sub",tabId="Debug",value="sub")
345 private String getSubString() {
346 if (children.size() == 0)
348 return Arrays.toString(children.toArray());
351 @GetPropertyValue(name="Type",tabId="Debug",value="type")
352 public String getTypeString() {
356 public Quat4d getControlPointOrientationQuat(double angle) {
358 if (turnAxis == null) {
359 Vector3d dir = getPathLegDirection(Direction.NEXT);
360 if (dir.lengthSquared() > MathTools.NEAR_ZERO)
362 return getControlPointOrientationQuat(dir, angle);
364 Vector3d dir = getPathLegDirection(Direction.PREVIOUS);
366 if (dir.lengthSquared() > MathTools.NEAR_ZERO)
368 return getControlPointOrientationQuat(dir, turnAxis, angle);
374 public static Quat4d getControlPointOrientationQuat(Vector3d dir, double angle) {
375 if (dir.lengthSquared() < MathTools.NEAR_ZERO)
376 return MathTools.getIdentityQuat();
379 Vector3d up = new Vector3d(0.0, 1.0, 0.0);
380 double a = up.angle(dir);
381 if (a < 0.1 || (Math.PI - a) < 0.1) {
382 up.set(1.0, 0.0, 0.0);
386 return getControlPointOrientationQuat(dir, up, angle);
389 public static Quat4d getControlPointOrientationQuat(Vector3d dir, Vector3d up, double angle) {
390 if (dir.lengthSquared() < MathTools.NEAR_ZERO)
391 return MathTools.getIdentityQuat();
393 final Vector3d front = new Vector3d(1.0,0.0,0.0);
395 Quat4d q1 = new Quat4d();
398 Vector3d right = new Vector3d();
400 right.cross(dir, up);
401 up.cross(right, dir);
405 Matrix3d m = new Matrix3d();
416 //q1.set(m); MathTools contains more stable conversion
417 MathTools.getQuat(m, q1);
419 // if (DEBUG) System.out.println("PipingTools.getPipeComponentOrientationQuat() " + dir+ " " + up + " " + right);
421 Quat4d q2 = new Quat4d();
422 q2.set(new AxisAngle4d(front, angle));
427 public Vector3d getDirection() {
428 return getDirectedControlPointDirection();
437 public void insert(PipeControlPoint previous, PipeControlPoint next) {
438 // inserting an offsetpoint is error,
440 throw new RuntimeException();
441 // size change control point cannot be inserted this way, because it ends PipeRun
443 throw new RuntimeException();
444 PipeRun piperun = previous.getPipeRun();
445 // and just to make sure that control point structure is not corrupted
446 if (getPipeRun() != null) {
447 if (piperun != getPipeRun() || piperun != next.getPipeRun())
448 throw new RuntimeException();
450 piperun.addChild(this);
453 // insert new BranchControlPoint between straight's control points
454 PipeControlPoint previousNext = previous.getNext();
455 PipeControlPoint previousPrevious = previous.getPrevious();
457 PipeControlPoint offsetCP = null;
459 offsetCP = getSubPoint().get(0);
461 if (previousNext != null && previousNext == next) {
462 if (previous.isDualInline()) {
463 throw new RuntimeException();
465 if (next.isDualSub()) {
466 throw new RuntimeException();
468 previous.setNext(this);
469 this.setPrevious(previous);
470 if (previous.isDualSub()) {
471 previous.getParentPoint().setNext(this);
475 if (offsetCP == null) {
476 next.setPrevious(this);
478 next.setPrevious(offsetCP);
479 offsetCP.setNext(next);
480 offsetCP.setPrevious(previous);
483 if (next.isDualInline()) {
484 next.getSubPoint().get(0).setPrevious(this);
486 } else if (previousPrevious != null && previousPrevious == next) {
487 // control point were given in reverse order
488 if (next.isDualInline())
489 throw new RuntimeException();
490 if (previous.isDualSub())
491 throw new RuntimeException();
493 this.setNext(previous);
494 if (offsetCP == null) {
495 previous.setNext(this);
497 previous.setPrevious(offsetCP);
498 offsetCP.setNext(previous);
499 offsetCP.setPrevious(next);
501 if (previous.isDualInline()) {
502 previous.getSubPoint().get(0).setPrevious(this);
504 this.setPrevious(next);
506 if (next.isDualSub()) {
507 next.getParentPoint().setNext(this);
511 throw new RuntimeException();
514 PipingRules.validate(piperun);
519 public void insert(PipeControlPoint pcp, Direction direction) {
521 throw new RuntimeException();
522 if (direction == Direction.NEXT) {
523 // if direction is next, user must have given OffsetPoint
524 if (pcp.isDualInline())
525 throw new RuntimeException();
526 // basic next/prev links
528 this.setPrevious(pcp);
529 // and last take care of sizechange / offset points
530 if (pcp.isDualSub()) {
531 pcp.getParentPoint().setNext(this);
533 if (isDualInline()) {
534 getSubPoint().get(0).setPrevious(this);
537 // if direction is previous, user must have given sizechange
539 throw new RuntimeException();
540 // previous direction is more complicated, since if newCP is SizeChangeControlPoint,
541 // we must link pcp to newCP's OffsetPoint
542 PipeControlPoint nocp = null;
543 if (isDualInline()) {
544 nocp = getSubPoint().get(0);
548 pcp.setPrevious(this);
550 pcp.setPrevious(nocp);
553 if (pcp.isDualInline()) {
554 PipeControlPoint ocp = pcp.getSubPoint().get(0);
556 ocp.setPrevious(this);
558 ocp.setPrevious(nocp);
562 PipingRules.validate(getPipeRun());
565 public Vector3d getDirectedControlPointDirection() {
566 assert (isDirected());
567 Vector3d dir = new Vector3d();
568 MathTools.rotate(getWorldOrientation(), new Vector3d(1.0, 0.0, 0.0), dir);
573 public Vector3d getPathLegDirection(Direction direction) {
574 if (direction == Direction.NEXT) {
576 PipeControlPoint pcp = this;
577 if (pcp.isDualInline()) {
578 pcp = pcp.getSubPoint().get(0);
580 Vector3d v = new Vector3d();
581 v.sub(next.getWorldPosition(),pcp.getWorldPosition());
584 if (isVariableAngle())
585 throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
586 if (previous == null) {
588 throw new RuntimeException("Cannot calculate path leg direction for unconnected control point");
589 return getDirectedControlPointDirection();
593 PipeControlPoint pcp = this;
594 if (pcp.isDualSub()) {
595 pcp = pcp.getParentPoint();
597 Vector3d v = new Vector3d();
598 v.sub(pcp.getWorldPosition(),previous.getWorldPosition());
600 } else if (isDirected()) {
601 return getDirectedControlPointDirection();
602 } else if (isEnd()) {
603 Vector3d v = new Vector3d();
604 v.sub(getWorldPosition(),previous.getWorldPosition());
607 throw new RuntimeException("Missing implementation");
611 if (previous != null) {
612 PipeControlPoint pcp = this;
614 pcp = getParentPoint();
615 Vector3d v = new Vector3d();
616 v.sub(previous.getWorldPosition(),pcp.getWorldPosition());
619 if (isVariableAngle())
620 throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
623 throw new RuntimeException("Cannot calculate path leg direction for unconnected control point");
624 Vector3d v = getDirectedControlPointDirection();
629 PipeControlPoint pcp = this;
630 if (pcp.isDualInline()) {
631 pcp = pcp.getSubPoint().get(0);
633 Vector3d v = new Vector3d();
634 v.sub(pcp.getWorldPosition(),next.getWorldPosition());
636 } else if (isDirected()) {
637 Vector3d v = getDirectedControlPointDirection();
640 } else if (isEnd()) {
641 Vector3d v = new Vector3d();
642 v.sub(getWorldPosition(),next.getWorldPosition());
645 throw new RuntimeException("Missing implementation");
651 public void getInlineControlPointEnds(Tuple3d p1, Tuple3d p2) {
654 Vector3d pos = getWorldPosition();
655 Vector3d dir = getPathLegDirection(Direction.NEXT);
657 dir.scale(length * 0.5);
664 public void getControlPointEnds(Tuple3d p1, Tuple3d p2) {
665 Vector3d pos = getWorldPosition();
666 Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS);
668 Vector3d dir2 = getPathLegDirection(Direction.NEXT);
671 dir1.scale(length * 0.5);
672 dir2.scale(length * 0.5);
683 public void getInlineControlPointEnds(Tuple3d p1, Tuple3d p2, Vector3d dir) {
686 Vector3d pos = getWorldPosition();
687 dir.set(getPathLegDirection(Direction.NEXT));
689 dir.scale(length * 0.5);
696 public void getInlineControlPointEnds(Tuple3d center, Tuple3d p1, Tuple3d p2, Vector3d dir) {
699 Vector3d pos = getWorldPosition();
701 dir.set(getPathLegDirection(Direction.NEXT));
703 dir.scale(length * 0.5);
710 public double getInlineLength() {
711 if (type == Type.TURN)
713 else if (type == Type.INLINE)
718 public Vector3d getRealPosition(PositionType type) {
719 Vector3d pos = getWorldPosition();
722 Vector3d dir = getPathLegDirection(Direction.NEXT);
723 double length = getInlineLength();
730 Vector3d dir = getPathLegDirection(Direction.PREVIOUS);
731 double length = getInlineLength();
738 // IEntity portDir = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.HasDirection);
739 // TODO : how we calculated needed space for a port; does it has an offset from control point's position or not?
749 public void getInlineMovement(Tuple3d start, Tuple3d end) {
750 // FIXME : check type of neighbor components and allow movement on top of variable length components,
751 // find proper range for movement (pcp's position is not)
752 PipeControlPoint p = previous.getPrevious();
753 PipeControlPoint n = next.getNext();
754 start.set(p.getWorldPosition());
755 end.set(n.getWorldPosition());
758 public PipeControlPoint findNextEnd() {
759 ArrayList<PipeControlPoint> t = new ArrayList<PipeControlPoint>();
760 return findNextEnd( t);
763 public PipeControlPoint findPreviousEnd() {
764 ArrayList<PipeControlPoint> t = new ArrayList<PipeControlPoint>();
765 return findPreviousEnd(t);
768 public PipeControlPoint findNextEnd(List<PipeControlPoint> nextList) {
770 PipeControlPoint pcp = null;
771 PipeControlPoint p = null;
772 if (nextList.size() == 0)
776 p = nextList.get(nextList.size() - 1);
781 if (nextList.size() > 0)
782 nextList.remove(nextList.size() - 1);
783 // if (DEBUG) System.out.println(" " + pcp.getResource() + " not full");
787 if (pcp.isPathLegEnd()) {
788 //if (DEBUG) System.out.println(" " + pcp.getResource());
792 // if (DEBUG) System.out.print(" " + pcp.getResource());
797 public PipeControlPoint findPreviousEnd(List<PipeControlPoint> prevList) {
799 PipeControlPoint pcp = null;
800 PipeControlPoint p = null;
801 if (prevList.size() == 0)
805 p = prevList.get(prevList.size() - 1);
807 pcp = p.getPrevious();
810 if (prevList.size() > 0)
811 prevList.remove(prevList.size() - 1);
812 // if (DEBUG) System.out.println(" " + pcp.getResource() + " not full");
815 if (pcp.isPathLegEnd()) {
816 // if (DEBUG) System.out.println(" " + pcp.getResource());
820 // if (DEBUG)System.out.print(" " + pcp.getResource());
825 public void _remove() {
826 if (component == null && next == null && previous == null)
828 if (isDualInline() || isDualSub()) {
832 PipeRun pipeRun = getPipeRun();
836 PipeControlPoint additionalRemove = null;
837 if (!PipingRules.isEnabled()) {
842 PipeControlPoint currentPrev = previous;
843 PipeControlPoint currentNext = next;
844 if (currentNext == null && currentPrev == null) {
846 pipeRun.remChild(this);
849 if (currentNext != null && currentPrev != null) {
851 if (currentNext.isBranchEnd()) {
853 // currentNext.setPrevious(null);
854 // currentNext.setNext(null);
855 currentNext.remove();
859 if (currentPrev.isBranchEnd()) {
861 // currentPrev.setPrevious(null);
862 // currentPrev.setNext(null);
863 currentPrev.remove();
867 if (link && currentPrev.isDirected() && currentNext.isDirected()) {
870 if (currentNext == null) {
872 } else if (currentNext.isDualInline()) {
873 PipeControlPoint sccp = currentNext;
874 PipeControlPoint ocp = sccp.getSubPoint().get(0);
876 throw new RuntimeException("Removing PipeControlPoint " + this+ " structure damaged, no offset control point");
879 sccp.setPrevious(currentPrev);
880 ocp.setPrevious(currentPrev);
882 sccp.setPrevious(null);
883 ocp.setPrevious(null);
886 } else if (currentNext.isDualSub()) {
887 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, next control point is offset control point");
888 } else if (currentNext.previous == this) {
890 currentNext.setPrevious(currentPrev);
892 currentNext.setPrevious(null);
896 throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
898 if (currentPrev == null) {
900 } else if (currentPrev.isDualInline()) {
901 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, previous control point is size change control point");
902 } else if (currentPrev.isDualSub()) {
903 PipeControlPoint ocp = currentPrev;
904 PipeControlPoint sccp = ocp.getParentPoint();
906 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, no size change control point");
908 ocp.setNext(currentNext);
909 sccp.setNext(currentNext);
915 } else if (currentPrev.next == this) {
917 currentPrev.setNext(currentNext);
919 currentPrev.setNext(null);
923 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged");
926 if (currentNext.isVariableLength() && currentPrev.isVariableLength()) {
927 // we have to join them into single variable length component.
928 additionalRemove = currentPrev;
929 //currentPrev.remove();
932 // FIXME : pipe run must be split into two parts, since the control point structure is no more continuous.
934 } else if (next != null) {
935 if (next.isDualInline()) {
936 PipeControlPoint sccp = next;
937 PipeControlPoint ocp = sccp.getSubPoint().get(0);
939 throw new RuntimeException("Removing PipeControlPoint " + this+ " structure damaged, no offset control point");
941 sccp.setPrevious(null);
942 ocp.setPrevious(null);
943 } else if (next.isDualSub()) {
944 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, next control point is offset control point");
945 } else if (next.previous == this) {
946 next.setPrevious(null);
948 throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
951 } else { //(previous != null)
952 if(previous.isDualInline()) {
953 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, previous control point is size change control point");
954 } else if (previous.isDualSub()) {
955 PipeControlPoint ocp = previous;
956 PipeControlPoint sccp = ocp.getParentPoint();
958 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, no size change control point");
962 } else if (previous.next == this) {
963 previous.setNext(null);
965 throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
969 if (children.size() > 0 ) {
971 } else if (parent!= null) {
978 pipeRun.remChild(this);
979 checkRemove(pipeRun);
980 if (PipingRules.isEnabled() && pipeRun.getParent() != null && pipeRun.getControlPoints().size() > 0)
981 PipingRules.validate(pipeRun);
982 if (additionalRemove != null)
983 additionalRemove.remove();
986 public void remove() {
987 PipeControlPoint currentPrev = previous;
988 PipeControlPoint currentNext = next;
991 if (currentNext != null)
992 PipingRules.requestUpdate(currentNext);
993 if (currentPrev != null)
994 PipingRules.requestUpdate(currentPrev);
995 } catch (Exception e) {
1000 private void checkRemove(PipeRun pipeRun) {
1001 Collection<PipeControlPoint> points = pipeRun.getControlPoints();
1002 if (points.size() == 0) {
1004 } else if (points.size() == 1) {
1005 PipeControlPoint pcp = points.iterator().next();
1006 if (pcp.isDeletable())
1011 private void removeDualPoint() {
1012 if (previous != null)
1013 previous.setNext(null);
1015 next.setPrevious(null);
1016 PipeControlPoint ocp;
1017 PipeControlPoint sccp;
1018 if (isDualInline()) {
1020 ocp = getSubPoint().get(0);
1023 sccp = getParentPoint();
1025 PipeRun p1 = ocp.getPipeRun();
1026 PipeRun p2 = sccp.getPipeRun();
1028 ocp.removeComponent();
1029 sccp.removeComponent();
1034 // TODO : now we assume that this is size change, and we do
1035 if (ocp.next != null)
1036 ocp.next.setPrevious(null);
1037 if (ocp.previous != null)
1038 ocp.previous.setNext(null);
1039 if (sccp.next != null)
1040 sccp.next.setPrevious(null);
1041 if (sccp.previous != null)
1042 sccp.previous.setNext(null);
1044 ocp.setPrevious(null);
1046 sccp.setPrevious(null);
1052 private void removeSubPoints() {
1053 for (PipeControlPoint p : children) {
1054 // TODO : this may affect delete routine, since classification of the point changes.
1061 private void removeParentPoint() {
1062 throw new RuntimeException("Child points cannot be removed directly");
1065 private void removeComponent() {
1066 if (component == null)
1068 PipelineComponent next = component.getNext();
1069 PipelineComponent prev = component.getNext();
1071 if (next.getNext() == component)
1073 else if (next.getPrevious() == component)
1074 next.setPrevious(null);
1077 if (prev.getNext() == component)
1079 else if (prev.getPrevious() == component)
1080 prev.setPrevious(null);
1082 PipelineComponent comp = component;
1089 public void setOrientation(Quat4d orientation) {
1090 if (MathTools.equals(orientation, getOrientation()))
1092 super.setOrientation(orientation);
1093 if (getParentPoint() == null && component != null)
1094 component._setWorldOrientation(getWorldOrientation());
1099 public void setPosition(Vector3d position) {
1100 if (MathTools.equals(position, getPosition()))
1102 if (Double.isNaN(position.x) || Double.isNaN(position.y) || Double.isNaN(position.z))
1103 throw new IllegalArgumentException("NaN is not supported");
1104 super.setPosition(position);
1105 if (getParentPoint() == null && component != null)
1106 component._setWorldPosition(getWorldPosition());
1110 private void updateSubPoint() {
1112 if (next == null && previous == null) {
1113 for (PipeControlPoint sub : getSubPoint()) {
1114 sub.setWorldPosition(getWorldPosition());
1115 sub.setWorldOrientation(getWorldOrientation());
1119 for (PipeControlPoint sub : getSubPoint()) {
1120 Vector3d wp = getWorldPosition();
1121 wp.add(getSizeChangeOffsetVector());
1122 sub.setWorldPosition(wp);
1123 sub.setWorldOrientation(getWorldOrientation());
1126 for (PipeControlPoint sub : getSubPoint()) {
1127 sub.setWorldPosition(getWorldPosition());
1128 sub.setWorldOrientation(getWorldOrientation());
1134 public void _setWorldPosition(Vector3d position) {
1135 Vector3d localPos = getLocalPosition(position);
1136 super.setPosition(localPos);
1140 public void _setWorldOrientation(Quat4d orientation) {
1141 Quat4d localOr = getLocalOrientation(orientation);
1142 super.setOrientation(localOr);
1147 public String toString() {
1148 return getClass().getName() + "@" + Integer.toHexString(hashCode());