]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java
Handle variable length components on offset path leg
[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.Type;
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         /**
35          * Sets the pipe run.
36          * 
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.
40          * 
41          * @param pipeRun
42          */
43         public void setPipeRun(PipeRun pipeRun) {
44                 if (pipeRun == this.pipeRun)
45                         return;
46                 this.pipeRun = pipeRun;
47                 if (getControlPoint() != null) {
48                         getControlPoint().deattach();
49                         if (pipeRun != null) {
50                                 pipeRun.addChild(getControlPoint());
51                         }
52                 }
53                 updateParameters();
54         }
55         
56         @RelatedGetObj(Plant3D.URIs.HasAlternativePipeRun)
57         public PipeRun getAlternativePipeRun() {
58                 return alternativePipeRun;
59         }
60         
61         @RelatedSetObj(Plant3D.URIs.HasAlternativePipeRun)
62         public void setAlternativePipeRun(PipeRun pipeRun) {
63                 if (this.alternativePipeRun == pipeRun)
64                         return;
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);
70                 }
71                 firePropertyChanged(Plant3D.URIs.HasAlternativePipeRun);
72         }
73         
74         @Override
75         public void updateParameters() {
76                 setParameterMap(updateParameterMap());
77                 super.updateParameters();
78         }
79         
80         public abstract void setType(String typeURI) throws Exception;
81         
82         @RelatedGetObj(Plant3D.URIs.HasNext)
83         public PipelineComponent getNext() {
84                 return next;
85         }
86         
87         @RelatedSetObj(Plant3D.URIs.HasNext)
88         public void setNext(PipelineComponent comp) {
89                 if (next == comp)
90                         return;
91                 this.next = comp;
92                 syncNext();
93                 firePropertyChanged(Plant3D.URIs.HasNext);
94                 if (comp != null)
95                         comp.sync();
96 //              System.out.println(this + " next " + comp);
97         }
98         
99         
100         @RelatedGetObj(Plant3D.URIs.HasPrevious)
101         public PipelineComponent getPrevious() {
102                 return previous;
103         }
104         
105         @RelatedSetObj(Plant3D.URIs.HasPrevious)
106         public void setPrevious(PipelineComponent comp) {
107                 if (previous == comp)
108                         return;
109                 this.previous = comp;
110                 
111                 firePropertyChanged(Plant3D.URIs.HasPrevious);
112                 if (comp != null)
113                         comp.sync();
114 //              System.out.println(this + " prev " + comp);
115         }
116         private PipelineComponent branch0;
117         
118         @RelatedGetObj(Plant3D.URIs.HasBranch0)
119         public PipelineComponent getBranch0() {
120                 return branch0;
121         }
122         
123         @RelatedSetObj(Plant3D.URIs.HasBranch0)
124         public void setBranch0(PipelineComponent comp) {
125                 if (branch0 == comp)
126                         return;
127                 this.branch0 = comp;
128                 syncBranch0();
129                 firePropertyChanged(Plant3D.URIs.HasBranch0);
130                 if (comp != null)
131                         comp.sync();
132 //              System.out.println(this + " next " + comp);
133         }
134
135
136         
137         private PipeControlPoint getBranchPoint() {
138                 PipeControlPoint branchPoint;
139                 if (getControlPoint().getSubPoint().size() > 0) {
140                         branchPoint = getControlPoint().getSubPoint().get(0);
141                 } else {
142                         if (branch0.getPipeRun() == null)
143                                 return null;
144                         branchPoint = new PipeControlPoint(this,branch0.getPipeRun());
145                         branchPoint.setFixed(false);
146                         branchPoint.setType(Type.END);
147                         branchPoint.parent = getControlPoint();
148                         getControlPoint().children.add(branchPoint);
149                         branchPoint.setWorldOrientation(getControlPoint().getWorldOrientation());
150                         branchPoint.setWorldPosition(getControlPoint().getWorldPosition());
151                 }
152                 return branchPoint;
153         }
154         
155         private boolean _connectNext(PipeControlPoint pcp, PipeControlPoint nextPCP) {
156                 if (nextPCP == null)
157                         return false;
158                 if (pcp.getNext() != nextPCP) {
159                         pcp.setNext(nextPCP);
160                 }
161                 if (pcp.isDualInline()) {
162                         PipeControlPoint sub = pcp.getSubPoint().get(0);
163                         if (sub.getNext() != nextPCP)
164                                 sub.setNext(nextPCP);
165                 }
166                 return true;
167         }
168         
169         private boolean  _connectPrev(PipeControlPoint pcp, PipeControlPoint prevPCP) {
170                 if (prevPCP == null)
171                         return false;
172                 if (prevPCP.isDualInline())
173                         prevPCP = prevPCP.getSubPoint().get(0);
174                 if (pcp.getPrevious() != prevPCP) {
175                         pcp.setPrevious(prevPCP);
176                 }
177                 if (pcp.isDualInline()) {
178                         PipeControlPoint sub = pcp.getSubPoint().get(0);
179                         if (sub.getPrevious() != prevPCP)
180                                 sub.setPrevious(prevPCP);
181                 }
182                 return true;
183         }
184         
185         
186         
187         private boolean syncNext() {
188                 
189                 if (getControlPoint() != null) {
190                         if (next != null ) {
191                                 if (next.getControlPoint() != null && next.getPipeRun() != null) {
192                                         
193                                         // TODO, relying that the other direction is connected.
194                                         boolean nxt = next.getPrevious() == this;
195                                         boolean br0 = next.getBranch0() == this;
196                                         if (nxt){
197                                                 return _connectNext(getControlPoint(), next.getControlPoint()); 
198                                         } else if (br0) {
199                                                 return _connectNext(getControlPoint(), next.getBranchPoint());
200                                         }
201                                 } else {
202                                         return false;
203                                 }
204                                 
205                         } else if (getControlPoint().getPrevious() != null) {
206                                 getControlPoint().setNext(null);
207                         }
208                 } else {
209                         return false;
210                 }
211                 return true;
212         }
213         
214         private boolean syncPrevious() {
215
216                 if (getControlPoint() != null) {
217                         if (previous != null ) {
218                                 if (previous.getControlPoint() != null && previous.getPipeRun() != null) {
219                                         
220                                         // TODO, relying that the other direction is connected.
221                                         boolean prev = previous.getNext() == this;
222                                         boolean br0 = previous.getBranch0() == this;
223                                         if (prev){
224                                                 return _connectPrev(getControlPoint(), previous.getControlPoint());     
225                                         } else if (br0) {
226                                                 return _connectPrev(getControlPoint(), previous.getBranchPoint());
227                                         }
228                                 } else {
229                                         return false;
230                                 }
231                                 
232                         } else if (getControlPoint().getPrevious() != null) {
233                                 getControlPoint().setPrevious(null);
234                         }
235                 } else {
236                         return false;
237                 }
238                 return true;
239         }
240         
241         private boolean syncBranch0() {
242                 if (getControlPoint() != null) {
243                         if (getControlPoint().isDualInline()) {
244                                 branch0 = null;
245                                 return false;
246                         }
247                         if (branch0 != null) {
248                                 if (branch0.getControlPoint() != null  && branch0.getPipeRun() != null) {
249                                         PipeControlPoint branchPoint = getBranchPoint();
250                                         PipeControlPoint pcp = branch0.getControlPoint();
251                                         // TODO, relying that the other direction is connected.
252                                         boolean next = branch0.getPrevious() == this; // this --> branch0
253                                         boolean prev = branch0.getNext() == this;
254                                         if (next) {
255                                                 _connectNext(branchPoint, pcp);
256                                         } else if (prev){
257                                                 _connectPrev(branchPoint, pcp); 
258                                         }
259                                 } else {
260                                         return false;
261                                 }
262                                 
263                         } else if (getControlPoint().getSubPoint().size() > 0) { // TODO : this may cause problems? (Removes branch point, before branch has been set?)
264                                 getControlPoint().getSubPoint().get(0).remove();
265                                 getControlPoint().children.clear();
266                         }
267                 } else {
268                         return false;
269                 }
270                 return true;
271         }
272         
273         public void sync() {
274                 syncPrevious();
275                 syncNext();
276                 syncBranch0();
277         }
278         
279         public void sync2() {
280 //              if (getControlPoint().isDualInline()) {
281 //                      PipeControlPoint sub = getControlPoint().getSubPoint().get(0);
282 //                      next.getControlPoint().getPipeRun().addChild(sub);
283 //              }
284                 getControlPoint()._setWorldOrientation(getWorldOrientation());
285                 getControlPoint()._setWorldPosition(getWorldPosition());
286         }
287         
288         public Map<String,Object> updateParameterMap() {
289                 return Collections.EMPTY_MAP;
290         }
291         
292         public PipeRun getPipeRun() {
293                 return pipeRun;
294         }
295         
296         public abstract String getType();
297         public abstract PipeControlPoint getControlPoint();
298         
299         @Override
300         public void remove() {
301                 PipeControlPoint pcp = getControlPoint();
302                 // Second check is needed, when remove process is initiated from control point.
303                 if (pcp != null && pcp.getPipelineComponent() != null) {
304                         pcp.remove();
305                 }
306                 super.remove();
307         }
308
309         @Override
310         protected double[] getColor() {
311                 if (getControlPoint() == null || !getControlPoint().isFixed())
312                         return new double[]{0.7,0.7,0.7};
313                 else
314                         return new double[]{1.0,0.0,0.0};
315         }
316         
317         @Override
318         protected double[] getSelectedColor() {
319                 return new double[]{0.5,0,0.5};
320         }
321         
322         @Override
323         public void setOrientation(Quat4d orientation) {
324                 if (MathTools.equals(orientation, getOrientation()))
325                         return;
326                 super.setOrientation(orientation);
327                 if (getControlPoint() != null) {
328                         getControlPoint()._setWorldOrientation(getWorldOrientation());
329                         try {
330                                 PipingRules.requestUpdate(getControlPoint());
331                         } catch (Exception e) {
332                                 // TODO Auto-generated catch block
333                                 e.printStackTrace();
334                         }       
335                 }
336         }
337         
338         @Override
339         public void setPosition(Vector3d position) {
340                 if (MathTools.equals(position, getPosition()))
341                         return;
342                 super.setPosition(position);
343                 if (getControlPoint() != null) {
344                         getControlPoint()._setWorldPosition(getWorldPosition());
345                         try {
346                                 PipingRules.requestUpdate(getControlPoint());
347                         } catch (Exception e) {
348                                 // TODO Auto-generated catch block
349                                 e.printStackTrace();
350                         }
351                 }
352         }
353         
354         
355         public void _setWorldPosition(Vector3d position) {
356                 Vector3d localPos = getLocalPosition(position);
357                 super.setPosition(localPos);
358         }
359         
360         public void _setWorldOrientation(Quat4d orientation) {
361                 Quat4d localOr = getLocalOrientation(orientation);
362                 super.setOrientation(localOr);
363         }
364         
365         @GetPropertyValue(name="Flow Length", value="flowlength", tabId = "Default")
366         public Double getFlowLength() {
367                 PipeControlPoint pcp = getControlPoint(); 
368                 if (pcp == null)
369                         return null;
370                 switch (pcp.getType()) {
371                         case INLINE:
372                                 return pcp.getLength();
373                         case END:
374                                 return null;
375                         case TURN: {
376                                 double r = getPipeRun().getTurnRadius();
377                                 double a = pcp.getTurnAngle();
378                                 return a*r;
379                         }
380                          default:
381                                  return null;
382                 }
383         }
384         
385         public void getControlPointEnds(Tuple3d p1, Tuple3d p2) {
386                 getControlPoint().getControlPointEnds(p1, p2);
387         }
388         
389         public Vector3d getNormal() {
390                 Vector3d v = new Vector3d();
391                 MathTools.rotate(getWorldOrientation(), MathTools.Z_AXIS, v);
392                 return v;
393         }
394         
395 }