]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java
Add a wall thickness property to pipe runs.
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / scenegraph / PipeRun.java
1 package org.simantics.plant3d.scenegraph;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collection;
6 import java.util.Collections;
7 import java.util.Comparator;
8 import java.util.HashMap;
9 import java.util.List;
10 import java.util.Map;
11
12 import org.simantics.g3d.math.MathTools;
13 import org.simantics.g3d.property.annotations.GetPropertyValue;
14 import org.simantics.g3d.property.annotations.PropertyTabBlacklist;
15 import org.simantics.g3d.property.annotations.SetPropertyValue;
16 import org.simantics.g3d.scenegraph.IG3DNode;
17 import org.simantics.g3d.vtk.common.VtkView;
18 import org.simantics.objmap.graph.annotations.GraphType;
19 import org.simantics.objmap.graph.annotations.RelatedElementsAdd;
20 import org.simantics.objmap.graph.annotations.RelatedElementsGet;
21 import org.simantics.objmap.graph.annotations.RelatedElementsRem;
22 import org.simantics.objmap.graph.annotations.RelatedGetValue;
23 import org.simantics.objmap.graph.annotations.RelatedSetValue;
24 import org.simantics.plant3d.ontology.Plant3D;
25 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
26
27 import vtk.vtkProp3D;
28 import vtk.vtkRenderer;
29
30 @GraphType(Plant3D.URIs.PipeRun)
31 @PropertyTabBlacklist("Transform")
32 public class PipeRun extends P3DParentNode<IP3DNode> {
33         
34         private double pipeDiameter = 0.1;
35         private double pipeThickness = 0.0;
36         private double[] turnRadius = new double[] {0.2};
37         
38         @Override
39         public void update(vtkRenderer ren) {
40                 
41         }
42         
43         @Override
44         public void visualize(VtkView panel) {
45                 
46         }
47         
48         @Override
49         public Collection<vtkProp3D> getActors() {
50                 return Collections.emptyList();
51         }
52         
53         @Override
54         public void stopVisualize() {
55                 
56         }
57         
58         @SuppressWarnings("deprecation")
59         @RelatedGetValue(Plant3D.URIs.HasTurnRadius)
60         @GetPropertyValue(value=Plant3D.URIs.HasTurnRadius, name = "Elbow radius")
61         public double getTurnRadius() {
62                 return turnRadius[0];
63         }
64         
65         @SuppressWarnings("deprecation")
66         @RelatedSetValue(Plant3D.URIs.HasTurnRadius)
67         @SetPropertyValue(Plant3D.URIs.HasTurnRadius)
68         public void setTurnRadius(double turnRadius) {
69                 if (this.turnRadius[0] == turnRadius)
70                         return;
71                 this.turnRadius[0] = turnRadius;
72                 firePropertyChanged(Plant3D.URIs.HasTurnRadius);
73                 firePropertyChanged(Plant3D.URIs.HasTurnRadiusArray);
74         }
75         
76         @RelatedGetValue(Plant3D.URIs.HasTurnRadiusArray)
77     @GetPropertyValue(value=Plant3D.URIs.HasTurnRadiusArray, name = "Elbow radius array")
78     public double[] getTurnRadiusArray() {
79         return turnRadius;
80     }
81     
82     @RelatedSetValue(Plant3D.URIs.HasTurnRadiusArray)
83     @SetPropertyValue(Plant3D.URIs.HasTurnRadiusArray)
84     public void setTurnRadiusArray(double[] turnRadiusArray) {
85         if (turnRadiusArray == null || turnRadiusArray.length == 0 || Arrays.equals(this.turnRadius, turnRadiusArray))
86             return;
87         this.turnRadius = turnRadiusArray;
88         firePropertyChanged(Plant3D.URIs.HasTurnRadiusArray);
89     }
90         
91         @RelatedGetValue(Plant3D.URIs.HasPipeDiameter)
92         @GetPropertyValue(value=Plant3D.URIs.HasPipeDiameter, name = "Diameter")
93         public double getPipeDiameter() {
94                 return pipeDiameter;
95         }
96         
97         @RelatedSetValue(Plant3D.URIs.HasPipeDiameter)
98         @SetPropertyValue(Plant3D.URIs.HasPipeDiameter)
99         public void setPipeDiameter(double pipeDiameter) {
100                 if (this.pipeDiameter == pipeDiameter)
101                         return;
102                 
103                 this.pipeDiameter = pipeDiameter;
104                 firePropertyChanged(Plant3D.URIs.HasPipeDiameter);
105         }
106         
107         @RelatedGetValue(Plant3D.URIs.HasPipeThickness)
108         @GetPropertyValue(value=Plant3D.URIs.HasPipeThickness, name = "Wall Thickness")
109         public double getPipeThickness() {
110                 return pipeThickness;
111         }
112         
113         @RelatedSetValue(Plant3D.URIs.HasPipeThickness)
114         @SetPropertyValue(Plant3D.URIs.HasPipeThickness)
115         public void setPipeThickness(double pipeThickness) {
116                 if (this.pipeThickness == pipeThickness)
117                         return;
118                 
119                 this.pipeThickness = pipeThickness;
120                 firePropertyChanged(Plant3D.URIs.HasPipeThickness);
121         }
122         
123         @RelatedElementsAdd(Plant3D.URIs.children)
124         public void addChild(PipelineComponent node) {
125                 addNode(Plant3D.URIs.children,node);
126         }
127         
128         @RelatedElementsGet(Plant3D.URIs.children)
129         public Collection<PipelineComponent> getChild() {
130                 Collection<PipelineComponent> coll = new ArrayList<PipelineComponent>();
131                 for (IG3DNode n : getNodes(Plant3D.URIs.children)) {
132                         coll.add((PipelineComponent)n);
133                 }
134                 return coll;
135         }
136         
137         @RelatedElementsRem(Plant3D.URIs.children)
138         public void _remChild(PipelineComponent node) {
139                 //since we do not now, if DB remove is actually remove or detach, we have to use detach. NodeMap will handle Component removals.
140             deattachNode(Plant3D.URIs.children, node);
141         }
142         
143         public void remChild(PipelineComponent node) {
144             removeNode(Plant3D.URIs.children, node);
145         }
146         
147         @Override
148         public void remove() {
149             // since we do not now, if DB remove is actually remove or detach, we have to use detach. NodeMap will handle Component removals.
150             Collection<PipelineComponent> comps = getChild();
151             for (PipelineComponent c : comps)
152                 c.deattach();
153             super.remove();
154         }
155
156         
157         public List<PipelineComponent> getSortedChild() {
158                 List<PipelineComponent> coll = new ArrayList<PipelineComponent>();
159                 for (IG3DNode n : getNodes(Plant3D.URIs.children)) {
160                         coll.add((PipelineComponent)n);
161                 }
162                 Collections.sort(coll, new ComponentComparator());
163                 return coll;
164         }
165         private static String PIPECP = "pipecp";
166         
167         public void addChild(PipeControlPoint node) {
168                 addNode(PIPECP,node);
169         }
170         
171         public void remChild(PipeControlPoint node) {
172                 removeNode(PIPECP, node);
173         }
174         
175         public void deattachChild(PipeControlPoint node) {
176                 deattachNode(PIPECP, node);
177         }
178         
179         public Collection<PipeControlPoint> getControlPoints() {
180                 Collection<PipeControlPoint> coll = new ArrayList<PipeControlPoint>();
181                 for (IG3DNode n : getNodes(PIPECP)) {
182                         coll.add((PipeControlPoint)n);
183                 }
184                 return coll;
185         }
186         
187         
188         public boolean equalSpecs(PipeRun other) {
189                 if (!MathTools.equals(pipeDiameter,other.pipeDiameter))
190                         return false;
191                 if (turnRadius.length != other.turnRadius.length)
192                     return false;
193                 for (int i = 0; i < turnRadius.length; i++) {
194                     if (!MathTools.equals(turnRadius[i],other.turnRadius[i]))
195                         return false;
196                 }
197                 return true;
198         }
199         
200         public boolean canMerge(PipeRun other) {
201             return MathTools.equals(pipeDiameter,other.pipeDiameter);
202         }
203         
204         /**
205          * Merges contents of PipeRun r2 to this PipeRun. Note: does not connect boundary components!
206          * @param r2
207          */
208         public void merge(PipeRun r2) {
209         Map<Integer, Integer> turnIndexMap = null;
210         if (!this.equalSpecs(r2)) {
211             if (!this.canMerge(r2))
212                 throw new IllegalArgumentException("PipeRuns cannot be merged");
213             // Merge turn radii.
214             turnIndexMap = new HashMap<>();
215             List<Double> mergedTurnRadius = new ArrayList<>();
216             for (double t : this.getTurnRadiusArray()) {
217                 mergedTurnRadius.add(t);
218             }
219             for (int i2 = 0; i2 < r2.getTurnRadiusArray().length; i2++) {
220                 double t2 = r2.getTurnRadiusArray()[i2];
221                 boolean found = false;
222                 for (int i = 0; i < mergedTurnRadius.size(); i++) {
223                     if (MathTools.equals(mergedTurnRadius.get(i), t2)) {
224                         turnIndexMap.put(i2, i);
225                         found = true;
226                         break;
227                     }
228                 }
229                 if (!found) {
230                     turnIndexMap.put(i2, mergedTurnRadius.size());
231                     mergedTurnRadius.add(t2);
232                 }
233             }
234             for (PipeControlPoint pcp : r2.getControlPoints()) {
235                 PipelineComponent comp = pcp.getPipelineComponent();
236                 if (comp instanceof TurnComponent) {
237                     
238                 }
239             }
240             if (mergedTurnRadius.size() > this.getTurnRadiusArray().length) {
241                 double arr[] = new double[mergedTurnRadius.size()];
242                 for (int i = 0; i < mergedTurnRadius.size(); i++) {
243                     arr[i] = mergedTurnRadius.get(i);
244                 }
245                 this.setTurnRadiusArray(arr);
246             }
247         }
248         // Move components and control points
249         Collection<PipeControlPoint> pcps = r2.getControlPoints();
250         for (PipeControlPoint pcp : pcps) {
251             r2.deattachChild(pcp);
252             this.addChild(pcp);
253             PipelineComponent component = pcp.getPipelineComponent();
254             if (component != null) {
255                 if (!(component instanceof Nozzle)) {
256                     component.deattach();
257                     this.addChild(component);
258                 } else {
259                     Nozzle n = (Nozzle)component;
260                     n.setPipeRun(this);
261                 }
262             }
263         }
264         // Use new turn radii indexes 
265         if (turnIndexMap != null) {
266             for (PipeControlPoint pcp : pcps) {
267                 PipelineComponent component = pcp.getPipelineComponent();
268                 if (component instanceof TurnComponent) {
269                     TurnComponent tc = (TurnComponent)component;
270                     if (tc.getTurnRadiusIndex() == null || tc.getTurnRadiusIndex() < 0)
271                         continue;
272                     tc.setTurnRadiusIndex(turnIndexMap.get(tc.getTurnRadiusIndex()));
273                 }
274             }
275         }
276         r2.remove();
277         
278     }
279         
280         private class ComponentComparator implements Comparator<PipelineComponent> {
281                 @Override
282                 public int compare(PipelineComponent o1, PipelineComponent o2) {
283                         if (o1 == o2)
284                                 return 0;
285                         int i = 1;
286                         PipelineComponent c = o1.getPrevious();
287                         while (c != null) {
288                                 if (c == o2)
289                                         return i;
290                                 c = c.getPrevious();
291                                 i++;
292                         }
293                         i = -1;
294                         c = o1.getNext();
295                         while (c != null) {
296                                 if (c == o2)
297                                         return i;
298                                 c = c.getNext();
299                                 i--;
300                         }
301                         return 0;
302                         
303                 }
304         }
305         
306 }