1 package fi.vtt.simantics.processeditor.common;
\r
3 import java.util.ArrayList;
\r
4 import java.util.Collection;
\r
5 import java.util.HashMap;
\r
6 import java.util.Stack;
\r
8 import javax.vecmath.AxisAngle4d;
\r
9 import javax.vecmath.Matrix3d;
\r
10 import javax.vecmath.Point3d;
\r
11 import javax.vecmath.Quat4d;
\r
12 import javax.vecmath.Tuple3d;
\r
13 import javax.vecmath.Vector3d;
\r
15 import org.simantics.db.Graph;
\r
16 import org.simantics.db.Resource;
\r
17 import org.simantics.layer0.utils.EntityFactory;
\r
18 import org.simantics.layer0.utils.IEntity;
\r
19 import org.simantics.proconf.g3d.base.G3DTools;
\r
20 import org.simantics.proconf.g3d.base.MathTools;
\r
21 import org.simantics.proconf.g3d.base.TransformationTools;
\r
22 import org.simantics.utils.ErrorLogger;
\r
23 import org.simantics.utils.datastructures.Pair;
\r
25 import fi.vtt.simantics.processeditor.ProcessResource;
\r
26 import fi.vtt.simantics.processeditor.actions.PositionType;
\r
27 import fi.vtt.simantics.processeditor.common.PipingTools2.Direction;
\r
28 import fi.vtt.simantics.processeditor.stubs.PipeControlPoint;
\r
29 import fi.vtt.simantics.processeditor.stubs.PipeRun;
\r
31 public class ControlPointTools {
\r
33 private static boolean DEBUG = false;
\r
35 private static TransformationTools tt;
\r
37 public static void initialize() {
\r
38 tt = new TransformationTools(ProcessResource.plant3Dresource.HasSubPoint,ProcessResource.plant3Dresource.SubPointOf) {
\r
40 public IEntity getParent(IEntity node) {
\r
41 IEntity parent = super.getParent(node);
\r
42 if (parent == null) {
\r
43 parent = node.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.ControlPointOf);
\r
45 parent = parent.getAtMostOneRelatedObject(ProcessResource.g3dResource.HasParent);
\r
47 parent = node.getAtMostOneRelatedObject(ProcessResource.g3dResource.HasParent);
\r
55 public static void deinitialize() {
\r
60 * Adds new control point between given control points.
\r
61 * New pcp must be already part of the same piperun as previous CP and nextCP
\r
63 * SizeChangeControlPoints cannot be inserted with this method, since it does link two different piperuns to each other
\r
69 public static void insertControlPoint(IEntity newCP, IEntity previousCP, IEntity nextCP) {
\r
70 // inserting an offsetpoint is error,
\r
71 assert(!newCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint));
\r
72 // size change control point cannot be inserted this way, because it ends PipeRun
\r
73 assert(!newCP.isInstanceOf(ProcessResource.plant3Dresource.SizeChangeControlPoint));
\r
75 IEntity piperun = previousCP.getSingleRelatedObject(ProcessResource.plant3Dresource.ControlPointOfPipeRun);
\r
76 // and just to make sure that control point structure is not corrupted
\r
77 assert(piperun.equals(nextCP.getSingleRelatedObject(ProcessResource.plant3Dresource.ControlPointOfPipeRun)));
\r
78 assert(piperun.equals(newCP.getSingleRelatedObject(ProcessResource.plant3Dresource.ControlPointOfPipeRun)));
\r
80 // insert new BranchControlPoint between straight's control points
\r
81 IEntity previousNext = previousCP.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasNext);
\r
82 IEntity previousPrevious = previousCP.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasPrevious);
\r
84 IEntity offsetCP = null;
\r
86 if (newCP.isInstanceOf(ProcessResource.plant3Dresource.OffsettingPoint)) {
\r
87 offsetCP = newCP.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
90 if (previousNext != null && previousNext.equals(nextCP)) {
\r
91 assert(!previousCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint));
\r
92 assert(!nextCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint));
\r
94 setStatement(previousCP, ProcessResource.plant3Dresource.HasNext, newCP);
\r
95 setStatement(newCP, ProcessResource.plant3Dresource.HasPrevious, previousCP);
\r
97 if (previousCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
98 IEntity sccp = previousCP.getSingleRelatedObject(ProcessResource.plant3Dresource.SubPointOf);
\r
99 setStatement(sccp, ProcessResource.plant3Dresource.HasNext, newCP);
\r
102 setStatement(newCP, ProcessResource.plant3Dresource.HasNext, nextCP);
\r
104 if (offsetCP == null) {
\r
105 setStatement(nextCP, ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
107 setStatement(nextCP, ProcessResource.plant3Dresource.HasPrevious, offsetCP);
\r
108 setStatement(offsetCP, ProcessResource.plant3Dresource.HasNext, nextCP);
\r
109 setStatement(offsetCP, ProcessResource.plant3Dresource.HasPrevious, previousCP);
\r
112 if (nextCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
113 IEntity ocp = nextCP.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
114 setStatement(ocp, ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
117 } else if (previousPrevious != null && previousPrevious.equals(nextCP)) {
\r
118 // control point were given in reverse order
\r
119 assert(!nextCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint));
\r
120 assert(!previousCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint));
\r
122 setStatement(newCP, ProcessResource.plant3Dresource.HasNext, previousCP);
\r
123 if (offsetCP == null) {
\r
124 setStatement(previousCP, ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
126 setStatement(previousCP, ProcessResource.plant3Dresource.HasPrevious, offsetCP);
\r
127 setStatement(offsetCP, ProcessResource.plant3Dresource.HasNext, previousCP);
\r
128 setStatement(offsetCP, ProcessResource.plant3Dresource.HasPrevious, nextCP);
\r
131 if (previousCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
132 IEntity ocp = previousCP.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
133 setStatement(ocp, ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
136 setStatement(newCP, ProcessResource.plant3Dresource.HasPrevious, nextCP);
\r
137 setStatement(nextCP, ProcessResource.plant3Dresource.HasNext, newCP);
\r
138 if (nextCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
139 IEntity sccp = nextCP.getSingleRelatedObject(ProcessResource.plant3Dresource.SubPointOf);
\r
140 setStatement(sccp, ProcessResource.plant3Dresource.HasNext, newCP);
\r
143 ErrorLogger.defaultLogError(
\r
144 "Route pipe : could not find connection between straight pipe's control points", null);
\r
150 * Adds new control point attaching it to given control point.
\r
151 * If the new control point is SizeChangeControlPoint, it must have its offset point set.
\r
157 public static void insertControlPoint(IEntity newCP, IEntity pcp, Direction direction) {
\r
158 assert(!newCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint));
\r
159 if (direction == Direction.NEXT) {
\r
160 // if direction is next, user must have given OffsetPoint
\r
161 assert(!pcp.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint));
\r
162 // basic next/prev links
\r
163 pcp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
164 pcp.addStatement(ProcessResource.plant3Dresource.HasNext, newCP);
\r
165 newCP.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
166 newCP.addStatement(ProcessResource.plant3Dresource.HasPrevious, pcp);
\r
167 // and last take care of sizechange / offset points
\r
168 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
169 IEntity sccp = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.SubPointOf);
\r
170 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
171 sccp.addStatement(ProcessResource.plant3Dresource.HasNext, newCP);
\r
173 if (newCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
174 IEntity ocp = newCP.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
175 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
176 ocp.addStatement(ProcessResource.plant3Dresource.HasPrevious, pcp);
\r
179 // if direction is previous, user must have given sizechange
\r
180 assert(!pcp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint));
\r
181 // previous direction is more complicated, since if newCP is SizeChangeControlPoint,
\r
182 // we must link pcp to newCP's OffsetPoint
\r
183 IEntity nocp = null;
\r
184 if (newCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
185 nocp = newCP.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
186 nocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
187 nocp.addStatement(ProcessResource.plant3Dresource.HasNext, pcp);
\r
189 pcp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
191 pcp.addStatement(ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
193 pcp.addStatement(ProcessResource.plant3Dresource.HasPrevious, nocp);
\r
195 newCP.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
196 newCP.addStatement(ProcessResource.plant3Dresource.HasNext, pcp);
\r
197 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
198 IEntity ocp = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
199 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
201 ocp.addStatement(ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
203 ocp.addStatement(ProcessResource.plant3Dresource.HasPrevious, nocp);
\r
210 * Returns path legs direction
\r
215 public static Vector3d getPathLegDirection(IEntity pcp,Direction direction) {
\r
216 IEntity previous = pcp.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasPrevious);
\r
217 IEntity next = pcp.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasNext);
\r
218 if (direction == Direction.NEXT) {
\r
219 if (next != null) {
\r
220 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint))
\r
221 pcp = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
222 Point3d p1 = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
223 Point3d p2 = G3DTools.getPoint(next.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
224 Vector3d v = new Vector3d();
\r
228 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.VariableAngleTurnControlPoint))
\r
229 throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + pcp.getResource());
\r
230 if (previous == null) {
\r
231 if (!pcp.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint))
\r
232 throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + pcp.getResource());
\r
234 return getDirectedControlPointDirection(pcp);
\r
236 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint)) {
\r
237 Point3d p1 = G3DTools.getPoint(previous.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
238 Point3d p2 = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
239 Vector3d v = new Vector3d();
\r
243 throw new RuntimeException("Missing implementation");
\r
247 if (previous != null) {
\r
248 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint))
\r
249 pcp = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.SubPointOf);
\r
250 Point3d p1 = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
251 Point3d p2 = G3DTools.getPoint(previous.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
252 Vector3d v = new Vector3d();
\r
256 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.VariableAngleTurnControlPoint))
\r
257 throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + pcp.getResource());
\r
258 if (next == null) {
\r
259 if (!pcp.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint))
\r
260 throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + pcp.getResource());
\r
262 Vector3d v = getDirectedControlPointDirection(pcp);
\r
267 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint)) {
\r
268 Point3d p1 = G3DTools.getPoint(next.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
269 Point3d p2 = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
270 Vector3d v = new Vector3d();
\r
274 throw new RuntimeException("Missing implementation");
\r
282 * Return positions (world) of an InlineComponents ends
\r
287 public static void getInlineControlPointEnds(IEntity pcp, Point3d p1, Point3d p2) {
\r
288 assert (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint));
\r
290 Point3d pos = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
291 Vector3d dir = ControlPointTools.getPathLegDirection(pcp, Direction.NEXT);
\r
293 double length = pcp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);
\r
294 dir.scale(length * 0.5);
\r
302 * Return positions (world) of an InlineComponents ends
\r
307 public static void getInlineControlPointEnds(IEntity pcp, Point3d p1, Point3d p2, Vector3d dir) {
\r
308 assert (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint));
\r
310 Point3d pos = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
311 dir.set(ControlPointTools.getPathLegDirection(pcp, Direction.NEXT));
\r
312 double length = pcp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);
\r
313 Vector3d d = new Vector3d(dir);
\r
314 d.scale(length * 0.5);
\r
322 * Return positions (world) of an InlineComponents ends
\r
327 public static void getInlineControlPointEnds(IEntity pcp, Point3d center, Point3d p1, Point3d p2, Vector3d dir) {
\r
328 assert (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint));
\r
330 Point3d pos = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
332 dir.set(ControlPointTools.getPathLegDirection(pcp, Direction.NEXT));
\r
333 double length = pcp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);
\r
334 Vector3d d = new Vector3d(dir);
\r
335 d.scale(length * 0.5);
\r
342 public static double getInlineLength(IEntity pcp) {
\r
344 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.TurnControlPoint)) {
\r
345 l2 += pcp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);
\r
346 } else if (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint)) {
\r
347 l2 += pcp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength) * 0.5;
\r
353 * Returns position (world) of a single port
\r
358 public static Point3d getRealPosition(IEntity pcp, PositionType type) {
\r
359 PipeControlPoint p= new PipeControlPoint(pcp);
\r
360 Point3d pos = G3DTools.getPoint(p.getWorldPosition());
\r
363 Vector3d dir = ControlPointTools.getPathLegDirection(pcp,Direction.NEXT);
\r
364 double length = getInlineLength(pcp);
\r
371 Vector3d dir = ControlPointTools.getPathLegDirection(pcp,Direction.PREVIOUS);
\r
372 double length = getInlineLength(pcp);
\r
379 // IEntity portDir = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.HasDirection);
\r
380 // TODO : how we calculated needed space for a port; does it has an offset from control point's position or not?
\r
390 public static void getInlineMovement(PipeControlPoint pcp, Point3d start, Point3d end) {
\r
391 // FIXME : check type of neighbor components and allow movement on top of variable length components,
\r
392 // ffind proper range for movement (pcp's position is not)
\r
393 PipeControlPoint prev = pcp.getPrevious().getPrevious();
\r
394 PipeControlPoint next = pcp.getNext().getNext();
\r
395 start.set(G3DTools.getPoint(prev.getWorldPosition()));
\r
396 end.set(G3DTools.getPoint(next.getWorldPosition()));
\r
399 public static AxisAngle4d getControlPointLocalRotation(IEntity pcp, double angle) {
\r
400 Quat4d q1 = getControlPointLocalOrientationQuat(pcp, angle);
\r
401 AxisAngle4d aa= new AxisAngle4d();
\r
406 public static AxisAngle4d getControlPointWorldRotation(IEntity pcp, double angle) {
\r
407 Quat4d q1 = getControlPointWorldOrientationQuat(pcp, angle);
\r
408 AxisAngle4d aa= new AxisAngle4d();
\r
414 public static Quat4d getControlPointLocalOrientationQuat(IEntity pcp, double angle) {
\r
415 return getControlPointLocalOrientationQuat(pcp, angle, false);
\r
418 public static Quat4d getControlPointWorldOrientationQuat(IEntity pcp, double angle) {
\r
419 return getControlPointWorldOrientationQuat(pcp, angle, false);
\r
422 public static Quat4d getControlPointLocalOrientationQuat(IEntity cp, double angle, boolean offset) {
\r
423 PipeControlPoint pcp = new PipeControlPoint(cp);
\r
424 PipeControlPoint next;
\r
425 // if pcp is size change control point with offset, next control point is not in line with previous and pcp control point (it's offsetted)
\r
426 // else it's more numerically stable to use next control point
\r
430 next = pcp.getNext();
\r
432 PipeControlPoint prev = pcp.getPrevious();
\r
433 assert (next != null || prev != null);
\r
436 else if (next == null)
\r
438 // TODO : check correct type
\r
439 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.PathLegEndControlPoint) && pcp.getPrevious() == null) {
\r
440 PipeControlPoint temp = next;
\r
444 Vector3d current = new Vector3d(G3DTools.getPoint(next.getLocalPosition()));
\r
445 current.sub(G3DTools.getPoint(prev.getLocalPosition()));
\r
446 current.normalize();
\r
447 return getControlPointOrientationQuat(current, angle);
\r
450 public static Quat4d getControlPointWorldOrientationQuat(IEntity cp, double angle, boolean offset) {
\r
451 PipeControlPoint pcp = new PipeControlPoint(cp);
\r
452 PipeControlPoint next;
\r
453 // if pcp is size change control point with offset, next control point is not in line with previous and pcp control point (it's offsetted)
\r
454 // else it's more numerically stable to use next control point
\r
458 next = pcp.getNext();
\r
460 PipeControlPoint prev = pcp.getPrevious();
\r
461 assert (next != null || prev != null);
\r
464 else if (next == null)
\r
466 // TODO : check correct type
\r
467 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.PathLegEndControlPoint) && pcp.getPrevious() == null) {
\r
468 PipeControlPoint temp = next;
\r
472 Vector3d current = new Vector3d(G3DTools.getPoint(next.getWorldPosition()));
\r
473 current.sub(G3DTools.getPoint(prev.getWorldPosition()));
\r
474 current.normalize();
\r
475 return getControlPointOrientationQuat(current, angle);
\r
478 public static Quat4d getControlPointOrientationQuat(Vector3d dir, double angle) {
\r
481 final Vector3d front = new Vector3d(1.0,0.0,0.0);
\r
483 Quat4d q1 = new Quat4d();
\r
485 Vector3d up = new Vector3d(0.0, 1.0, 0.0);
\r
486 double a = up.angle(dir);
\r
487 if (a < 0.1 || (Math.PI - a) < 0.1) {
\r
488 up.set(1.0, 0.0, 0.0);
\r
491 Vector3d right = new Vector3d();
\r
493 right.cross(dir, up);
\r
494 up.cross(right, dir);
\r
498 Matrix3d m = new Matrix3d();
\r
509 //q1.set(m); MathTools contains more stable conversion
\r
510 MathTools.getQuat(m, q1);
\r
512 if (DEBUG) System.out.println("PipingTools.getPipeComponentOrientationQuat() " + dir+ " " + up + " " + right);
\r
514 Quat4d q2 = new Quat4d();
\r
515 q2.set(new AxisAngle4d(front, angle));
\r
520 public static PipeControlPoint findPreviousEnd(PipeControlPoint tcp) {
\r
521 // TODO : optimize (we do not need the list here)
\r
522 ArrayList<PipeControlPoint> t = new ArrayList<PipeControlPoint>();
\r
523 return findPreviousEnd(tcp, t);
\r
526 public static PipeControlPoint findNextEnd(PipeControlPoint tcp) {
\r
527 // TODO : optimize (we do not need the list here)
\r
528 ArrayList<PipeControlPoint> t = new ArrayList<PipeControlPoint>();
\r
529 return findNextEnd(tcp, t);
\r
533 * Returns pipe leg's end using "nextControlPoint" relation and collects control point in the given list.
\r
538 public static PipeControlPoint findNextEnd(PipeControlPoint tcp, ArrayList<PipeControlPoint> nextList) {
\r
539 if (DEBUG) System.out.print("PipingTools.findNextEnd " + tcp.getResource());
\r
541 PipeControlPoint pcp = null;
\r
542 PipeControlPoint p = null;
\r
543 if (nextList.size() == 0)
\r
547 p = nextList.get(nextList.size() - 1);
\r
552 if (nextList.size() > 0)
\r
553 nextList.remove(nextList.size() - 1);
\r
554 if (DEBUG) System.out.println(" " + pcp.getResource() + " not full");
\r
558 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.PathLegEndControlPoint)) {
\r
559 if (DEBUG) System.out.println(" " + pcp.getResource());
\r
563 if (DEBUG) System.out.print(" " + pcp.getResource());
\r
571 * Returns pipe leg's end using "previousControlPoint" relation and collects control point in the given list.
\r
576 public static PipeControlPoint findPreviousEnd(PipeControlPoint tcp, ArrayList<PipeControlPoint> prevList) {
\r
577 if (DEBUG) System.out.print("PipingTools.findPreviousEnd " + tcp.getResource());
\r
579 PipeControlPoint pcp = null;
\r
580 PipeControlPoint p = null;
\r
581 if (prevList.size() == 0)
\r
585 p = prevList.get(prevList.size() - 1);
\r
587 pcp = p.getPrevious();
\r
590 if (prevList.size() > 0)
\r
591 prevList.remove(prevList.size() - 1);
\r
592 if (DEBUG) System.out.println(" " + pcp.getResource() + " not full");
\r
595 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.PathLegEndControlPoint)) {
\r
596 if (DEBUG) System.out.println(" " + pcp.getResource());
\r
600 if (DEBUG) System.out.print(" " + pcp.getResource());
\r
605 public static PipeRun getPipeRun(PipeControlPoint pcp) {
\r
606 return pcp.getControlPointOfPipeRun();
\r
610 public static Vector3d getSizeChangeOffsetVector(PipeControlPoint sccp) {
\r
611 Quat4d q = getControlPointWorldOrientationQuat(sccp, sccp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasRotationAngle),true);
\r
612 return getSizeChangeOffsetVector(sccp,q);
\r
615 public static Vector3d getSizeChangeOffsetVector(PipeControlPoint sccp, Vector3d dir) {
\r
616 Quat4d q = getControlPointOrientationQuat(dir, sccp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasRotationAngle));
\r
617 return getSizeChangeOffsetVector(sccp,q);
\r
620 public static Vector3d getSizeChangeOffsetVector(PipeControlPoint sccp, Quat4d q) {
\r
621 Vector3d v = new Vector3d(0.0,0.0,sccp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasOffset));
\r
622 Vector3d offset = new Vector3d();
\r
623 MathTools.rotate(q, v, offset);
\r
627 public static Vector3d getDirectedControlPointDirection(IEntity dcp) {
\r
628 assert(dcp.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint));
\r
629 AxisAngle4d worldR = G3DTools.getOrientation(dcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldOrientation));
\r
630 Quat4d q = new Quat4d();
\r
632 Vector3d dir = new Vector3d();
\r
633 MathTools.rotate(q, new Vector3d(1.0, 0.0, 0.0), dir);
\r
638 public static Vector3d getNozzleDirection(IEntity rotation) {
\r
639 AxisAngle4d worldR = G3DTools.getOrientation(rotation);
\r
640 Quat4d q = new Quat4d();
\r
642 Vector3d dir = new Vector3d();
\r
643 MathTools.rotate(q, new Vector3d(1.0, 0.0, 0.0), dir);
\r
647 public static Vector3d getNozzleDirection(PipeControlPoint dcp) {
\r
648 return getNozzleDirection(dcp.getWorldOrientation());
\r
651 public static void removeControlPoint(PipeControlPoint removed) {
\r
652 if (DEBUG) System.out.println("PipingTools.removeControlPoint() controlpoint " + removed.getResource());//FIXME : offset + size change control points !
\r
654 // this code is not valid anymore.
\r
656 // different removing cases:
\r
658 // 1. Point is SizeChangeControlPoint (this is currently ok)
\r
659 // * remove offset point and component
\r
660 // * do NOT link components together
\r
662 // 2. Point is VariableLength
\r
663 // * check if its a branch (TODO : ontology support?)
\r
664 // * if so, also branch point in the other piperun may have to be removed
\r
665 // (we cannot move other components next to branch)
\r
666 // * if not, components next to removed one are moved next to each other
\r
668 // * check if there is VariableLength on both sides,
\r
669 // * if so, those must be unified to a single Variable Length component.
\r
670 // * if not, components must be moved next to each other
\r
672 // a) If removed Control Point is next to Nozzle and after the point is removed nozzle is not connected to anything
\r
673 // * nozzle's link to piperun's specs must be removed
\r
677 if (removed.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)||
\r
678 removed.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
679 // sccp & ocp connect two pipeRuns to each other; when thoes are remove, pipeRuns are not connected to each other anymore.
\r
680 removeDualPoint(removed);
\r
683 PipeControlPoint prev = removed.getPrevious();
\r
684 PipeControlPoint next = removed.getNext();
\r
685 PipeRun pipeRun = getPipeRun(removed);
\r
686 if (pipeRun == null)
\r
688 if (next == null && prev == null) {
\r
689 if (removed.isInstanceOf(ProcessResource.plant3Dresource.NozzleControlPoint)) {
\r
690 // Nozzle's control point does not need to be removed, only unlinked
\r
691 // TODO : what about component ports?
\r
692 PipingTools2.unlinkNozzleAndPiperun(removed.getSingleRelatedObject(ProcessResource.plant3Dresource.ControlPointOf), ControlPointTools.getPipeRun(removed));
\r
697 if (next != null && prev != null) {
\r
698 boolean link = true;
\r
699 if (next.isInstanceOf(ProcessResource.plant3Dresource.BranchEndControlPoint)){
\r
701 next.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
702 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
703 removeControlPoint(next);
\r
705 if (prev.isInstanceOf(ProcessResource.plant3Dresource.BranchEndControlPoint)) {
\r
707 prev.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
708 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
709 removeControlPoint(prev);
\r
711 if (link && prev.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint)&&
\r
712 next.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint)) {
\r
715 if (next.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
716 PipeControlPoint sccp = next;
\r
717 PipeControlPoint ocp = sccp.getSubPoint().iterator().next();
\r
719 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource()+ " structure damaged, no offset control point",null);
\r
723 sccp.setPrevious(prev);
\r
724 ocp.setPrevious(prev);
\r
726 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
727 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
730 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
731 } else if (next.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
732 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource()+ " structure damaged, next control point is offset control point",null);
\r
734 } else if (next.getPrevious().getResource().equals(removed.getResource())) {
\r
736 next.setPrevious(prev);
\r
738 next.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
740 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
742 ErrorLogger.defaultLogError("Removing PipeControlPoint "+ removed.getResource()+ " structure damaged", null);
\r
745 if (prev.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
746 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged, previous control point is size change control point", null);
\r
748 } else if (prev.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
749 PipeControlPoint ocp = prev;
\r
750 PipeControlPoint sccp = ocp.getSubPointOf();
\r
751 if (sccp == null) {
\r
752 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged, no size change control point",null);
\r
757 sccp.setNext(next);
\r
759 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
760 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
762 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
763 } else if (prev.getNext().getResource().equals(removed.getResource())) {
\r
765 prev.setNext(next);
\r
767 prev.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
768 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
770 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged", null);
\r
774 if (next.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthControlPoint) &&
\r
775 prev.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthControlPoint)) {
\r
776 // we have to join them into single variable length component.
\r
777 removeControlPoint(prev);
\r
782 } else if (next != null) {
\r
783 if (next.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
784 PipeControlPoint sccp = next;
\r
785 PipeControlPoint ocp = sccp.getSubPoint().iterator().next();
\r
787 ErrorLogger.defaultLogError("Removing PipeControlPoint "+ removed.getResource()+ " structure damaged, no offset control point",null);
\r
790 next.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
791 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
792 } else if (next.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
793 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged, next control point is offset control point", null);
\r
795 } else if (next.getPrevious().getResource().equals(removed.getResource())) {
\r
796 next.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
798 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged", null);
\r
801 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
802 } else { //(prev != null)
\r
803 if (prev.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
804 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged, previous control point is size change control point", null);
\r
806 } else if (prev.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
807 PipeControlPoint ocp = prev;
\r
808 PipeControlPoint sccp = ocp.getSubPointOf();
\r
809 if (sccp == null) {
\r
810 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged, no size change control point", null);
\r
813 prev.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
814 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
815 } else if (prev.getNext().getResource().equals(removed.getResource())) {
\r
816 prev.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
818 ErrorLogger.defaultLogError("Removing PipeControlPoint "+ removed.getResource() + " structure damaged", null);
\r
821 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
825 if (removed.getSubPoint().size() > 0 ) {
\r
826 removeSubPoints(removed);
\r
827 } else if (removed.getSubPointOf() != null) {
\r
828 removeParentPoint(removed);
\r
831 removeComponents(removed);
\r
833 pipeRun.removeStatement(ProcessResource.plant3Dresource.HasControlPoints, removed);
\r
834 if (pipeRun.getChild().size() == 0) {
\r
835 PipingTools2.removePipeRun(pipeRun);
\r
837 else if (pipeRun.getControlPoints().size() == 1) {
\r
838 removeControlPoint(pipeRun.getControlPoints().iterator().next());
\r
844 private static void removeDualPoint(PipeControlPoint removed) {
\r
845 PipeControlPoint prev = removed.getPrevious();
\r
846 PipeControlPoint next = removed.getNext();
\r
847 if (prev != null) {
\r
848 prev.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
851 next.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
852 PipeControlPoint ocp;
\r
853 PipeControlPoint sccp;
\r
854 // get sccp / ocp pair
\r
855 if (removed.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
857 ocp = sccp.getSubPoint().iterator().next();
\r
861 sccp = ocp.getSubPointOf();
\r
863 PipeRun p1 = getPipeRun(ocp);
\r
864 PipeRun p2 = getPipeRun(sccp);
\r
866 // removes all components connected to control point
\r
868 removeComponents(ocp);
\r
870 removeComponents(sccp);
\r
872 // remove control points from pipeRuns
\r
873 p1.removeStatement(ProcessResource.plant3Dresource.HasControlPoints, ocp);
\r
874 p2.removeStatement(ProcessResource.plant3Dresource.HasControlPoints, sccp);
\r
876 // remove links to other control points
\r
877 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
878 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
879 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
880 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
882 // if pipeRuns contains no other components(control points), they can be removed too.
\r
883 if (p1.getControlPoints().size() == 0) {
\r
884 PipingTools2.removePipeRun(p1);
\r
885 } else if (p1.getControlPoints().size() == 1) {
\r
886 removeControlPoint(p1.getControlPoints().iterator().next());
\r
888 if (p2.getControlPoints().size() == 0) {
\r
889 PipingTools2.removePipeRun(p2);
\r
890 } else if (p2.getControlPoints().size() == 1) {
\r
891 removeControlPoint(p2.getControlPoints().iterator().next());
\r
896 * Removes sub points of a point
\r
898 * @throws TransactionException
\r
900 private static void removeSubPoints(PipeControlPoint removed) {
\r
901 // if control point is branch control point, all branch of points must be removed too
\r
902 Collection<PipeControlPoint> points = removed.getSubPoint();
\r
904 for (PipeControlPoint p : points) {
\r
905 removed.removeStatement(ProcessResource.plant3Dresource.HasSubPoint, p);
\r
906 removeControlPoint(p);
\r
911 * Removed point is a subpoint of something,
\r
914 private static void removeParentPoint(PipeControlPoint removed) {
\r
915 throw new RuntimeException("Subpoints cannot be removed");
\r
917 // if control point is branch it has to be removed from branch control point
\r
918 // BranchEndControlPoint ecp = BranchEndControlPointFactory.create(removed);
\r
919 // BranchControlPoint bcp = null;
\r
920 // if (ecp.getBranchOfPointSet().size() == 1) {
\r
921 // bcp = ecp.getBranchOfPointSet().iterator().next();
\r
923 // if (bcp != null) {
\r
924 // bcp.getBranchPointSet().remove(ecp);
\r
925 // if (bcp.getBranchPointSet().size() == 0) {
\r
926 // // branch control point is not used and can be removed
\r
927 // removeControlPoint(bcp);
\r
933 private static void removeComponents(PipeControlPoint pcp) {
\r
934 IEntity component = pcp.getControlPointOf();
\r
935 if (component != null) {
\r
936 PipeRun p1 = getPipeRun(pcp);
\r
937 p1.removeStatement(ProcessResource.g3dResource.HasChild, component);
\r
938 component.removeRelatedStatements(ProcessResource.plant3Dresource.HasControlPoint);
\r
942 private static void setStatement(IEntity subject, Resource relation, IEntity object) {
\r
943 subject.removeRelatedStatements(relation);
\r
944 subject.addStatement(relation, object);
\r
948 public static void setWorldPosition(IEntity pcp, Tuple3d position) {
\r
949 IEntity wp = pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition);
\r
950 G3DTools.setTuple3(wp, position);
\r
951 tt.propagateWorldTransformChange(tt.getParent(pcp), pcp);
\r
955 public static void setLocalPosition(IEntity pcp, Tuple3d position) {
\r
956 G3DTools.setTuple3(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasLocalPosition), position);
\r
957 tt.propagateLocalTransformChange(tt.getParent(pcp), pcp);
\r
960 public static void setWorldOrientation(IEntity node, AxisAngle4d orientation) {
\r
961 G3DTools.setOrientation(node.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldOrientation), orientation);
\r
962 tt.propagateWorldTransformChange(tt.getParent(node), node);
\r
966 public static void setLocalOrientation(IEntity node, AxisAngle4d orientation) {
\r
967 G3DTools.setOrientation(node.getSingleRelatedObject(ProcessResource.g3dResource.HasLocalOrientation), orientation);
\r
968 tt.propagateLocalTransformChange(tt.getParent(node), node);
\r
971 private static boolean updatePosition(IEntity pcp) {
\r
972 return tt.transformationUpdate(pcp);
\r
975 // TODO : orientation is also needed, current code handles only position
\r
976 // TODO : reuse the code in G3DTools!
\r
978 IEntity worldPosition = pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition);
\r
979 IEntity localPosition = pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasLocalPosition);
\r
982 Tuple3d worldP = G3DTools.getPoint(worldPosition);
\r
983 Tuple3d localP = G3DTools.getPoint(localPosition);
\r
985 if (localP == null || worldP == null)
\r
987 if (!isValid(worldP) && !isValid(localP))
\r
990 Tuple3d cachedWorldP = (Tuple3d) getProperty(worldPosition.getResource());
\r
991 Tuple3d cachedLocalP = (Tuple3d) getProperty(localPosition.getResource());
\r
993 if (DEBUG) System.out.println("PipeControlPoint changed " + worldP + " " + cachedWorldP + " " + localP + " " + cachedLocalP);
\r
994 boolean changed = false;
\r
996 IEntity parent = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.ControlPointOf);
\r
998 if (parent == null) {
\r
999 if (DEBUG) System.out.println("PipeControlPoint changed, no parent node");
\r
1003 if (cachedLocalP == null) {
\r
1004 storeProperty(localPosition.getResource(), localP);
\r
1005 Tuple3d p = G3DTools.getWorldFromLocal(parent, new Point3d(localP));
\r
1006 storeProperty(worldPosition.getResource(), p);
\r
1007 G3DTools.setTuple3(worldPosition, p);
\r
1008 if (DEBUG) System.out.println("PipeControlPoint changed local " + worldP + " " + p);
\r
1011 if (TransformationTools.changed(cachedLocalP, localP)) {
\r
1012 storeProperty(localPosition.getResource(), localP);
\r
1013 Tuple3d p = G3DTools.getWorldFromLocal(parent, new Point3d(localP));
\r
1014 storeProperty(worldPosition.getResource(), p);
\r
1015 G3DTools.setTuple3(worldPosition, p);
\r
1016 if (DEBUG) System.out.println("PipeControlPoint changed local " + worldP + " " + localP);
\r
1019 if (cachedWorldP == null) {
\r
1020 storeProperty(worldPosition.getResource(), worldP);
\r
1021 Tuple3d p = G3DTools.getLocalFromWorld(parent, new Point3d(worldP));
\r
1022 G3DTools.setTuple3(localPosition, p);
\r
1023 storeProperty(localPosition.getResource(), p);
\r
1024 if (DEBUG) System.out.println("PipeControlPoint changed world " + worldP + " " + p);
\r
1027 if (TransformationTools.changed(cachedWorldP, worldP)) {
\r
1028 storeProperty(worldPosition.getResource(), worldP);
\r
1029 Tuple3d p = G3DTools.getLocalFromWorld(parent, new Point3d(worldP));
\r
1030 G3DTools.setTuple3(localPosition, p);
\r
1031 storeProperty(localPosition.getResource(), p);
\r
1032 if (DEBUG) System.out.println("PipeControlPoint changed world " + worldP + " " + p);
\r
1041 static boolean isControlPointChanged(PipeControlPoint node) {
\r
1042 long id = node.getResource().getResourceId();
\r
1043 boolean changed = updatePosition(node);
\r
1045 if (node.isInstanceOf(ProcessResource.plant3Dresource.PathLegEndControlPoint)) {
\r
1046 if (node.isInstanceOf(ProcessResource.plant3Dresource.TurnControlPoint)) {
\r
1047 Pair<Long,Long> connected = (Pair<Long,Long>)getProperty(node.getResource().getResourceId());
\r
1048 PipeControlPoint next = node.getNext();
\r
1049 PipeControlPoint prev = node.getPrevious();
\r
1050 if ((next != null && prev != null) && (
\r
1051 connected == null ||
\r
1052 (connected.first == null && prev != null) ||
\r
1053 (connected.second == null && next != null) ||
\r
1054 !connected.first.equals(prev.getResource().getResourceId()) ||
\r
1055 !connected.second.equals(next.getResource().getResourceId()))) {
\r
1056 storeProperty(id, new Pair<Long,Long>(prev.getResource().getResourceId(),next.getResource().getResourceId()));
\r
1059 if (node.isInstanceOf(ProcessResource.plant3Dresource.VariableAngleTurnControlPoint)) {
\r
1060 double r = node.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasTurnRadius);
\r
1061 Double d = (Double)getProperty(id + ":turnradius");
\r
1062 if (d == null || TransformationTools.changed(r, d)) {
\r
1063 storeProperty(id + ":turnradius", r);
\r
1068 else if (node.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint)) {
\r
1069 Vector3d dir = ControlPointTools.getDirectedControlPointDirection(node);
\r
1070 Vector3d old = (Vector3d)getProperty(id + ":direction");
\r
1071 if (old == null || TransformationTools.changed(dir, old)) {
\r
1072 storeProperty(id + ":direction", dir);
\r
1076 } else { // InlineControlPoint
\r
1077 if (node.isInstanceOf(ProcessResource.plant3Dresource.FixedLengthControlPoint)) {
\r
1078 double length = node.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);
\r
1079 Double d = (Double)getProperty(id + ":length");
\r
1083 changed = changed || TransformationTools.changed(length, d);
\r
1086 storeProperty(id + ":length", length);
\r
1090 if (node.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
1092 double angle = node.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasRotationAngle);
\r
1093 Double d = (Double)getProperty(id + ":rotationangle");
\r
1097 changed = changed || TransformationTools.changed(angle, d);
\r
1099 storeProperty(id + ":rotationangle", angle);
\r
1102 Collection<PipeControlPoint> subpoints = node.getSubPoint();
\r
1103 if (subpoints.size() != 1)
\r
1104 throw new RuntimeException("Current implementation assumes that size change components are dual conmnected");
\r
1105 PipeControlPoint ocp = subpoints.iterator().next();
\r
1106 if (node.isInstanceOf(ProcessResource.plant3Dresource.OffsettingPoint)) {
\r
1107 double offset = ocp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasOffset);
\r
1108 d = (Double)getProperty(id +":offset");
\r
1112 changed = TransformationTools.changed(offset, d);
\r
1114 storeProperty(id+":offset", offset);
\r
1118 // } else if (node instanceof OffsetControlPoint) {
\r
1119 // OffsetControlPoint ocp = (OffsetControlPoint)node;
\r
1121 // } else if (node instanceof BranchControlPoint) {
\r
1122 // BranchControlPoint bcp = (BranchControlPoint)node;
\r
1123 // int size = bcp.getBranchPointSet().size();
\r
1124 // Integer i = (Integer)getProperty(bcp.getResource().getId());
\r
1128 // changed = changed || i != size;
\r
1130 // storeProperty(bcp.getResource().getId(), size);
\r
1140 private static boolean isValid(Tuple3d v) {
\r
1141 if (Double.isInfinite(v.x) ||
\r
1142 Double.isNaN(v.x) ||
\r
1143 Double.isInfinite(v.y) ||
\r
1144 Double.isNaN(v.y) ||
\r
1145 Double.isInfinite(v.z) ||
\r
1146 Double.isNaN(v.z))
\r
1151 private static HashMap<Object, Object> properties = new HashMap<Object, Object>();
\r
1153 public static Object getProperty(Object key) {
\r
1154 return properties.get(key);
\r
1157 public static void storeProperty(Object key, Object value) {
\r
1158 properties.put(key, value);
\r
1162 * Loads positions of controlpoint to rule cache
\r
1164 * TODO : this caches only transformation information : other info must be cached too
\r
1166 * @param root resource of the modeled plant
\r
1168 public static void reloadCache(Graph graph, Resource root) {
\r
1170 Stack<IEntity> stack = new Stack<IEntity>();
\r
1171 stack.add(EntityFactory.create(graph,root));
\r
1172 while (!stack.isEmpty()) {
\r
1173 IEntity current = stack.pop();
\r
1174 IEntity pcp = current.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasControlPoint);
\r
1175 if (pcp == null) {
\r
1176 stack.addAll(current.getRelatedObjects(ProcessResource.g3dResource.HasChild));
\r
1178 if (DEBUG) System.out.println("Cached pcp " + pcp.getResource());
\r
1179 IEntity localPos = pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasLocalPosition);
\r
1180 IEntity worldPos = pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition);
\r
1182 tt.storeProperty(localPos.getResource(),G3DTools.getPoint(localPos));
\r
1183 tt.storeProperty(worldPos.getResource(),G3DTools.getPoint(worldPos));
\r
1185 IEntity localOr = pcp.getAtMostOneRelatedObject(ProcessResource.g3dResource.HasLocalOrientation);
\r
1186 IEntity worldOr = pcp.getAtMostOneRelatedObject(ProcessResource.g3dResource.HasWorldOrientation);
\r
1188 if (worldOr != null) {
\r
1189 tt.storeProperty(localOr.getResource(),G3DTools.getOrientation(localOr));
\r
1190 tt.storeProperty(worldOr.getResource(),G3DTools.getOrientation(worldOr));
\r
1193 stack.addAll(pcp.getRelatedObjects(ProcessResource.plant3Dresource.HasSubPoint));
\r