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;
34 public PipeRun getPipeRun() {
41 * With in-line,turn, and end components, the pipe run is the parent object in the scene-graph.
42 * With nozzles, the pipe run setting is explicit (nozzle has to be linked to the piperun, since the parent object is equipment).
43 * With size change components (in-line), there is also alternative pipe run, which must match the next component's pipe run.
47 public void setPipeRun(PipeRun pipeRun) {
48 if (pipeRun == this.pipeRun)
50 this.pipeRun = pipeRun;
51 if (getControlPoint() != null) {
52 getControlPoint().deattach();
53 if (pipeRun != null) {
54 pipeRun.addChild(getControlPoint());
60 @RelatedGetObj(Plant3D.URIs.HasAlternativePipeRun)
61 public PipeRun getAlternativePipeRun() {
62 return alternativePipeRun;
65 @RelatedSetObj(Plant3D.URIs.HasAlternativePipeRun)
66 public void setAlternativePipeRun(PipeRun pipeRun) {
67 if (this.alternativePipeRun == pipeRun)
69 this.alternativePipeRun = pipeRun;
70 if (getControlPoint().isDualInline()) {
71 PipeControlPoint sub = getControlPoint().getSubPoint().get(0);
72 if (sub.getParent() != this.alternativePipeRun)
73 this.alternativePipeRun.addChild(sub);
75 firePropertyChanged(Plant3D.URIs.HasAlternativePipeRun);
79 public void updateParameters() {
80 setParameterMap(updateParameterMap());
81 super.updateParameters();
84 public abstract void setType(String typeURI) throws Exception;
86 @RelatedGetObj(Plant3D.URIs.HasNext)
87 public PipelineComponent getNext() {
91 @RelatedSetObj(Plant3D.URIs.HasNext)
92 public void setNext(PipelineComponent comp) {
95 if (this.next != null)
96 this.next._removeRef(this);
98 this.syncnext = false;
100 firePropertyChanged(Plant3D.URIs.HasNext);
103 // System.out.println(this + " next " + comp);
107 @RelatedGetObj(Plant3D.URIs.HasPrevious)
108 public PipelineComponent getPrevious() {
112 @RelatedSetObj(Plant3D.URIs.HasPrevious)
113 public void setPrevious(PipelineComponent comp) {
114 if (previous == comp)
116 if (this.previous != null)
117 this.previous._removeRef(this);
118 this.previous = comp;
119 this.syncprev = false;
121 firePropertyChanged(Plant3D.URIs.HasPrevious);
124 // System.out.println(this + " prev " + comp);
126 private PipelineComponent branch0;
128 @RelatedGetObj(Plant3D.URIs.HasBranch0)
129 public PipelineComponent getBranch0() {
133 @RelatedSetObj(Plant3D.URIs.HasBranch0)
134 public void setBranch0(PipelineComponent comp) {
137 if (this.branch0 != null)
138 this.branch0._removeRef(this);
140 this.syncbr0 = false;
142 firePropertyChanged(Plant3D.URIs.HasBranch0);
145 // System.out.println(this + " next " + comp);
148 @GetPropertyValue(name="Previous",tabId="Debug",value=Plant3D.URIs.HasPrevious)
149 public String getPreviousDebug() {
150 if (previous == null)
152 return previous.getName();
155 @GetPropertyValue(name="Next",tabId="Debug",value=Plant3D.URIs.HasNext)
156 public String getNextDebug() {
159 return next.getName();
162 @GetPropertyValue(name="Branch0",tabId="Debug",value=Plant3D.URIs.HasBranch0)
163 public String getBR0Debug() {
166 return branch0.getName();
171 private PipeControlPoint getBranchPoint() {
172 PipeControlPoint branchPoint;
173 if (getControlPoint().getSubPoint().size() > 0) {
174 branchPoint = getControlPoint().getSubPoint().get(0);
176 if (branch0.getPipeRun() == null)
178 branchPoint = new PipeControlPoint(this,branch0.getPipeRun());
179 branchPoint.setFixed(false);
180 branchPoint.setType(Type.END);
181 branchPoint.parent = getControlPoint();
182 getControlPoint().children.add(branchPoint);
183 branchPoint.setWorldOrientation(getControlPoint().getWorldOrientation());
184 branchPoint.setWorldPosition(getControlPoint().getWorldPosition());
189 private boolean _connectNext(PipeControlPoint pcp, PipeControlPoint nextPCP) {
192 if (pcp.getNext() != nextPCP) {
193 pcp.setNext(nextPCP);
195 if (pcp.isDualInline()) {
196 PipeControlPoint sub = pcp.getSubPoint().get(0);
197 if (sub.getNext() != nextPCP)
198 sub.setNext(nextPCP);
203 private boolean _connectPrev(PipeControlPoint pcp, PipeControlPoint prevPCP) {
206 if (prevPCP.isDualInline())
207 prevPCP = prevPCP.getSubPoint().get(0);
208 if (pcp.getPrevious() != prevPCP) {
209 pcp.setPrevious(prevPCP);
211 if (pcp.isDualInline()) {
212 PipeControlPoint sub = pcp.getSubPoint().get(0);
213 if (sub.getPrevious() != prevPCP)
214 sub.setPrevious(prevPCP);
219 // When link to a component is removed, also link to the other direction must be removed at the same time, or
220 // Control point structure is left into illegal state.
221 private void _removeRef(PipelineComponent comp) {
226 } else if (previous == comp) {
230 } else if (branch0 == comp) {
237 boolean syncnext = false;
238 private void syncNext() {
241 syncnext = _syncNext();
245 private boolean _syncNext() {
246 PipeControlPoint pcp = getControlPoint();
250 if (next.getControlPoint() != null) {
252 // TODO, relying that the other direction is connected.
253 boolean nxt = next.getPrevious() == this;
254 boolean br0 = next.getBranch0() == this;
256 return _connectNext(pcp, next.getControlPoint());
258 return _connectNext(pcp, next.getBranchPoint());
266 } else if (pcp.getNext() != null) {
276 boolean syncprev = false;
277 private void syncPrevious() {
280 syncprev = _syncPrevious();
283 private boolean _syncPrevious() {
284 PipeControlPoint pcp = getControlPoint();
286 if (previous != null ) {
287 if (previous.getControlPoint() != null) {
289 // TODO, relying that the other direction is connected.
290 boolean prev = previous.getNext() == this;
291 boolean br0 = previous.getBranch0() == this;
293 return _connectPrev(pcp, previous.getControlPoint());
295 return _connectPrev(pcp, previous.getBranchPoint());
303 } else if (pcp.getPrevious() != null) {
304 pcp.setPrevious(null);
313 boolean syncbr0 = false;
314 private void syncBranch0() {
317 syncbr0 = _syncBranch0();
320 private boolean _syncBranch0() {
321 if (getControlPoint() != null) {
322 if (getControlPoint().isDualInline()) {
326 if (branch0 != null) {
327 if (branch0.getControlPoint() != null) {
328 PipeControlPoint branchPoint = getBranchPoint();
329 if (branchPoint == null)
331 PipeControlPoint pcp = branch0.getControlPoint();
332 // TODO, relying that the other direction is connected.
333 boolean next = branch0.getPrevious() == this; // this --> branch0
334 boolean prev = branch0.getNext() == this;
336 _connectNext(branchPoint, pcp);
338 _connectPrev(branchPoint, pcp);
347 } else if (getControlPoint().getSubPoint().size() > 0) { // TODO : this may cause problems? (Removes branch point, before branch has been set?)
348 getControlPoint().getSubPoint().get(0).remove();
349 getControlPoint().children.clear();
364 public void sync2() {
365 // if (getControlPoint().isDualInline()) {
366 // PipeControlPoint sub = getControlPoint().getSubPoint().get(0);
367 // next.getControlPoint().getPipeRun().addChild(sub);
369 getControlPoint()._setWorldOrientation(getWorldOrientation());
370 getControlPoint()._setWorldPosition(getWorldPosition());
373 public Map<String,Object> updateParameterMap() {
374 return Collections.EMPTY_MAP;
377 public abstract String getType();
378 public abstract PipeControlPoint getControlPoint();
381 public void remove() {
382 PipeControlPoint pcp = getControlPoint();
383 // Second check is needed, when remove process is initiated from control point.
384 if (pcp != null && pcp.getPipelineComponent() != null) {
391 protected double[] getColor() {
392 if (getControlPoint() == null || !getControlPoint().isFixed())
393 return new double[]{0.7,0.7,0.7};
395 return new double[]{1.0,0.0,0.0};
399 protected double[] getSelectedColor() {
400 return new double[]{0.5,0,0.5};
404 public void setOrientation(Quat4d orientation) {
405 if (MathTools.equals(orientation, getOrientation()))
407 super.setOrientation(orientation);
408 if (getControlPoint() != null) {
409 getControlPoint()._setWorldOrientation(getWorldOrientation());
411 PipingRules.requestUpdate(getControlPoint());
412 } catch (Exception e) {
413 // TODO Auto-generated catch block
420 public void setPosition(Vector3d position) {
421 if (MathTools.equals(position, getPosition()))
423 super.setPosition(position);
424 if (getControlPoint() != null) {
425 getControlPoint()._setWorldPosition(getWorldPosition());
427 PipingRules.requestUpdate(getControlPoint());
428 } catch (Exception e) {
429 // TODO Auto-generated catch block
436 public void _setWorldPosition(Vector3d position) {
437 Vector3d localPos = getLocalPosition(position);
438 super.setPosition(localPos);
441 public void _setWorldOrientation(Quat4d orientation) {
442 Quat4d localOr = getLocalOrientation(orientation);
443 super.setOrientation(localOr);
446 @GetPropertyValue(name="Flow Length", value="flowlength", tabId = "Default")
447 public Double getFlowLength() {
448 PipeControlPoint pcp = getControlPoint();
451 switch (pcp.getType()) {
453 return pcp.getLength();
457 double r = getPipeRun().getTurnRadius();
458 double a = pcp.getTurnAngle();
466 public void getEnds(Tuple3d p1, Tuple3d p2) {
467 getControlPoint().getControlPointEnds(p1, p2);