1 package org.simantics.plant3d.scenegraph;
3 import java.util.Collections;
6 import javax.vecmath.Quat4d;
7 import javax.vecmath.Tuple3d;
8 import javax.vecmath.Vector3d;
10 import org.simantics.g3d.math.MathTools;
11 import org.simantics.g3d.property.annotations.GetPropertyValue;
12 import org.simantics.g3d.property.annotations.PropertyContributor;
13 import org.simantics.objmap.graph.annotations.RelatedGetObj;
14 import org.simantics.objmap.graph.annotations.RelatedSetObj;
15 import org.simantics.plant3d.ontology.Plant3D;
16 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
17 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Type;
18 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
22 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
26 public abstract class PipelineComponent extends GeometryNode {
29 private PipeRun pipeRun;
30 private PipeRun alternativePipeRun;
31 private PipelineComponent next;
32 private PipelineComponent previous;
37 * With in-line,turn, and end components, the pipe run is the parent object in the scene-graph.
38 * With nozzles, the pipe run setting is explicit (nozzle has to be linked to the piperun, since the parent object is equipment).
39 * With size change components (in-line), there is also alternative pipe run, which must match the next component's pipe run.
43 public void setPipeRun(PipeRun pipeRun) {
44 if (pipeRun == this.pipeRun)
46 this.pipeRun = pipeRun;
47 if (getControlPoint() != null) {
48 getControlPoint().deattach();
49 if (pipeRun != null) {
50 pipeRun.addChild(getControlPoint());
56 @RelatedGetObj(Plant3D.URIs.HasAlternativePipeRun)
57 public PipeRun getAlternativePipeRun() {
58 return alternativePipeRun;
61 @RelatedSetObj(Plant3D.URIs.HasAlternativePipeRun)
62 public void setAlternativePipeRun(PipeRun pipeRun) {
63 if (this.alternativePipeRun == pipeRun)
65 this.alternativePipeRun = pipeRun;
66 if (getControlPoint().isDualInline()) {
67 PipeControlPoint sub = getControlPoint().getSubPoint().get(0);
68 if (sub.getParent() != this.alternativePipeRun)
69 this.alternativePipeRun.addChild(sub);
71 firePropertyChanged(Plant3D.URIs.HasAlternativePipeRun);
75 public void updateParameters() {
76 setParameterMap(updateParameterMap());
77 super.updateParameters();
80 public abstract void setType(String typeURI) throws Exception;
82 @RelatedGetObj(Plant3D.URIs.HasNext)
83 public PipelineComponent getNext() {
87 @RelatedSetObj(Plant3D.URIs.HasNext)
88 public void setNext(PipelineComponent comp) {
91 if (this.next != null)
92 this.next._removeRef(this);
94 this.syncnext = false;
96 firePropertyChanged(Plant3D.URIs.HasNext);
99 // System.out.println(this + " next " + comp);
103 @RelatedGetObj(Plant3D.URIs.HasPrevious)
104 public PipelineComponent getPrevious() {
108 @RelatedSetObj(Plant3D.URIs.HasPrevious)
109 public void setPrevious(PipelineComponent comp) {
110 if (previous == comp)
112 if (this.previous != null)
113 this.previous._removeRef(this);
114 this.previous = comp;
115 this.syncprev = false;
117 firePropertyChanged(Plant3D.URIs.HasPrevious);
120 // System.out.println(this + " prev " + comp);
122 private PipelineComponent branch0;
124 @RelatedGetObj(Plant3D.URIs.HasBranch0)
125 public PipelineComponent getBranch0() {
129 @RelatedSetObj(Plant3D.URIs.HasBranch0)
130 public void setBranch0(PipelineComponent comp) {
133 if (this.branch0 != null)
134 this.branch0._removeRef(this);
136 this.syncbr0 = false;
138 firePropertyChanged(Plant3D.URIs.HasBranch0);
141 // System.out.println(this + " next " + comp);
144 @GetPropertyValue(name="Previous",tabId="Debug",value=Plant3D.URIs.HasPrevious)
145 public String getPreviousDebug() {
146 if (previous == null)
148 return previous.getName();
151 @GetPropertyValue(name="Next",tabId="Debug",value=Plant3D.URIs.HasNext)
152 public String getNextDebug() {
155 return next.getName();
158 @GetPropertyValue(name="Branch0",tabId="Debug",value=Plant3D.URIs.HasBranch0)
159 public String getBR0Debug() {
162 return branch0.getName();
167 private PipeControlPoint getBranchPoint() {
168 PipeControlPoint branchPoint;
169 if (getControlPoint().getSubPoint().size() > 0) {
170 branchPoint = getControlPoint().getSubPoint().get(0);
172 if (branch0.getPipeRun() == null)
174 branchPoint = new PipeControlPoint(this,branch0.getPipeRun());
175 branchPoint.setFixed(false);
176 branchPoint.setType(Type.END);
177 branchPoint.parent = getControlPoint();
178 getControlPoint().children.add(branchPoint);
179 branchPoint.setWorldOrientation(getControlPoint().getWorldOrientation());
180 branchPoint.setWorldPosition(getControlPoint().getWorldPosition());
185 private boolean _connectNext(PipeControlPoint pcp, PipeControlPoint nextPCP) {
188 if (pcp.getNext() != nextPCP) {
189 pcp.setNext(nextPCP);
191 if (pcp.isDualInline()) {
192 PipeControlPoint sub = pcp.getSubPoint().get(0);
193 if (sub.getNext() != nextPCP)
194 sub.setNext(nextPCP);
199 private boolean _connectPrev(PipeControlPoint pcp, PipeControlPoint prevPCP) {
202 if (prevPCP.isDualInline())
203 prevPCP = prevPCP.getSubPoint().get(0);
204 if (pcp.getPrevious() != prevPCP) {
205 pcp.setPrevious(prevPCP);
207 if (pcp.isDualInline()) {
208 PipeControlPoint sub = pcp.getSubPoint().get(0);
209 if (sub.getPrevious() != prevPCP)
210 sub.setPrevious(prevPCP);
215 // When link to a component is removed, also link to the other direction must be removed at the same time, or
216 // Control point structure is left into illegal state.
217 private void _removeRef(PipelineComponent comp) {
222 } else if (previous == comp) {
226 } else if (branch0 == comp) {
233 boolean syncnext = false;
234 private void syncNext() {
237 syncnext = _syncNext();
241 private boolean _syncNext() {
242 PipeControlPoint pcp = getControlPoint();
246 if (next.getControlPoint() != null) {
248 // TODO, relying that the other direction is connected.
249 boolean nxt = next.getPrevious() == this;
250 boolean br0 = next.getBranch0() == this;
252 return _connectNext(pcp, next.getControlPoint());
254 return _connectNext(pcp, next.getBranchPoint());
262 } else if (pcp.getNext() != null) {
272 boolean syncprev = false;
273 private void syncPrevious() {
276 syncprev = _syncPrevious();
279 private boolean _syncPrevious() {
280 PipeControlPoint pcp = getControlPoint();
282 if (previous != null ) {
283 if (previous.getControlPoint() != null) {
285 // TODO, relying that the other direction is connected.
286 boolean prev = previous.getNext() == this;
287 boolean br0 = previous.getBranch0() == this;
289 return _connectPrev(pcp, previous.getControlPoint());
291 return _connectPrev(pcp, previous.getBranchPoint());
299 } else if (pcp.getPrevious() != null) {
300 pcp.setPrevious(null);
309 boolean syncbr0 = false;
310 private void syncBranch0() {
313 syncbr0 = _syncBranch0();
316 private boolean _syncBranch0() {
317 if (getControlPoint() != null) {
318 if (getControlPoint().isDualInline()) {
322 if (branch0 != null) {
323 if (branch0.getControlPoint() != null) {
324 PipeControlPoint branchPoint = getBranchPoint();
325 PipeControlPoint pcp = branch0.getControlPoint();
326 // TODO, relying that the other direction is connected.
327 boolean next = branch0.getPrevious() == this; // this --> branch0
328 boolean prev = branch0.getNext() == this;
330 _connectNext(branchPoint, pcp);
332 _connectPrev(branchPoint, pcp);
341 } else if (getControlPoint().getSubPoint().size() > 0) { // TODO : this may cause problems? (Removes branch point, before branch has been set?)
342 getControlPoint().getSubPoint().get(0).remove();
343 getControlPoint().children.clear();
358 public void sync2() {
359 // if (getControlPoint().isDualInline()) {
360 // PipeControlPoint sub = getControlPoint().getSubPoint().get(0);
361 // next.getControlPoint().getPipeRun().addChild(sub);
363 getControlPoint()._setWorldOrientation(getWorldOrientation());
364 getControlPoint()._setWorldPosition(getWorldPosition());
367 public Map<String,Object> updateParameterMap() {
368 return Collections.EMPTY_MAP;
371 public PipeRun getPipeRun() {
375 public abstract String getType();
376 public abstract PipeControlPoint getControlPoint();
379 public void remove() {
380 PipeControlPoint pcp = getControlPoint();
381 // Second check is needed, when remove process is initiated from control point.
382 if (pcp != null && pcp.getPipelineComponent() != null) {
389 protected double[] getColor() {
390 if (getControlPoint() == null || !getControlPoint().isFixed())
391 return new double[]{0.7,0.7,0.7};
393 return new double[]{1.0,0.0,0.0};
397 protected double[] getSelectedColor() {
398 return new double[]{0.5,0,0.5};
402 public void setOrientation(Quat4d orientation) {
403 if (MathTools.equals(orientation, getOrientation()))
405 super.setOrientation(orientation);
406 if (getControlPoint() != null) {
407 getControlPoint()._setWorldOrientation(getWorldOrientation());
409 PipingRules.requestUpdate(getControlPoint());
410 } catch (Exception e) {
411 // TODO Auto-generated catch block
418 public void setPosition(Vector3d position) {
419 if (MathTools.equals(position, getPosition()))
421 super.setPosition(position);
422 if (getControlPoint() != null) {
423 getControlPoint()._setWorldPosition(getWorldPosition());
425 PipingRules.requestUpdate(getControlPoint());
426 } catch (Exception e) {
427 // TODO Auto-generated catch block
434 public void _setWorldPosition(Vector3d position) {
435 Vector3d localPos = getLocalPosition(position);
436 super.setPosition(localPos);
439 public void _setWorldOrientation(Quat4d orientation) {
440 Quat4d localOr = getLocalOrientation(orientation);
441 super.setOrientation(localOr);
444 @GetPropertyValue(name="Flow Length", value="flowlength", tabId = "Default")
445 public Double getFlowLength() {
446 PipeControlPoint pcp = getControlPoint();
449 switch (pcp.getType()) {
451 return pcp.getLength();
455 double r = getPipeRun().getTurnRadius();
456 double a = pcp.getTurnAngle();
464 public void getControlPointEnds(Tuple3d p1, Tuple3d p2) {
465 getControlPoint().getControlPointEnds(p1, p2);
468 public Vector3d getNormal() {
469 Vector3d v = new Vector3d();
470 MathTools.rotate(getWorldOrientation(), MathTools.Z_AXIS, v);