]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java
Additional SCL Bindings to G3D and Plant3D classes
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / scenegraph / PipelineComponent.java
1 package org.simantics.plant3d.scenegraph;
2
3 import java.util.Collections;
4 import java.util.Map;
5
6 import javax.vecmath.Quat4d;
7 import javax.vecmath.Tuple3d;
8 import javax.vecmath.Vector3d;
9
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.PointType;
18 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
19
20 /**
21  * 
22  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
23  *
24  */
25 @PropertyContributor
26 public abstract class PipelineComponent extends GeometryNode {
27
28         
29         private PipeRun pipeRun;
30         private PipeRun alternativePipeRun;
31         private PipelineComponent next;
32         private PipelineComponent previous;
33         
34         public PipeRun getPipeRun() {
35         return pipeRun;
36     }
37         
38         /**
39          * Sets the pipe run.
40          * 
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.
44          * 
45          * @param pipeRun
46          */
47         public void setPipeRun(PipeRun pipeRun) {
48                 if (pipeRun == this.pipeRun)
49                         return;
50                 this.pipeRun = pipeRun;
51                 if (getControlPoint() != null) {
52                         getControlPoint().deattach();
53                         if (pipeRun != null) {
54                                 pipeRun.addChild(getControlPoint());
55                         }
56                 }
57                 updateParameters();
58         }
59         
60         @RelatedGetObj(Plant3D.URIs.HasAlternativePipeRun)
61         public PipeRun getAlternativePipeRun() {
62                 return alternativePipeRun;
63         }
64         
65         @RelatedSetObj(Plant3D.URIs.HasAlternativePipeRun)
66         public void setAlternativePipeRun(PipeRun pipeRun) {
67                 if (this.alternativePipeRun == pipeRun)
68                         return;
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);
74                 }
75                 firePropertyChanged(Plant3D.URIs.HasAlternativePipeRun);
76         }
77         
78         @Override
79         public void updateParameters() {
80                 setParameterMap(updateParameterMap());
81                 super.updateParameters();
82         }
83         
84         public abstract void setType(String typeURI) throws Exception;
85         
86         @RelatedGetObj(Plant3D.URIs.HasNext)
87         public PipelineComponent getNext() {
88                 return next;
89         }
90         
91         @RelatedSetObj(Plant3D.URIs.HasNext)
92         public void setNext(PipelineComponent comp) {
93                 if (next == comp)
94                         return;
95                 if (this.next != null)
96                     this.next._removeRef(this);
97                 this.next = comp;
98                 this.syncnext = false;
99                 syncNext();
100                 firePropertyChanged(Plant3D.URIs.HasNext);
101                 if (comp != null)
102                         comp.sync();
103 //              System.out.println(this + " next " + comp);
104         }
105         
106         
107         @RelatedGetObj(Plant3D.URIs.HasPrevious)
108         public PipelineComponent getPrevious() {
109                 return previous;
110         }
111         
112         @RelatedSetObj(Plant3D.URIs.HasPrevious)
113         public void setPrevious(PipelineComponent comp) {
114                 if (previous == comp)
115                         return;
116                 if (this.previous != null)
117                     this.previous._removeRef(this);
118                 this.previous = comp;
119                 this.syncprev = false;
120                 syncPrevious();
121                 firePropertyChanged(Plant3D.URIs.HasPrevious);
122                 if (comp != null)
123                         comp.sync();
124 //              System.out.println(this + " prev " + comp);
125         }
126         private PipelineComponent branch0;
127         
128         @RelatedGetObj(Plant3D.URIs.HasBranch0)
129         public PipelineComponent getBranch0() {
130                 return branch0;
131         }
132         
133         @RelatedSetObj(Plant3D.URIs.HasBranch0)
134         public void setBranch0(PipelineComponent comp) {
135                 if (branch0 == comp)
136                         return;
137                 if (this.branch0 != null)
138                     this.branch0._removeRef(this);
139                 this.branch0 = comp;
140                 this.syncbr0 = false;
141                 syncBranch0();
142                 firePropertyChanged(Plant3D.URIs.HasBranch0);
143                 if (comp != null)
144                         comp.sync();
145 //              System.out.println(this + " next " + comp);
146         }
147
148         @GetPropertyValue(name="Previous",tabId="Debug",value=Plant3D.URIs.HasPrevious)
149     public String getPreviousDebug() {
150         if (previous == null)
151             return null;
152         return previous.getName();
153     }
154     
155     @GetPropertyValue(name="Next",tabId="Debug",value=Plant3D.URIs.HasNext)
156     public String getNextDebug() {
157         if (next == null)
158             return null;
159         return next.getName();
160     }
161     
162         @GetPropertyValue(name="Branch0",tabId="Debug",value=Plant3D.URIs.HasBranch0)
163     public String getBR0Debug() {
164         if (branch0 == null)
165             return null;
166         return branch0.getName();
167     }
168
169         
170         
171         private PipeControlPoint getBranchPoint() {
172                 PipeControlPoint branchPoint;
173                 if (getControlPoint().getSubPoint().size() > 0) {
174                         branchPoint = getControlPoint().getSubPoint().get(0);
175                 } else {
176                         if (branch0.getPipeRun() == null)
177                                 return null;
178                         branchPoint = new PipeControlPoint(this,branch0.getPipeRun());
179                         branchPoint.setFixed(false);
180                         branchPoint.setType(PointType.END);
181                         branchPoint.parent = getControlPoint();
182                         getControlPoint().children.add(branchPoint);
183                         branchPoint.setWorldOrientation(getControlPoint().getWorldOrientation());
184                         branchPoint.setWorldPosition(getControlPoint().getWorldPosition());
185                 }
186                 return branchPoint;
187         }
188         
189         private boolean _connectNext(PipeControlPoint pcp, PipeControlPoint nextPCP) {
190                 if (nextPCP == null)
191                         return false;
192                 if (pcp.getNext() != nextPCP) {
193                         pcp.setNext(nextPCP);
194                 }
195                 if (pcp.isDualInline()) {
196                         PipeControlPoint sub = pcp.getSubPoint().get(0);
197                         if (sub.getNext() != nextPCP)
198                                 sub.setNext(nextPCP);
199                 }
200                 return true;
201         }
202         
203         private boolean  _connectPrev(PipeControlPoint pcp, PipeControlPoint prevPCP) {
204                 if (prevPCP == null)
205                         return false;
206                 if (prevPCP.isDualInline())
207                         prevPCP = prevPCP.getSubPoint().get(0);
208                 if (pcp.getPrevious() != prevPCP) {
209                         pcp.setPrevious(prevPCP);
210                 }
211                 if (pcp.isDualInline()) {
212                         PipeControlPoint sub = pcp.getSubPoint().get(0);
213                         if (sub.getPrevious() != prevPCP)
214                                 sub.setPrevious(prevPCP);
215                 }
216                 return true;
217         }
218         
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) {
222             if (next == comp) {
223                 next = null;
224                 syncnext = false;
225             syncNext();
226             } else if (previous == comp) {
227                 previous = null;
228                 syncprev = false;
229             syncPrevious();
230             } else if (branch0 == comp) {
231                 branch0 = null;
232                 syncbr0 = false;
233                 syncBranch0();
234             }
235         }
236         
237         boolean syncnext = false;
238     private void syncNext() {
239         if (syncnext)
240             return;
241         syncnext = _syncNext();
242     }
243         
244         
245         private boolean _syncNext() {
246             PipeControlPoint pcp = getControlPoint();
247                 if (pcp != null) {
248                     
249                         if (next != null ) {
250                                 if (next.getControlPoint() != null) {
251                                         
252                                         // TODO, relying that the other direction is connected.
253                                         boolean nxt = next.getPrevious() == this;
254                                         boolean br0 = next.getBranch0() == this;
255                                         if (nxt){
256                                                 return _connectNext(pcp, next.getControlPoint());       
257                                         } else if (br0) {
258                                                 return _connectNext(pcp, next.getBranchPoint());
259                                         } else {
260                                             return false;
261                                         }
262                                 } else {
263                                         return false;
264                                 }
265                                 
266                         } else if (pcp.getNext() != null) {
267                             pcp.setNext(null);
268                             return true;
269                         }
270                 } else {
271                         return false;
272                 }
273                 return true;
274         }
275         
276         boolean syncprev = false;
277     private void syncPrevious() {
278         if (syncprev)
279             return;
280         syncprev = _syncPrevious();
281     }
282         
283         private boolean _syncPrevious() {
284             PipeControlPoint pcp = getControlPoint();
285                 if (pcp != null) {
286                         if (previous != null ) {
287                                 if (previous.getControlPoint() != null) {
288                                         
289                                         // TODO, relying that the other direction is connected.
290                                         boolean prev = previous.getNext() == this;
291                                         boolean br0 = previous.getBranch0() == this;
292                                         if (prev){
293                                                 return _connectPrev(pcp, previous.getControlPoint());   
294                                         } else if (br0) {
295                                                 return _connectPrev(pcp, previous.getBranchPoint());
296                                         } else {
297                                             return false;
298                                         }
299                                 } else {
300                                         return false;
301                                 }
302                                 
303                         } else if (pcp.getPrevious() != null) {
304                             pcp.setPrevious(null);
305                             return true;
306                         }
307                 } else {
308                         return false;
309                 }
310                 return true;
311         }
312         
313         boolean syncbr0 = false;
314         private void syncBranch0() {
315             if (syncbr0)
316                 return;
317             syncbr0 = _syncBranch0();
318         }
319         
320         private boolean _syncBranch0() {
321                 if (getControlPoint() != null) {
322                         if (getControlPoint().isDualInline()) {
323                                 branch0 = null;
324                                 return false;
325                         }
326                         if (branch0 != null) {
327                                 if (branch0.getControlPoint() != null) {
328                                         PipeControlPoint branchPoint = getBranchPoint();
329                                         if (branchPoint == null)
330                                             return false;
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;
335                                         if (next) {
336                                                 _connectNext(branchPoint, pcp);
337                                         } else if (prev){
338                                                 _connectPrev(branchPoint, pcp); 
339                                         } else {
340                                             return false;
341                                         }
342                                         
343                                 } else {
344                                         return false;
345                                 }
346                                 
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();
350                                 return true;
351                         }
352                 } else {
353                         return false;
354                 }
355                 return true;
356         }
357         
358         public void sync() {
359                 syncPrevious();
360                 syncNext();
361                 syncBranch0();
362         }
363         
364         public void sync2() {
365 //              if (getControlPoint().isDualInline()) {
366 //                      PipeControlPoint sub = getControlPoint().getSubPoint().get(0);
367 //                      next.getControlPoint().getPipeRun().addChild(sub);
368 //              }
369                 getControlPoint()._setWorldOrientation(getWorldOrientation());
370                 getControlPoint()._setWorldPosition(getWorldPosition());
371         }
372         
373         public Map<String,Object> updateParameterMap() {
374                 return Collections.EMPTY_MAP;
375         }
376         
377         public abstract String getType();
378         public abstract PipeControlPoint getControlPoint();
379         
380         @Override
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) {
385                         pcp.remove();
386                 }
387                 super.remove();
388         }
389
390         @Override
391         protected double[] getColor() {
392                 if (getControlPoint() == null || !getControlPoint().isFixed())
393                         return new double[]{0.7,0.7,0.7};
394                 else
395                         return new double[]{1.0,0.0,0.0};
396         }
397         
398         @Override
399         protected double[] getSelectedColor() {
400                 return new double[]{0.5,0,0.5};
401         }
402         
403         @Override
404         public void setOrientation(Quat4d orientation) {
405                 if (MathTools.equals(orientation, getOrientation()))
406                         return;
407                 super.setOrientation(orientation);
408                 if (getControlPoint() != null) {
409                         getControlPoint()._setWorldOrientation(getWorldOrientation());
410                         try {
411                                 PipingRules.requestUpdate(getControlPoint());
412                         } catch (Exception e) {
413                                 // TODO Auto-generated catch block
414                                 e.printStackTrace();
415                         }       
416                 }
417         }
418         
419         @Override
420         public void setPosition(Vector3d position) {
421                 if (MathTools.equals(position, getPosition()))
422                         return;
423                 super.setPosition(position);
424                 if (getControlPoint() != null) {
425                         getControlPoint()._setWorldPosition(getWorldPosition());
426                         try {
427                                 PipingRules.requestUpdate(getControlPoint());
428                         } catch (Exception e) {
429                                 // TODO Auto-generated catch block
430                                 e.printStackTrace();
431                         }
432                 }
433         }
434         
435         
436         public void _setWorldPosition(Vector3d position) {
437                 Vector3d localPos = getLocalPosition(position);
438                 super.setPosition(localPos);
439         }
440         
441         public void _setWorldOrientation(Quat4d orientation) {
442                 Quat4d localOr = getLocalOrientation(orientation);
443                 super.setOrientation(localOr);
444         }
445         
446         @GetPropertyValue(name="Flow Length", value="flowlength", tabId = "Default")
447         public Double getFlowLength() {
448                 PipeControlPoint pcp = getControlPoint(); 
449                 if (pcp == null)
450                         return null;
451                 switch (pcp.getType()) {
452                         case INLINE:
453                                 return pcp.getLength();
454                         case END:
455                                 return null;
456                         case TURN: {
457                                 double r = getPipeRun().getTurnRadius();
458                                 double a = pcp.getTurnAngle();
459                                 return a*r;
460                         }
461                          default:
462                                  return null;
463                 }
464         }
465         
466         public void getEnds(Tuple3d p1, Tuple3d p2) {
467                 getControlPoint().getControlPointEnds(p1, p2);
468         }
469         
470 }