1 package org.simantics.plant3d.scenegraph.controlpoint;
3 import java.util.ArrayList;
4 import java.util.Collection;
7 import javax.vecmath.AxisAngle4d;
8 import javax.vecmath.Matrix3d;
9 import javax.vecmath.Quat4d;
10 import javax.vecmath.Tuple3d;
11 import javax.vecmath.Vector3d;
13 import org.simantics.g3d.math.MathTools;
14 import org.simantics.g3d.property.annotations.GetPropertyValue;
15 import org.simantics.g3d.scenegraph.G3DNode;
16 import org.simantics.plant3d.scenegraph.IP3DNode;
17 import org.simantics.plant3d.scenegraph.PipeRun;
18 import org.simantics.plant3d.scenegraph.PipelineComponent;
20 import vtk.vtkRenderer;
23 public class PipeControlPoint extends G3DNode implements IP3DNode {
25 public enum Type{INLINE,TURN,END};
26 public enum Direction{NEXT,PREVIOUS};
27 public enum PositionType {SPLIT,NEXT,PREVIOUS,PORT}
29 private PipelineComponent component;
32 private boolean fixed = true;
33 private boolean deletable = true;
34 private boolean sub = false;
36 public PipeControlPoint(PipelineComponent component) {
37 this.component = component;
38 if (component.getPipeRun() != null)
39 component.getPipeRun().addChild(this);
43 public PipeControlPoint(PipelineComponent component, PipeRun piperun) {
44 this.component = component;
45 piperun.addChild(this);
49 public void update(vtkRenderer ren) {
51 PipingRules.requestUpdate(this);
52 } catch (Exception e) {
58 public PipeRun getPipeRun() {
59 return (PipeRun)getParent();
62 public PipelineComponent getPipelineComponent() {
66 public Type getType() {
70 public void setType(Type type) {
74 @GetPropertyValue(name="Fixed",tabId="Debug",value="fixed")
75 public boolean isFixed() {
80 public void setFixed(boolean fixed) {
84 public void setSub(boolean sub) {
88 @GetPropertyValue(name="Deletable",tabId="Debug",value="deletable")
89 public boolean isDeletable() {
93 public void setDeletable(boolean deletable) {
94 this.deletable = deletable;
97 public boolean isPathLegEnd() {
98 return type != Type.INLINE;
101 public boolean isEnd() {
102 return type == Type.END;
105 public boolean isTurn() {
106 return type == Type.TURN;
109 public boolean isInline() {
110 return type == Type.INLINE;
113 public boolean isDirected() {
114 return fixed && isEnd();
117 public boolean isNonDirected() {
118 return !fixed && isEnd();
121 public boolean isVariableLength() {
122 return !fixed && isInline();
125 public boolean isVariableAngle() {
126 return !fixed && isTurn();
129 public boolean isBranchEnd() {
130 return deletable && isEnd();
133 public boolean isOffset() {
134 return offset != null;
137 public boolean isDualSub() {
138 return parent != null && sub;
141 public boolean isDualInline() {
142 return children.size() == 1 && children.get(0).isDualSub();
145 public boolean isSizeChange() {
146 if (children.size() == 0)
150 return getPipeRun() != children.get(0).getPipeRun();
154 private PipeControlPoint next;
155 private PipeControlPoint previous;
157 public PipeControlPoint getNext() {
161 public PipeControlPoint getPrevious() {
165 public void setNext(PipeControlPoint next) {
166 if (isEnd() && previous != null && next != null)
167 throw new RuntimeException("End control points are allowed to have only one connection");
168 // if (next != null && getPipeRun() == null)
169 // throw new RuntimeException("Cannot connect control point befor piperun has been set");
171 if (component != null) {
172 if (parent == null || sub)
173 component.setNext(next != null ? next.component : null);
175 component.setBranch0(next != null ? next.component : null);
181 public void setPrevious(PipeControlPoint previous) {
182 if (isEnd() && next != null && previous != null)
183 throw new RuntimeException("End control points are allowed to have only one connection");
184 // if (previous != null && getPipeRun() == null)
185 // throw new RuntimeException("Cannot connect control point befor piperun has been set");
186 this.previous = previous;
187 if (component != null) {
188 if (parent == null || sub)
189 component.setPrevious(previous != null ? previous.component : null);
191 component.setBranch0(previous != null ? previous.component : null);
197 public PipeControlPoint parent;
198 public List<PipeControlPoint> children = new ArrayList<PipeControlPoint>();
200 public List<PipeControlPoint> getSubPoint() {
204 public PipeControlPoint getParentPoint() {
215 private double length;
216 private Double turnAngle;
217 private Vector3d turnAxis;
219 private Double offset;
220 private Double rotationAngle;
222 @GetPropertyValue(name="Length",tabId="Debug",value="length")
223 public double getLength() {
227 public void setLength(double l) {
228 if (Double.isInfinite(l) || Double.isNaN(l)) {
231 if (Math.abs(this.length-l) < MathTools.NEAR_ZERO)
234 firePropertyChanged("length");
236 getSubPoint().get(0).setLength(l);
239 @GetPropertyValue(name="Turn Angle",tabId="Debug",value="turnAngle")
240 public Double getTurnAngle() {
244 @GetPropertyValue(name="Turn Axis",tabId="Debug",value="turnAxis")
245 public Vector3d getTurnAxis() {
249 @GetPropertyValue(name="Offset",tabId="Debug",value="offset")
250 public Double getOffset() {
254 @GetPropertyValue(name="Rotation Angle",tabId="Debug",value="rotationAngle")
255 public Double getRotationAngle() {
256 return rotationAngle;
259 public void setTurnAngle(Double turnAngle) {
260 if (Double.isInfinite(turnAngle) || Double.isNaN(turnAngle)) {
263 if (this.turnAngle != null && Math.abs(this.turnAngle-turnAngle) < MathTools.NEAR_ZERO)
265 this.turnAngle = turnAngle;
266 firePropertyChanged("turnAngle");
269 public void setTurnAxis(Vector3d turnAxis) {
270 this.turnAxis = turnAxis;
271 firePropertyChanged("turnAxis");
274 public void setOffset(Double offset) {
275 if (Double.isInfinite(offset) || Double.isNaN(offset)) {
278 if (this.offset != null && Math.abs(this.offset-offset) < MathTools.NEAR_ZERO)
280 this.offset = offset;
281 firePropertyChanged("offset");
284 public void setRotationAngle(Double rotationAngle) {
285 if (Double.isInfinite(rotationAngle) || Double.isNaN(rotationAngle)) {
288 if (this.rotationAngle != null && Math.abs(this.rotationAngle-rotationAngle) < MathTools.NEAR_ZERO)
290 this.rotationAngle = rotationAngle;
291 firePropertyChanged("rotationAngle");
294 public Vector3d getSizeChangeOffsetVector(Vector3d dir) {
295 if (rotationAngle == null)
297 Quat4d q = getControlPointOrientationQuat(dir, rotationAngle);
298 Vector3d v = new Vector3d(0.0,offset,0.0);
299 Vector3d offset = new Vector3d();
300 MathTools.rotate(q, v, offset);
304 public Vector3d getSizeChangeOffsetVector() {
305 if (rotationAngle == null)
307 Quat4d q = getControlPointOrientationQuat(rotationAngle);
308 Vector3d v = new Vector3d(0.0,offset,0.0);
309 Vector3d offset = new Vector3d();
310 MathTools.rotate(q, v, offset);
314 @GetPropertyValue(name="Next",tabId="Debug",value="next")
315 private String getNextString() {
318 return next.toString();
321 @GetPropertyValue(name="Previous",tabId="Debug",value="previous")
322 private String getPrevString() {
323 if (previous == null)
325 return previous.toString();
328 public Quat4d getControlPointOrientationQuat(double angle) {
330 if (turnAxis == null) {
331 Vector3d dir = getPathLegDirection(Direction.NEXT);
332 if (dir.lengthSquared() > MathTools.NEAR_ZERO)
334 return getControlPointOrientationQuat(dir, angle);
336 Vector3d dir = getPathLegDirection(Direction.PREVIOUS);
338 if (dir.lengthSquared() > MathTools.NEAR_ZERO)
340 return getControlPointOrientationQuat(dir, turnAxis, angle);
346 public static Quat4d getControlPointOrientationQuat(Vector3d dir, double angle) {
347 if (dir.lengthSquared() < MathTools.NEAR_ZERO)
348 return MathTools.getIdentityQuat();
351 Vector3d up = new Vector3d(0.0, 1.0, 0.0);
352 double a = up.angle(dir);
353 if (a < 0.1 || (Math.PI - a) < 0.1) {
354 up.set(1.0, 0.0, 0.0);
358 return getControlPointOrientationQuat(dir, up, angle);
361 public static Quat4d getControlPointOrientationQuat(Vector3d dir, Vector3d up, double angle) {
362 if (dir.lengthSquared() < MathTools.NEAR_ZERO)
363 return MathTools.getIdentityQuat();
365 final Vector3d front = new Vector3d(1.0,0.0,0.0);
367 Quat4d q1 = new Quat4d();
370 Vector3d right = new Vector3d();
372 right.cross(dir, up);
373 up.cross(right, dir);
377 Matrix3d m = new Matrix3d();
388 //q1.set(m); MathTools contains more stable conversion
389 MathTools.getQuat(m, q1);
391 // if (DEBUG) System.out.println("PipingTools.getPipeComponentOrientationQuat() " + dir+ " " + up + " " + right);
393 Quat4d q2 = new Quat4d();
394 q2.set(new AxisAngle4d(front, angle));
399 public Vector3d getDirection() {
400 return getDirectedControlPointDirection();
409 public void insert(PipeControlPoint previous, PipeControlPoint next) {
410 // inserting an offsetpoint is error,
412 throw new RuntimeException();
413 // size change control point cannot be inserted this way, because it ends PipeRun
415 throw new RuntimeException();
416 PipeRun piperun = previous.getPipeRun();
417 // and just to make sure that control point structure is not corrupted
418 if (getPipeRun() != null) {
419 if (piperun != getPipeRun() || piperun != next.getPipeRun())
420 throw new RuntimeException();
422 piperun.addChild(this);
425 // insert new BranchControlPoint between straight's control points
426 PipeControlPoint previousNext = previous.getNext();
427 PipeControlPoint previousPrevious = previous.getPrevious();
429 PipeControlPoint offsetCP = null;
431 offsetCP = getSubPoint().get(0);
433 if (previousNext != null && previousNext == next) {
434 if (previous.isDualInline()) {
435 throw new RuntimeException();
437 if (next.isDualSub()) {
438 throw new RuntimeException();
440 previous.setNext(this);
441 this.setPrevious(previous);
442 if (previous.isDualSub()) {
443 previous.getParentPoint().setNext(this);
447 if (offsetCP == null) {
448 next.setPrevious(this);
450 next.setPrevious(offsetCP);
451 offsetCP.setNext(next);
452 offsetCP.setPrevious(previous);
455 if (next.isDualInline()) {
456 next.getSubPoint().get(0).setPrevious(this);
458 } else if (previousPrevious != null && previousPrevious == next) {
459 // control point were given in reverse order
460 if (next.isDualInline())
461 throw new RuntimeException();
462 if (previous.isDualSub())
463 throw new RuntimeException();
465 this.setNext(previous);
466 if (offsetCP == null) {
467 previous.setNext(this);
469 previous.setPrevious(offsetCP);
470 offsetCP.setNext(previous);
471 offsetCP.setPrevious(next);
473 if (previous.isDualInline()) {
474 previous.getSubPoint().get(0).setPrevious(this);
476 this.setPrevious(next);
478 if (next.isDualSub()) {
479 next.getParentPoint().setNext(this);
483 throw new RuntimeException();
486 PipingRules.validate(piperun);
491 public void insert(PipeControlPoint pcp, Direction direction) {
493 throw new RuntimeException();
494 if (direction == Direction.NEXT) {
495 // if direction is next, user must have given OffsetPoint
496 if (pcp.isDualInline())
497 throw new RuntimeException();
498 // basic next/prev links
500 this.setPrevious(pcp);
501 // and last take care of sizechange / offset points
502 if (pcp.isDualSub()) {
503 pcp.getParentPoint().setNext(this);
505 if (isDualInline()) {
506 getSubPoint().get(0).setPrevious(this);
509 // if direction is previous, user must have given sizechange
511 throw new RuntimeException();
512 // previous direction is more complicated, since if newCP is SizeChangeControlPoint,
513 // we must link pcp to newCP's OffsetPoint
514 PipeControlPoint nocp = null;
515 if (isDualInline()) {
516 nocp = getSubPoint().get(0);
520 pcp.setPrevious(this);
522 pcp.setPrevious(nocp);
525 if (pcp.isDualInline()) {
526 PipeControlPoint ocp = pcp.getSubPoint().get(0);
528 ocp.setPrevious(this);
530 ocp.setPrevious(nocp);
534 PipingRules.validate(getPipeRun());
537 public Vector3d getDirectedControlPointDirection() {
538 assert (isDirected());
539 Vector3d dir = new Vector3d();
540 MathTools.rotate(getWorldOrientation(), new Vector3d(1.0, 0.0, 0.0), dir);
545 public Vector3d getPathLegDirection(Direction direction) {
546 if (direction == Direction.NEXT) {
548 PipeControlPoint pcp = this;
549 if (pcp.isDualInline()) {
550 pcp = pcp.getSubPoint().get(0);
552 Vector3d v = new Vector3d();
553 v.sub(next.getWorldPosition(),pcp.getWorldPosition());
556 if (isVariableAngle())
557 throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
558 if (previous == null) {
560 throw new RuntimeException("Cannot calculate path leg direction for unconnected control point");
561 return getDirectedControlPointDirection();
565 PipeControlPoint pcp = this;
566 if (pcp.isDualSub()) {
567 pcp = pcp.getParentPoint();
569 Vector3d v = new Vector3d();
570 v.sub(pcp.getWorldPosition(),previous.getWorldPosition());
572 } else if (isDirected()) {
573 return getDirectedControlPointDirection();
574 } else if (isEnd()) {
575 Vector3d v = new Vector3d();
576 v.sub(getWorldPosition(),previous.getWorldPosition());
579 throw new RuntimeException("Missing implementation");
583 if (previous != null) {
584 PipeControlPoint pcp = this;
586 pcp = getParentPoint();
587 Vector3d v = new Vector3d();
588 v.sub(previous.getWorldPosition(),pcp.getWorldPosition());
591 if (isVariableAngle())
592 throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point");
595 throw new RuntimeException("Cannot calculate path leg direction for unconnected control point");
596 Vector3d v = getDirectedControlPointDirection();
601 PipeControlPoint pcp = this;
602 if (pcp.isDualInline()) {
603 pcp = pcp.getSubPoint().get(0);
605 Vector3d v = new Vector3d();
606 v.sub(pcp.getWorldPosition(),next.getWorldPosition());
608 } else if (isDirected()) {
609 Vector3d v = getDirectedControlPointDirection();
612 } else if (isEnd()) {
613 Vector3d v = new Vector3d();
614 v.sub(getWorldPosition(),next.getWorldPosition());
617 throw new RuntimeException("Missing implementation");
623 public void getInlineControlPointEnds(Tuple3d p1, Tuple3d p2) {
626 Vector3d pos = getWorldPosition();
627 Vector3d dir = getPathLegDirection(Direction.NEXT);
629 dir.scale(length * 0.5);
636 public void getControlPointEnds(Tuple3d p1, Tuple3d p2) {
637 Vector3d pos = getWorldPosition();
638 Vector3d dir1 = getPathLegDirection(Direction.PREVIOUS);
640 Vector3d dir2 = getPathLegDirection(Direction.NEXT);
643 dir1.scale(length * 0.5);
644 dir2.scale(length * 0.5);
655 public void getInlineControlPointEnds(Tuple3d p1, Tuple3d p2, Vector3d dir) {
658 Vector3d pos = getWorldPosition();
659 dir.set(getPathLegDirection(Direction.NEXT));
661 dir.scale(length * 0.5);
668 public void getInlineControlPointEnds(Tuple3d center, Tuple3d p1, Tuple3d p2, Vector3d dir) {
671 Vector3d pos = getWorldPosition();
673 dir.set(getPathLegDirection(Direction.NEXT));
675 dir.scale(length * 0.5);
682 public double getInlineLength() {
683 if (type == Type.TURN)
685 else if (type == Type.INLINE)
690 public Vector3d getRealPosition(PositionType type) {
691 Vector3d pos = getWorldPosition();
694 Vector3d dir = getPathLegDirection(Direction.NEXT);
695 double length = getInlineLength();
702 Vector3d dir = getPathLegDirection(Direction.PREVIOUS);
703 double length = getInlineLength();
710 // IEntity portDir = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.HasDirection);
711 // TODO : how we calculated needed space for a port; does it has an offset from control point's position or not?
721 public void getInlineMovement(Tuple3d start, Tuple3d end) {
722 // FIXME : check type of neighbor components and allow movement on top of variable length components,
723 // find proper range for movement (pcp's position is not)
724 PipeControlPoint p = previous.getPrevious();
725 PipeControlPoint n = next.getNext();
726 start.set(p.getWorldPosition());
727 end.set(n.getWorldPosition());
730 public PipeControlPoint findNextEnd() {
731 ArrayList<PipeControlPoint> t = new ArrayList<PipeControlPoint>();
732 return findNextEnd( t);
735 public PipeControlPoint findPreviousEnd() {
736 ArrayList<PipeControlPoint> t = new ArrayList<PipeControlPoint>();
737 return findPreviousEnd(t);
740 public PipeControlPoint findNextEnd(List<PipeControlPoint> nextList) {
742 PipeControlPoint pcp = null;
743 PipeControlPoint p = null;
744 if (nextList.size() == 0)
748 p = nextList.get(nextList.size() - 1);
753 if (nextList.size() > 0)
754 nextList.remove(nextList.size() - 1);
755 // if (DEBUG) System.out.println(" " + pcp.getResource() + " not full");
759 if (pcp.isPathLegEnd()) {
760 //if (DEBUG) System.out.println(" " + pcp.getResource());
764 // if (DEBUG) System.out.print(" " + pcp.getResource());
769 public PipeControlPoint findPreviousEnd(List<PipeControlPoint> prevList) {
771 PipeControlPoint pcp = null;
772 PipeControlPoint p = null;
773 if (prevList.size() == 0)
777 p = prevList.get(prevList.size() - 1);
779 pcp = p.getPrevious();
782 if (prevList.size() > 0)
783 prevList.remove(prevList.size() - 1);
784 // 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 void _remove() {
798 if (component == null && next == null && previous == null)
800 if (isDualInline() || isDualSub()) {
804 PipeRun pipeRun = getPipeRun();
808 PipeControlPoint additionalRemove = null;
809 if (!PipingRules.isEnabled()) {
814 PipeControlPoint currentPrev = previous;
815 PipeControlPoint currentNext = next;
816 if (currentNext == null && currentPrev == null) {
818 pipeRun.remChild(this);
821 if (currentNext != null && currentPrev != null) {
823 if (currentNext.isBranchEnd()) {
825 // currentNext.setPrevious(null);
826 // currentNext.setNext(null);
827 currentNext.remove();
831 if (currentPrev.isBranchEnd()) {
833 // currentPrev.setPrevious(null);
834 // currentPrev.setNext(null);
835 currentPrev.remove();
839 if (link && currentPrev.isDirected() && currentNext.isDirected()) {
842 if (currentNext == null) {
844 } else if (currentNext.isDualInline()) {
845 PipeControlPoint sccp = currentNext;
846 PipeControlPoint ocp = sccp.getSubPoint().get(0);
848 throw new RuntimeException("Removing PipeControlPoint " + this+ " structure damaged, no offset control point");
851 sccp.setPrevious(currentPrev);
852 ocp.setPrevious(currentPrev);
854 sccp.setPrevious(null);
855 ocp.setPrevious(null);
858 } else if (currentNext.isDualSub()) {
859 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, next control point is offset control point");
860 } else if (currentNext.previous == this) {
862 currentNext.setPrevious(currentPrev);
864 currentNext.setPrevious(null);
868 throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
870 if (currentPrev == null) {
872 } else if (currentPrev.isDualInline()) {
873 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, previous control point is size change control point");
874 } else if (currentPrev.isDualSub()) {
875 PipeControlPoint ocp = currentPrev;
876 PipeControlPoint sccp = ocp.getParentPoint();
878 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, no size change control point");
880 ocp.setNext(currentNext);
881 sccp.setNext(currentNext);
887 } else if (currentPrev.next == this) {
889 currentPrev.setNext(currentNext);
891 currentPrev.setNext(null);
895 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged");
898 if (currentNext.isVariableLength() && currentPrev.isVariableLength()) {
899 // we have to join them into single variable length component.
900 additionalRemove = currentPrev;
901 //currentPrev.remove();
904 // FIXME : pipe run must be split into two parts, since the control point structure is no more continuous.
906 } else if (next != null) {
907 if (next.isDualInline()) {
908 PipeControlPoint sccp = next;
909 PipeControlPoint ocp = sccp.getSubPoint().get(0);
911 throw new RuntimeException("Removing PipeControlPoint " + this+ " structure damaged, no offset control point");
913 sccp.setPrevious(null);
914 ocp.setPrevious(null);
915 } else if (next.isDualSub()) {
916 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, next control point is offset control point");
917 } else if (next.previous == this) {
918 next.setPrevious(null);
920 throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
923 } else { //(previous != null)
924 if(previous.isDualInline()) {
925 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, previous control point is size change control point");
926 } else if (previous.isDualSub()) {
927 PipeControlPoint ocp = previous;
928 PipeControlPoint sccp = ocp.getParentPoint();
930 throw new RuntimeException("Removing PipeControlPoint " + this + " structure damaged, no size change control point");
934 } else if (previous.next == this) {
935 previous.setNext(null);
937 throw new RuntimeException("Removing PipeControlPoint "+ this+ " structure damaged");
941 if (children.size() > 0 ) {
943 } else if (parent!= null) {
950 pipeRun.remChild(this);
951 checkRemove(pipeRun);
952 if (PipingRules.isEnabled() && pipeRun.getParent() != null && pipeRun.getControlPoints().size() > 0)
953 PipingRules.validate(pipeRun);
954 if (additionalRemove != null)
955 additionalRemove.remove();
958 public void remove() {
959 PipeControlPoint currentPrev = previous;
960 PipeControlPoint currentNext = next;
963 if (currentNext != null)
964 PipingRules.requestUpdate(currentNext);
965 if (currentPrev != null)
966 PipingRules.requestUpdate(currentPrev);
967 } catch (Exception e) {
972 private void checkRemove(PipeRun pipeRun) {
973 Collection<PipeControlPoint> points = pipeRun.getControlPoints();
974 if (points.size() == 0) {
976 } else if (points.size() == 1) {
977 PipeControlPoint pcp = points.iterator().next();
978 if (pcp.isDeletable())
983 private void removeDualPoint() {
984 if (previous != null)
985 previous.setNext(null);
987 next.setPrevious(null);
988 PipeControlPoint ocp;
989 PipeControlPoint sccp;
990 if (isDualInline()) {
992 ocp = getSubPoint().get(0);
995 sccp = getParentPoint();
997 PipeRun p1 = ocp.getPipeRun();
998 PipeRun p2 = sccp.getPipeRun();
1000 ocp.removeComponent();
1001 sccp.removeComponent();
1007 ocp.setPrevious(null);
1009 sccp.setPrevious(null);
1015 private void removeSubPoints() {
1016 for (PipeControlPoint p : children) {
1017 // TODO : this may affect delete routine, since classification of the point changes.
1024 private void removeParentPoint() {
1025 throw new RuntimeException("Child points cannot be removed directly");
1028 private void removeComponent() {
1029 if (component == null)
1031 PipelineComponent next = component.getNext();
1032 PipelineComponent prev = component.getNext();
1034 if (next.getNext() == component)
1036 else if (next.getPrevious() == component)
1037 next.setPrevious(null);
1040 if (prev.getNext() == component)
1042 else if (prev.getPrevious() == component)
1043 prev.setPrevious(null);
1045 PipelineComponent comp = component;
1051 public void setOrientation(Quat4d orientation) {
1052 if (MathTools.equals(orientation, getOrientation()))
1054 super.setOrientation(orientation);
1055 if (getParentPoint() == null && component != null)
1056 component._setWorldOrientation(getWorldOrientation());
1061 public void setPosition(Vector3d position) {
1062 if (MathTools.equals(position, getPosition()))
1064 super.setPosition(position);
1065 if (getParentPoint() == null && component != null)
1066 component._setWorldPosition(getWorldPosition());
1068 System.out.println();
1072 private void updateSubPoint() {
1074 if (next == null && previous == null) {
1075 for (PipeControlPoint sub : getSubPoint()) {
1076 sub.setWorldPosition(getWorldPosition());
1077 sub.setWorldOrientation(getWorldOrientation());
1081 for (PipeControlPoint sub : getSubPoint()) {
1082 Vector3d wp = getWorldPosition();
1083 wp.add(getSizeChangeOffsetVector());
1084 sub.setWorldPosition(wp);
1085 sub.setWorldOrientation(getWorldOrientation());
1088 for (PipeControlPoint sub : getSubPoint()) {
1089 sub.setWorldPosition(getWorldPosition());
1090 sub.setWorldOrientation(getWorldOrientation());
1096 public void _setWorldPosition(Vector3d position) {
1097 Vector3d localPos = getLocalPosition(position);
1098 super.setPosition(localPos);
1102 public void _setWorldOrientation(Quat4d orientation) {
1103 Quat4d localOr = getLocalOrientation(orientation);
1104 super.setOrientation(localOr);
1109 public String toString() {
1110 return getClass().getName() + "@" + Integer.toHexString(hashCode());