1 package org.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.db.Session;
\r
18 import org.simantics.layer0.utils.EntityFactory;
\r
19 import org.simantics.layer0.utils.IEntity;
\r
20 import org.simantics.processeditor.ProcessResource;
\r
21 import org.simantics.processeditor.actions.PositionType;
\r
22 import org.simantics.processeditor.common.PipingTools2.Direction;
\r
23 import org.simantics.processeditor.stubs.PipeControlPoint;
\r
24 import org.simantics.processeditor.stubs.PipeRun;
\r
25 import org.simantics.proconf.g3d.base.G3DTools;
\r
26 import org.simantics.proconf.g3d.base.MathTools;
\r
27 import org.simantics.proconf.g3d.base.TransformationTools;
\r
28 import org.simantics.utils.ui.ErrorLogger;
\r
29 import org.simantics.utils.datastructures.Pair;
\r
32 public class ControlPointTools {
\r
34 private static boolean DEBUG = false;
\r
36 private static TransformationTools tt;
\r
38 public static void initialize() {
\r
39 tt = new TransformationTools(ProcessResource.plant3Dresource.HasSubPoint,ProcessResource.plant3Dresource.SubPointOf) {
\r
41 public IEntity getParent(IEntity node) {
\r
42 IEntity parent = super.getParent(node);
\r
43 if (parent == null) {
\r
44 parent = node.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.ControlPointOf);
\r
46 parent = parent.getAtMostOneRelatedObject(ProcessResource.g3dResource.HasParent);
\r
48 parent = node.getAtMostOneRelatedObject(ProcessResource.g3dResource.HasParent);
\r
56 public static void deinitialize() {
\r
61 * Adds new control point between given control points.
\r
62 * New pcp must be already part of the same piperun as previous CP and nextCP
\r
64 * SizeChangeControlPoints cannot be inserted with this method, since it does link two different piperuns to each other
\r
70 public static void insertControlPoint(IEntity newCP, IEntity previousCP, IEntity nextCP) {
\r
71 // inserting an offsetpoint is error,
\r
72 assert(!newCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint));
\r
73 // size change control point cannot be inserted this way, because it ends PipeRun
\r
74 assert(!newCP.isInstanceOf(ProcessResource.plant3Dresource.SizeChangeControlPoint));
\r
76 IEntity piperun = previousCP.getSingleRelatedObject(ProcessResource.plant3Dresource.ControlPointOfPipeRun);
\r
77 // and just to make sure that control point structure is not corrupted
\r
78 assert(piperun.equals(nextCP.getSingleRelatedObject(ProcessResource.plant3Dresource.ControlPointOfPipeRun)));
\r
79 assert(piperun.equals(newCP.getSingleRelatedObject(ProcessResource.plant3Dresource.ControlPointOfPipeRun)));
\r
81 // insert new BranchControlPoint between straight's control points
\r
82 IEntity previousNext = previousCP.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasNext);
\r
83 IEntity previousPrevious = previousCP.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasPrevious);
\r
85 IEntity offsetCP = null;
\r
87 if (newCP.isInstanceOf(ProcessResource.plant3Dresource.OffsettingPoint)) {
\r
88 offsetCP = newCP.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
91 if (previousNext != null && previousNext.equals(nextCP)) {
\r
92 assert(!previousCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint));
\r
93 assert(!nextCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint));
\r
95 setStatement(previousCP, ProcessResource.plant3Dresource.HasNext, newCP);
\r
96 setStatement(newCP, ProcessResource.plant3Dresource.HasPrevious, previousCP);
\r
98 if (previousCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
99 IEntity sccp = previousCP.getSingleRelatedObject(ProcessResource.plant3Dresource.SubPointOf);
\r
100 setStatement(sccp, ProcessResource.plant3Dresource.HasNext, newCP);
\r
103 setStatement(newCP, ProcessResource.plant3Dresource.HasNext, nextCP);
\r
105 if (offsetCP == null) {
\r
106 setStatement(nextCP, ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
108 setStatement(nextCP, ProcessResource.plant3Dresource.HasPrevious, offsetCP);
\r
109 setStatement(offsetCP, ProcessResource.plant3Dresource.HasNext, nextCP);
\r
110 setStatement(offsetCP, ProcessResource.plant3Dresource.HasPrevious, previousCP);
\r
113 if (nextCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
114 IEntity ocp = nextCP.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
115 setStatement(ocp, ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
118 } else if (previousPrevious != null && previousPrevious.equals(nextCP)) {
\r
119 // control point were given in reverse order
\r
120 assert(!nextCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint));
\r
121 assert(!previousCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint));
\r
123 setStatement(newCP, ProcessResource.plant3Dresource.HasNext, previousCP);
\r
124 if (offsetCP == null) {
\r
125 setStatement(previousCP, ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
127 setStatement(previousCP, ProcessResource.plant3Dresource.HasPrevious, offsetCP);
\r
128 setStatement(offsetCP, ProcessResource.plant3Dresource.HasNext, previousCP);
\r
129 setStatement(offsetCP, ProcessResource.plant3Dresource.HasPrevious, nextCP);
\r
132 if (previousCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
133 IEntity ocp = previousCP.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
134 setStatement(ocp, ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
137 setStatement(newCP, ProcessResource.plant3Dresource.HasPrevious, nextCP);
\r
138 setStatement(nextCP, ProcessResource.plant3Dresource.HasNext, newCP);
\r
139 if (nextCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
140 IEntity sccp = nextCP.getSingleRelatedObject(ProcessResource.plant3Dresource.SubPointOf);
\r
141 setStatement(sccp, ProcessResource.plant3Dresource.HasNext, newCP);
\r
144 ErrorLogger.defaultLogError(
\r
145 "Route pipe : could not find connection between straight pipe's control points", null);
\r
151 * Adds new control point attaching it to given control point.
\r
152 * If the new control point is SizeChangeControlPoint, it must have its offset point set.
\r
158 public static void insertControlPoint(IEntity newCP, IEntity pcp, Direction direction) {
\r
159 assert(!newCP.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint));
\r
160 if (direction == Direction.NEXT) {
\r
161 // if direction is next, user must have given OffsetPoint
\r
162 assert(!pcp.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint));
\r
163 // basic next/prev links
\r
164 pcp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
165 pcp.addStatement(ProcessResource.plant3Dresource.HasNext, newCP);
\r
166 newCP.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
167 newCP.addStatement(ProcessResource.plant3Dresource.HasPrevious, pcp);
\r
168 // and last take care of sizechange / offset points
\r
169 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
170 IEntity sccp = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.SubPointOf);
\r
171 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
172 sccp.addStatement(ProcessResource.plant3Dresource.HasNext, newCP);
\r
174 if (newCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
175 IEntity ocp = newCP.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
176 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
177 ocp.addStatement(ProcessResource.plant3Dresource.HasPrevious, pcp);
\r
180 // if direction is previous, user must have given sizechange
\r
181 assert(!pcp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint));
\r
182 // previous direction is more complicated, since if newCP is SizeChangeControlPoint,
\r
183 // we must link pcp to newCP's OffsetPoint
\r
184 IEntity nocp = null;
\r
185 if (newCP.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
186 nocp = newCP.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
187 nocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
188 nocp.addStatement(ProcessResource.plant3Dresource.HasNext, pcp);
\r
190 pcp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
192 pcp.addStatement(ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
194 pcp.addStatement(ProcessResource.plant3Dresource.HasPrevious, nocp);
\r
196 newCP.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
197 newCP.addStatement(ProcessResource.plant3Dresource.HasNext, pcp);
\r
198 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
199 IEntity ocp = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
200 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
202 ocp.addStatement(ProcessResource.plant3Dresource.HasPrevious, newCP);
\r
204 ocp.addStatement(ProcessResource.plant3Dresource.HasPrevious, nocp);
\r
211 * Returns path legs direction
\r
216 public static Vector3d getPathLegDirection(IEntity pcp,Direction direction) {
\r
217 IEntity previous = pcp.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasPrevious);
\r
218 IEntity next = pcp.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasNext);
\r
219 if (direction == Direction.NEXT) {
\r
220 if (next != null) {
\r
221 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint))
\r
222 pcp = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.HasSubPoint);
\r
223 Point3d p1 = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
224 Point3d p2 = G3DTools.getPoint(next.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
225 Vector3d v = new Vector3d();
\r
229 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.VariableAngleTurnControlPoint))
\r
230 throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + pcp.getResource());
\r
231 if (previous == null) {
\r
232 if (!pcp.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint))
\r
233 throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + pcp.getResource());
\r
235 return getDirectedControlPointDirection(pcp);
\r
237 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint)) {
\r
238 Point3d p1 = G3DTools.getPoint(previous.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
239 Point3d p2 = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
240 Vector3d v = new Vector3d();
\r
244 throw new RuntimeException("Missing implementation");
\r
248 if (previous != null) {
\r
249 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint))
\r
250 pcp = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.SubPointOf);
\r
251 Point3d p1 = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
252 Point3d p2 = G3DTools.getPoint(previous.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
253 Vector3d v = new Vector3d();
\r
257 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.VariableAngleTurnControlPoint))
\r
258 throw new RuntimeException("Cannot calculate path leg direction for unconnected variable angle control point " + pcp.getResource());
\r
259 if (next == null) {
\r
260 if (!pcp.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint))
\r
261 throw new RuntimeException("Cannot calculate path leg direction for unconnected control point " + pcp.getResource());
\r
263 Vector3d v = getDirectedControlPointDirection(pcp);
\r
268 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint)) {
\r
269 Point3d p1 = G3DTools.getPoint(next.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
270 Point3d p2 = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
271 Vector3d v = new Vector3d();
\r
275 throw new RuntimeException("Missing implementation");
\r
283 * Return positions (world) of an InlineComponents ends
\r
288 public static void getInlineControlPointEnds(IEntity pcp, Point3d p1, Point3d p2) {
\r
289 assert (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint));
\r
291 Point3d pos = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
292 Vector3d dir = ControlPointTools.getPathLegDirection(pcp, Direction.NEXT);
\r
294 double length = pcp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);
\r
295 dir.scale(length * 0.5);
\r
303 * Return positions (world) of an InlineComponents ends
\r
308 public static void getInlineControlPointEnds(IEntity pcp, Point3d p1, Point3d p2, Vector3d dir) {
\r
309 assert (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint));
\r
311 Point3d pos = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
312 dir.set(ControlPointTools.getPathLegDirection(pcp, Direction.NEXT));
\r
313 double length = pcp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);
\r
314 Vector3d d = new Vector3d(dir);
\r
315 d.scale(length * 0.5);
\r
323 * Return positions (world) of an InlineComponents ends
\r
328 public static void getInlineControlPointEnds(IEntity pcp, Point3d center, Point3d p1, Point3d p2, Vector3d dir) {
\r
329 assert (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint));
\r
331 Point3d pos = G3DTools.getPoint(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition));
\r
333 dir.set(ControlPointTools.getPathLegDirection(pcp, Direction.NEXT));
\r
334 double length = pcp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);
\r
335 Vector3d d = new Vector3d(dir);
\r
336 d.scale(length * 0.5);
\r
343 public static double getInlineLength(IEntity pcp) {
\r
345 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.TurnControlPoint)) {
\r
346 l2 += pcp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);
\r
347 } else if (pcp.isInstanceOf(ProcessResource.plant3Dresource.InlineControlPoint)) {
\r
348 l2 += pcp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength) * 0.5;
\r
354 * Returns position (world) of a single port
\r
359 public static Point3d getRealPosition(IEntity pcp, PositionType type) {
\r
360 PipeControlPoint p= new PipeControlPoint(pcp);
\r
361 Point3d pos = G3DTools.getPoint(p.getWorldPosition());
\r
364 Vector3d dir = ControlPointTools.getPathLegDirection(pcp,Direction.NEXT);
\r
365 double length = getInlineLength(pcp);
\r
372 Vector3d dir = ControlPointTools.getPathLegDirection(pcp,Direction.PREVIOUS);
\r
373 double length = getInlineLength(pcp);
\r
380 // IEntity portDir = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.HasDirection);
\r
381 // TODO : how we calculated needed space for a port; does it has an offset from control point's position or not?
\r
391 public static void getInlineMovement(PipeControlPoint pcp, Point3d start, Point3d end) {
\r
392 // FIXME : check type of neighbor components and allow movement on top of variable length components,
\r
393 // ffind proper range for movement (pcp's position is not)
\r
394 PipeControlPoint prev = pcp.getPrevious().getPrevious();
\r
395 PipeControlPoint next = pcp.getNext().getNext();
\r
396 start.set(G3DTools.getPoint(prev.getWorldPosition()));
\r
397 end.set(G3DTools.getPoint(next.getWorldPosition()));
\r
400 public static AxisAngle4d getControlPointLocalRotation(IEntity pcp, double angle) {
\r
401 Quat4d q1 = getControlPointLocalOrientationQuat(pcp, angle);
\r
402 AxisAngle4d aa= new AxisAngle4d();
\r
407 public static AxisAngle4d getControlPointWorldRotation(IEntity pcp, double angle) {
\r
408 Quat4d q1 = getControlPointWorldOrientationQuat(pcp, angle);
\r
409 AxisAngle4d aa= new AxisAngle4d();
\r
415 public static Quat4d getControlPointLocalOrientationQuat(IEntity pcp, double angle) {
\r
416 return getControlPointLocalOrientationQuat(pcp, angle, false);
\r
419 public static Quat4d getControlPointWorldOrientationQuat(IEntity pcp, double angle) {
\r
420 return getControlPointWorldOrientationQuat(pcp, angle, false);
\r
423 public static Quat4d getControlPointLocalOrientationQuat(IEntity cp, double angle, boolean offset) {
\r
424 PipeControlPoint pcp = new PipeControlPoint(cp);
\r
425 PipeControlPoint next;
\r
426 // 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
427 // else it's more numerically stable to use next control point
\r
431 next = pcp.getNext();
\r
433 PipeControlPoint prev = pcp.getPrevious();
\r
434 assert (next != null || prev != null);
\r
437 else if (next == null)
\r
439 // TODO : check correct type
\r
440 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.PathLegEndControlPoint) && pcp.getPrevious() == null) {
\r
441 PipeControlPoint temp = next;
\r
445 Vector3d current = new Vector3d(G3DTools.getPoint(next.getLocalPosition()));
\r
446 current.sub(G3DTools.getPoint(prev.getLocalPosition()));
\r
447 current.normalize();
\r
448 return getControlPointOrientationQuat(current, angle);
\r
451 public static Quat4d getControlPointWorldOrientationQuat(IEntity cp, double angle, boolean offset) {
\r
452 PipeControlPoint pcp = new PipeControlPoint(cp);
\r
453 PipeControlPoint next;
\r
454 // 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
455 // else it's more numerically stable to use next control point
\r
459 next = pcp.getNext();
\r
461 PipeControlPoint prev = pcp.getPrevious();
\r
462 assert (next != null || prev != null);
\r
465 else if (next == null)
\r
467 // TODO : check correct type
\r
468 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.PathLegEndControlPoint) && pcp.getPrevious() == null) {
\r
469 PipeControlPoint temp = next;
\r
473 Vector3d current = new Vector3d(G3DTools.getPoint(next.getWorldPosition()));
\r
474 current.sub(G3DTools.getPoint(prev.getWorldPosition()));
\r
475 current.normalize();
\r
476 return getControlPointOrientationQuat(current, angle);
\r
479 public static Quat4d getControlPointOrientationQuat(Vector3d dir, double angle) {
\r
482 final Vector3d front = new Vector3d(1.0,0.0,0.0);
\r
484 Quat4d q1 = new Quat4d();
\r
486 Vector3d up = new Vector3d(0.0, 1.0, 0.0);
\r
487 double a = up.angle(dir);
\r
488 if (a < 0.1 || (Math.PI - a) < 0.1) {
\r
489 up.set(1.0, 0.0, 0.0);
\r
492 Vector3d right = new Vector3d();
\r
494 right.cross(dir, up);
\r
495 up.cross(right, dir);
\r
499 Matrix3d m = new Matrix3d();
\r
510 //q1.set(m); MathTools contains more stable conversion
\r
511 MathTools.getQuat(m, q1);
\r
513 if (DEBUG) System.out.println("PipingTools.getPipeComponentOrientationQuat() " + dir+ " " + up + " " + right);
\r
515 Quat4d q2 = new Quat4d();
\r
516 q2.set(new AxisAngle4d(front, angle));
\r
521 public static PipeControlPoint findPreviousEnd(PipeControlPoint tcp) {
\r
522 // TODO : optimize (we do not need the list here)
\r
523 ArrayList<PipeControlPoint> t = new ArrayList<PipeControlPoint>();
\r
524 return findPreviousEnd(tcp, t);
\r
527 public static PipeControlPoint findNextEnd(PipeControlPoint tcp) {
\r
528 // TODO : optimize (we do not need the list here)
\r
529 ArrayList<PipeControlPoint> t = new ArrayList<PipeControlPoint>();
\r
530 return findNextEnd(tcp, t);
\r
534 * Returns pipe leg's end using "nextControlPoint" relation and collects control point in the given list.
\r
539 public static PipeControlPoint findNextEnd(PipeControlPoint tcp, ArrayList<PipeControlPoint> nextList) {
\r
540 if (DEBUG) System.out.print("PipingTools.findNextEnd " + tcp.getResource());
\r
542 PipeControlPoint pcp = null;
\r
543 PipeControlPoint p = null;
\r
544 if (nextList.size() == 0)
\r
548 p = nextList.get(nextList.size() - 1);
\r
553 if (nextList.size() > 0)
\r
554 nextList.remove(nextList.size() - 1);
\r
555 if (DEBUG) System.out.println(" " + pcp.getResource() + " not full");
\r
559 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.PathLegEndControlPoint)) {
\r
560 if (DEBUG) System.out.println(" " + pcp.getResource());
\r
564 if (DEBUG) System.out.print(" " + pcp.getResource());
\r
572 * Returns pipe leg's end using "previousControlPoint" relation and collects control point in the given list.
\r
577 public static PipeControlPoint findPreviousEnd(PipeControlPoint tcp, ArrayList<PipeControlPoint> prevList) {
\r
578 if (DEBUG) System.out.print("PipingTools.findPreviousEnd " + tcp.getResource());
\r
580 PipeControlPoint pcp = null;
\r
581 PipeControlPoint p = null;
\r
582 if (prevList.size() == 0)
\r
586 p = prevList.get(prevList.size() - 1);
\r
588 pcp = p.getPrevious();
\r
591 if (prevList.size() > 0)
\r
592 prevList.remove(prevList.size() - 1);
\r
593 if (DEBUG) System.out.println(" " + pcp.getResource() + " not full");
\r
596 if (pcp.isInstanceOf(ProcessResource.plant3Dresource.PathLegEndControlPoint)) {
\r
597 if (DEBUG) System.out.println(" " + pcp.getResource());
\r
601 if (DEBUG) System.out.print(" " + pcp.getResource());
\r
606 public static PipeRun getPipeRun(PipeControlPoint pcp) {
\r
607 return pcp.getControlPointOfPipeRun();
\r
611 public static Vector3d getSizeChangeOffsetVector(PipeControlPoint sccp) {
\r
612 Quat4d q = getControlPointWorldOrientationQuat(sccp, sccp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasRotationAngle),true);
\r
613 return getSizeChangeOffsetVector(sccp,q);
\r
616 public static Vector3d getSizeChangeOffsetVector(PipeControlPoint sccp, Vector3d dir) {
\r
617 Quat4d q = getControlPointOrientationQuat(dir, sccp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasRotationAngle));
\r
618 return getSizeChangeOffsetVector(sccp,q);
\r
621 public static Vector3d getSizeChangeOffsetVector(PipeControlPoint sccp, Quat4d q) {
\r
622 Vector3d v = new Vector3d(0.0,0.0,sccp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasOffset));
\r
623 Vector3d offset = new Vector3d();
\r
624 MathTools.rotate(q, v, offset);
\r
628 public static Vector3d getDirectedControlPointDirection(IEntity dcp) {
\r
629 assert(dcp.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint));
\r
630 AxisAngle4d worldR = G3DTools.getOrientation(dcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldOrientation));
\r
631 Quat4d q = new Quat4d();
\r
633 Vector3d dir = new Vector3d();
\r
634 MathTools.rotate(q, new Vector3d(1.0, 0.0, 0.0), dir);
\r
639 public static Vector3d getNozzleDirection(IEntity rotation) {
\r
640 AxisAngle4d worldR = G3DTools.getOrientation(rotation);
\r
641 Quat4d q = new Quat4d();
\r
643 Vector3d dir = new Vector3d();
\r
644 MathTools.rotate(q, new Vector3d(1.0, 0.0, 0.0), dir);
\r
648 public static Vector3d getNozzleDirection(PipeControlPoint dcp) {
\r
649 return getNozzleDirection(dcp.getWorldOrientation());
\r
652 public static void removeControlPoint(PipeControlPoint removed) {
\r
653 if (DEBUG) System.out.println("PipingTools.removeControlPoint() controlpoint " + removed.getResource());//FIXME : offset + size change control points !
\r
655 // this code is not valid anymore.
\r
657 // different removing cases:
\r
659 // 1. Point is SizeChangeControlPoint (this is currently ok)
\r
660 // * remove offset point and component
\r
661 // * do NOT link components together
\r
663 // 2. Point is VariableLength
\r
664 // * check if its a branch (TODO : ontology support?)
\r
665 // * if so, also branch point in the other piperun may have to be removed
\r
666 // (we cannot move other components next to branch)
\r
667 // * if not, components next to removed one are moved next to each other
\r
669 // * check if there is VariableLength on both sides,
\r
670 // * if so, those must be unified to a single Variable Length component.
\r
671 // * if not, components must be moved next to each other
\r
673 // a) If removed Control Point is next to Nozzle and after the point is removed nozzle is not connected to anything
\r
674 // * nozzle's link to piperun's specs must be removed
\r
678 if (removed.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)||
\r
679 removed.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
680 // sccp & ocp connect two pipeRuns to each other; when thoes are remove, pipeRuns are not connected to each other anymore.
\r
681 removeDualPoint(removed);
\r
684 PipeControlPoint prev = removed.getPrevious();
\r
685 PipeControlPoint next = removed.getNext();
\r
686 PipeRun pipeRun = getPipeRun(removed);
\r
687 if (pipeRun == null)
\r
689 if (next == null && prev == null) {
\r
690 if (removed.isInstanceOf(ProcessResource.plant3Dresource.NozzleControlPoint)) {
\r
691 // Nozzle's control point does not need to be removed, only unlinked
\r
692 // TODO : what about component ports?
\r
693 PipingTools2.unlinkNozzleAndPiperun(removed.getSingleRelatedObject(ProcessResource.plant3Dresource.ControlPointOf), ControlPointTools.getPipeRun(removed));
\r
698 if (next != null && prev != null) {
\r
699 boolean link = true;
\r
700 if (next.isInstanceOf(ProcessResource.plant3Dresource.BranchEndControlPoint)){
\r
702 next.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
703 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
704 removeControlPoint(next);
\r
706 if (prev.isInstanceOf(ProcessResource.plant3Dresource.BranchEndControlPoint)) {
\r
708 prev.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
709 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
710 removeControlPoint(prev);
\r
712 if (link && prev.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint)&&
\r
713 next.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint)) {
\r
716 if (next.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
717 PipeControlPoint sccp = next;
\r
718 PipeControlPoint ocp = sccp.getSubPoint().iterator().next();
\r
720 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource()+ " structure damaged, no offset control point",null);
\r
724 sccp.setPrevious(prev);
\r
725 ocp.setPrevious(prev);
\r
727 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
728 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
731 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
732 } else if (next.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
733 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource()+ " structure damaged, next control point is offset control point",null);
\r
735 } else if (next.getPrevious().getResource().equals(removed.getResource())) {
\r
737 next.setPrevious(prev);
\r
739 next.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
741 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
743 ErrorLogger.defaultLogError("Removing PipeControlPoint "+ removed.getResource()+ " structure damaged", null);
\r
746 if (prev.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
747 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged, previous control point is size change control point", null);
\r
749 } else if (prev.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
750 PipeControlPoint ocp = prev;
\r
751 PipeControlPoint sccp = ocp.getSubPointOf();
\r
752 if (sccp == null) {
\r
753 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged, no size change control point",null);
\r
758 sccp.setNext(next);
\r
760 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
761 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
763 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
764 } else if (prev.getNext().getResource().equals(removed.getResource())) {
\r
766 prev.setNext(next);
\r
768 prev.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
769 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
771 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged", null);
\r
775 if (next.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthControlPoint) &&
\r
776 prev.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthControlPoint)) {
\r
777 // we have to join them into single variable length component.
\r
778 removeControlPoint(prev);
\r
783 } else if (next != null) {
\r
784 if (next.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
785 PipeControlPoint sccp = next;
\r
786 PipeControlPoint ocp = sccp.getSubPoint().iterator().next();
\r
788 ErrorLogger.defaultLogError("Removing PipeControlPoint "+ removed.getResource()+ " structure damaged, no offset control point",null);
\r
791 next.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
792 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
793 } else if (next.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
794 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged, next control point is offset control point", null);
\r
796 } else if (next.getPrevious().getResource().equals(removed.getResource())) {
\r
797 next.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
799 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged", null);
\r
802 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
803 } else { //(prev != null)
\r
804 if (prev.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
805 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged, previous control point is size change control point", null);
\r
807 } else if (prev.isInstanceOf(ProcessResource.plant3Dresource.DualSubControlPoint)) {
\r
808 PipeControlPoint ocp = prev;
\r
809 PipeControlPoint sccp = ocp.getSubPointOf();
\r
810 if (sccp == null) {
\r
811 ErrorLogger.defaultLogError("Removing PipeControlPoint " + removed.getResource() + " structure damaged, no size change control point", null);
\r
814 prev.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
815 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
816 } else if (prev.getNext().getResource().equals(removed.getResource())) {
\r
817 prev.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
819 ErrorLogger.defaultLogError("Removing PipeControlPoint "+ removed.getResource() + " structure damaged", null);
\r
822 removed.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
826 if (removed.getSubPoint().size() > 0 ) {
\r
827 removeSubPoints(removed);
\r
828 } else if (removed.getSubPointOf() != null) {
\r
829 removeParentPoint(removed);
\r
832 removeComponents(removed);
\r
834 pipeRun.removeStatement(ProcessResource.plant3Dresource.HasControlPoints, removed);
\r
835 if (pipeRun.getChild().size() == 0) {
\r
836 PipingTools2.removePipeRun(pipeRun);
\r
838 else if (pipeRun.getControlPoints().size() == 1) {
\r
839 removeControlPoint(pipeRun.getControlPoints().iterator().next());
\r
845 private static void removeDualPoint(PipeControlPoint removed) {
\r
846 PipeControlPoint prev = removed.getPrevious();
\r
847 PipeControlPoint next = removed.getNext();
\r
848 if (prev != null) {
\r
849 prev.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
852 next.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
853 PipeControlPoint ocp;
\r
854 PipeControlPoint sccp;
\r
855 // get sccp / ocp pair
\r
856 if (removed.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
858 ocp = sccp.getSubPoint().iterator().next();
\r
862 sccp = ocp.getSubPointOf();
\r
864 PipeRun p1 = getPipeRun(ocp);
\r
865 PipeRun p2 = getPipeRun(sccp);
\r
867 // removes all components connected to control point
\r
869 removeComponents(ocp);
\r
871 removeComponents(sccp);
\r
873 // remove control points from pipeRuns
\r
874 p1.removeStatement(ProcessResource.plant3Dresource.HasControlPoints, ocp);
\r
875 p2.removeStatement(ProcessResource.plant3Dresource.HasControlPoints, sccp);
\r
877 // remove links to other control points
\r
878 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
879 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasNext);
\r
880 ocp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
881 sccp.removeRelatedStatements(ProcessResource.plant3Dresource.HasPrevious);
\r
883 // if pipeRuns contains no other components(control points), they can be removed too.
\r
884 if (p1.getControlPoints().size() == 0) {
\r
885 PipingTools2.removePipeRun(p1);
\r
886 } else if (p1.getControlPoints().size() == 1) {
\r
887 removeControlPoint(p1.getControlPoints().iterator().next());
\r
889 if (p2.getControlPoints().size() == 0) {
\r
890 PipingTools2.removePipeRun(p2);
\r
891 } else if (p2.getControlPoints().size() == 1) {
\r
892 removeControlPoint(p2.getControlPoints().iterator().next());
\r
897 * Removes sub points of a point
\r
899 * @throws TransactionException
\r
901 private static void removeSubPoints(PipeControlPoint removed) {
\r
902 // if control point is branch control point, all branch of points must be removed too
\r
903 Collection<PipeControlPoint> points = removed.getSubPoint();
\r
905 for (PipeControlPoint p : points) {
\r
906 removed.removeStatement(ProcessResource.plant3Dresource.HasSubPoint, p);
\r
907 removeControlPoint(p);
\r
912 * Removed point is a subpoint of something,
\r
915 private static void removeParentPoint(PipeControlPoint removed) {
\r
916 throw new RuntimeException("Subpoints cannot be removed");
\r
918 // if control point is branch it has to be removed from branch control point
\r
919 // BranchEndControlPoint ecp = BranchEndControlPointFactory.create(removed);
\r
920 // BranchControlPoint bcp = null;
\r
921 // if (ecp.getBranchOfPointSet().size() == 1) {
\r
922 // bcp = ecp.getBranchOfPointSet().iterator().next();
\r
924 // if (bcp != null) {
\r
925 // bcp.getBranchPointSet().remove(ecp);
\r
926 // if (bcp.getBranchPointSet().size() == 0) {
\r
927 // // branch control point is not used and can be removed
\r
928 // removeControlPoint(bcp);
\r
934 private static void removeComponents(PipeControlPoint pcp) {
\r
935 IEntity component = pcp.getControlPointOf();
\r
936 if (component != null) {
\r
937 PipeRun p1 = getPipeRun(pcp);
\r
938 p1.removeStatement(ProcessResource.g3dResource.HasChild, component);
\r
939 component.removeRelatedStatements(ProcessResource.plant3Dresource.HasControlPoint);
\r
943 private static void setStatement(IEntity subject, Resource relation, IEntity object) {
\r
944 subject.removeRelatedStatements(relation);
\r
945 subject.addStatement(relation, object);
\r
949 public static void setWorldPosition(IEntity pcp, Tuple3d position) {
\r
950 IEntity wp = pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition);
\r
951 G3DTools.setTuple3(wp, position);
\r
952 tt.propagateWorldTransformChange(tt.getParent(pcp), pcp);
\r
956 public static void setLocalPosition(IEntity pcp, Tuple3d position) {
\r
957 G3DTools.setTuple3(pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasLocalPosition), position);
\r
958 tt.propagateLocalTransformChange(tt.getParent(pcp), pcp);
\r
961 public static void setWorldOrientation(IEntity node, AxisAngle4d orientation) {
\r
962 G3DTools.setOrientation(node.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldOrientation), orientation);
\r
963 tt.propagateWorldTransformChange(tt.getParent(node), node);
\r
967 public static void setLocalOrientation(IEntity node, AxisAngle4d orientation) {
\r
968 G3DTools.setOrientation(node.getSingleRelatedObject(ProcessResource.g3dResource.HasLocalOrientation), orientation);
\r
969 tt.propagateLocalTransformChange(tt.getParent(node), node);
\r
972 private static boolean updatePosition(IEntity pcp) {
\r
973 return tt.transformationUpdate(pcp);
\r
976 // TODO : orientation is also needed, current code handles only position
\r
977 // TODO : reuse the code in G3DTools!
\r
979 IEntity worldPosition = pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition);
\r
980 IEntity localPosition = pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasLocalPosition);
\r
983 Tuple3d worldP = G3DTools.getPoint(worldPosition);
\r
984 Tuple3d localP = G3DTools.getPoint(localPosition);
\r
986 if (localP == null || worldP == null)
\r
988 if (!isValid(worldP) && !isValid(localP))
\r
991 Tuple3d cachedWorldP = (Tuple3d) getProperty(worldPosition.getResource());
\r
992 Tuple3d cachedLocalP = (Tuple3d) getProperty(localPosition.getResource());
\r
994 if (DEBUG) System.out.println("PipeControlPoint changed " + worldP + " " + cachedWorldP + " " + localP + " " + cachedLocalP);
\r
995 boolean changed = false;
\r
997 IEntity parent = pcp.getSingleRelatedObject(ProcessResource.plant3Dresource.ControlPointOf);
\r
999 if (parent == null) {
\r
1000 if (DEBUG) System.out.println("PipeControlPoint changed, no parent node");
\r
1004 if (cachedLocalP == null) {
\r
1005 storeProperty(localPosition.getResource(), localP);
\r
1006 Tuple3d p = G3DTools.getWorldFromLocal(parent, new Point3d(localP));
\r
1007 storeProperty(worldPosition.getResource(), p);
\r
1008 G3DTools.setTuple3(worldPosition, p);
\r
1009 if (DEBUG) System.out.println("PipeControlPoint changed local " + worldP + " " + p);
\r
1012 if (TransformationTools.changed(cachedLocalP, localP)) {
\r
1013 storeProperty(localPosition.getResource(), localP);
\r
1014 Tuple3d p = G3DTools.getWorldFromLocal(parent, new Point3d(localP));
\r
1015 storeProperty(worldPosition.getResource(), p);
\r
1016 G3DTools.setTuple3(worldPosition, p);
\r
1017 if (DEBUG) System.out.println("PipeControlPoint changed local " + worldP + " " + localP);
\r
1020 if (cachedWorldP == null) {
\r
1021 storeProperty(worldPosition.getResource(), worldP);
\r
1022 Tuple3d p = G3DTools.getLocalFromWorld(parent, new Point3d(worldP));
\r
1023 G3DTools.setTuple3(localPosition, p);
\r
1024 storeProperty(localPosition.getResource(), p);
\r
1025 if (DEBUG) System.out.println("PipeControlPoint changed world " + worldP + " " + p);
\r
1028 if (TransformationTools.changed(cachedWorldP, worldP)) {
\r
1029 storeProperty(worldPosition.getResource(), worldP);
\r
1030 Tuple3d p = G3DTools.getLocalFromWorld(parent, new Point3d(worldP));
\r
1031 G3DTools.setTuple3(localPosition, p);
\r
1032 storeProperty(localPosition.getResource(), p);
\r
1033 if (DEBUG) System.out.println("PipeControlPoint changed world " + worldP + " " + p);
\r
1042 static boolean isControlPointChanged(PipeControlPoint node) {
\r
1044 long id = node.getResource().getResourceId();
\r
1046 boolean changed = updatePosition(node);
\r
1048 if (node.isInstanceOf(ProcessResource.plant3Dresource.PathLegEndControlPoint)) {
\r
1049 if (node.isInstanceOf(ProcessResource.plant3Dresource.TurnControlPoint)) {
\r
1050 Pair<Long,Long> connected = (Pair<Long,Long>)getProperty(node.getResource().getResourceId());
\r
1051 PipeControlPoint next = node.getNext();
\r
1052 PipeControlPoint prev = node.getPrevious();
\r
1053 if ((next != null && prev != null) && (
\r
1054 connected == null ||
\r
1055 (connected.first == null && prev != null) ||
\r
1056 (connected.second == null && next != null) ||
\r
1057 !connected.first.equals(prev.getResource().getResourceId()) ||
\r
1058 !connected.second.equals(next.getResource().getResourceId()))) {
\r
1059 storeProperty(id, new Pair<Long,Long>(prev.getResource().getResourceId(),next.getResource().getResourceId()));
\r
1062 if (node.isInstanceOf(ProcessResource.plant3Dresource.VariableAngleTurnControlPoint)) {
\r
1063 double r = node.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasTurnRadius);
\r
1064 Double d = (Double)getProperty(id + ":turnradius");
\r
1065 if (d == null || TransformationTools.changed(r, d)) {
\r
1066 storeProperty(id + ":turnradius", r);
\r
1071 else if (node.isInstanceOf(ProcessResource.plant3Dresource.DirectedControlPoint)) {
\r
1072 Vector3d dir = ControlPointTools.getDirectedControlPointDirection(node);
\r
1073 Vector3d old = (Vector3d)getProperty(id + ":direction");
\r
1074 if (old == null || TransformationTools.changed(dir, old)) {
\r
1075 storeProperty(id + ":direction", dir);
\r
1079 } else { // InlineControlPoint
\r
1080 if (node.isInstanceOf(ProcessResource.plant3Dresource.FixedLengthControlPoint)) {
\r
1081 double length = node.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasLength);
\r
1082 Double d = (Double)getProperty(id + ":length");
\r
1086 changed = changed || TransformationTools.changed(length, d);
\r
1089 storeProperty(id + ":length", length);
\r
1093 if (node.isInstanceOf(ProcessResource.plant3Dresource.DualInlineControlPoint)) {
\r
1095 double angle = node.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasRotationAngle);
\r
1096 Double d = (Double)getProperty(id + ":rotationangle");
\r
1100 changed = changed || TransformationTools.changed(angle, d);
\r
1102 storeProperty(id + ":rotationangle", angle);
\r
1105 Collection<PipeControlPoint> subpoints = node.getSubPoint();
\r
1106 if (subpoints.size() != 1)
\r
1107 throw new RuntimeException("Current implementation assumes that size change components are dual conmnected");
\r
1108 PipeControlPoint ocp = subpoints.iterator().next();
\r
1109 if (node.isInstanceOf(ProcessResource.plant3Dresource.OffsettingPoint)) {
\r
1110 double offset = ocp.getSingleRelatedScalarDouble(ProcessResource.plant3Dresource.HasOffset);
\r
1111 d = (Double)getProperty(id +":offset");
\r
1115 changed = TransformationTools.changed(offset, d);
\r
1117 storeProperty(id+":offset", offset);
\r
1121 // } else if (node instanceof OffsetControlPoint) {
\r
1122 // OffsetControlPoint ocp = (OffsetControlPoint)node;
\r
1124 // } else if (node instanceof BranchControlPoint) {
\r
1125 // BranchControlPoint bcp = (BranchControlPoint)node;
\r
1126 // int size = bcp.getBranchPointSet().size();
\r
1127 // Integer i = (Integer)getProperty(bcp.getResource().getId());
\r
1131 // changed = changed || i != size;
\r
1133 // storeProperty(bcp.getResource().getId(), size);
\r
1143 private static boolean isValid(Tuple3d v) {
\r
1144 if (Double.isInfinite(v.x) ||
\r
1145 Double.isNaN(v.x) ||
\r
1146 Double.isInfinite(v.y) ||
\r
1147 Double.isNaN(v.y) ||
\r
1148 Double.isInfinite(v.z) ||
\r
1149 Double.isNaN(v.z))
\r
1154 private static HashMap<Object, Object> properties = new HashMap<Object, Object>();
\r
1156 public static Object getProperty(Object key) {
\r
1157 return properties.get(key);
\r
1160 public static void storeProperty(Object key, Object value) {
\r
1161 properties.put(key, value);
\r
1165 * Loads positions of controlpoint to rule cache
\r
1167 * TODO : this caches only transformation information : other info must be cached too
\r
1169 * @param root resource of the modeled plant
\r
1171 public static void reloadCache(Graph graph, Resource root) {
\r
1173 Stack<IEntity> stack = new Stack<IEntity>();
\r
1174 stack.add(EntityFactory.create(graph,root));
\r
1175 while (!stack.isEmpty()) {
\r
1176 IEntity current = stack.pop();
\r
1177 IEntity pcp = current.getAtMostOneRelatedObject(ProcessResource.plant3Dresource.HasControlPoint);
\r
1178 if (pcp == null) {
\r
1179 stack.addAll(current.getRelatedObjects(ProcessResource.g3dResource.HasChild));
\r
1181 if (DEBUG) System.out.println("Cached pcp " + pcp.getResource());
\r
1182 IEntity localPos = pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasLocalPosition);
\r
1183 IEntity worldPos = pcp.getSingleRelatedObject(ProcessResource.g3dResource.HasWorldPosition);
\r
1185 tt.storeProperty(localPos.getResource(),G3DTools.getPoint(localPos));
\r
1186 tt.storeProperty(worldPos.getResource(),G3DTools.getPoint(worldPos));
\r
1188 IEntity localOr = pcp.getAtMostOneRelatedObject(ProcessResource.g3dResource.HasLocalOrientation);
\r
1189 IEntity worldOr = pcp.getAtMostOneRelatedObject(ProcessResource.g3dResource.HasWorldOrientation);
\r
1191 if (worldOr != null) {
\r
1192 tt.storeProperty(localOr.getResource(),G3DTools.getOrientation(localOr));
\r
1193 tt.storeProperty(worldOr.getResource(),G3DTools.getOrientation(worldOr));
\r
1196 stack.addAll(pcp.getRelatedObjects(ProcessResource.plant3Dresource.HasSubPoint));
\r