]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java
Use inside diameter for eccentric reducer offset calculation
[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         public double getInsideDiameter() {
124                 return pipeDiameter - 2 * pipeThickness;
125         }
126         
127         @RelatedElementsAdd(Plant3D.URIs.children)
128         public void addChild(PipelineComponent node) {
129                 addNode(Plant3D.URIs.children,node);
130         }
131         
132         @RelatedElementsGet(Plant3D.URIs.children)
133         public Collection<PipelineComponent> getChild() {
134                 Collection<PipelineComponent> coll = new ArrayList<PipelineComponent>();
135                 for (IG3DNode n : getNodes(Plant3D.URIs.children)) {
136                         coll.add((PipelineComponent)n);
137                 }
138                 return coll;
139         }
140         
141         @RelatedElementsRem(Plant3D.URIs.children)
142         public void _remChild(PipelineComponent node) {
143                 //since we do not now, if DB remove is actually remove or detach, we have to use detach. NodeMap will handle Component removals.
144             deattachNode(Plant3D.URIs.children, node);
145         }
146         
147         public void remChild(PipelineComponent node) {
148             removeNode(Plant3D.URIs.children, node);
149         }
150         
151         @Override
152         public void remove() {
153             // since we do not now, if DB remove is actually remove or detach, we have to use detach. NodeMap will handle Component removals.
154             Collection<PipelineComponent> comps = getChild();
155             for (PipelineComponent c : comps)
156                 c.deattach();
157             super.remove();
158         }
159
160         
161         public List<PipelineComponent> getSortedChild() {
162                 List<PipelineComponent> coll = new ArrayList<PipelineComponent>();
163                 for (IG3DNode n : getNodes(Plant3D.URIs.children)) {
164                         coll.add((PipelineComponent)n);
165                 }
166                 Collections.sort(coll, new ComponentComparator());
167                 return coll;
168         }
169         private static String PIPECP = "pipecp";
170         
171         public void addChild(PipeControlPoint node) {
172                 addNode(PIPECP,node);
173         }
174         
175         public void remChild(PipeControlPoint node) {
176                 removeNode(PIPECP, node);
177         }
178         
179         public void deattachChild(PipeControlPoint node) {
180                 deattachNode(PIPECP, node);
181         }
182         
183         public Collection<PipeControlPoint> getControlPoints() {
184                 Collection<PipeControlPoint> coll = new ArrayList<PipeControlPoint>();
185                 for (IG3DNode n : getNodes(PIPECP)) {
186                         coll.add((PipeControlPoint)n);
187                 }
188                 return coll;
189         }
190         
191         
192         public boolean equalSpecs(PipeRun other) {
193                 if (!MathTools.equals(pipeDiameter,other.pipeDiameter))
194                         return false;
195                 if (turnRadius.length != other.turnRadius.length)
196                     return false;
197                 for (int i = 0; i < turnRadius.length; i++) {
198                     if (!MathTools.equals(turnRadius[i],other.turnRadius[i]))
199                         return false;
200                 }
201                 return true;
202         }
203         
204         public boolean canMerge(PipeRun other) {
205             return MathTools.equals(pipeDiameter,other.pipeDiameter);
206         }
207         
208         /**
209          * Merges contents of PipeRun r2 to this PipeRun. Note: does not connect boundary components!
210          * @param r2
211          */
212         public void merge(PipeRun r2) {
213         Map<Integer, Integer> turnIndexMap = null;
214         if (!this.equalSpecs(r2)) {
215             if (!this.canMerge(r2))
216                 throw new IllegalArgumentException("PipeRuns cannot be merged");
217             // Merge turn radii.
218             turnIndexMap = new HashMap<>();
219             List<Double> mergedTurnRadius = new ArrayList<>();
220             for (double t : this.getTurnRadiusArray()) {
221                 mergedTurnRadius.add(t);
222             }
223             for (int i2 = 0; i2 < r2.getTurnRadiusArray().length; i2++) {
224                 double t2 = r2.getTurnRadiusArray()[i2];
225                 boolean found = false;
226                 for (int i = 0; i < mergedTurnRadius.size(); i++) {
227                     if (MathTools.equals(mergedTurnRadius.get(i), t2)) {
228                         turnIndexMap.put(i2, i);
229                         found = true;
230                         break;
231                     }
232                 }
233                 if (!found) {
234                     turnIndexMap.put(i2, mergedTurnRadius.size());
235                     mergedTurnRadius.add(t2);
236                 }
237             }
238             for (PipeControlPoint pcp : r2.getControlPoints()) {
239                 PipelineComponent comp = pcp.getPipelineComponent();
240                 if (comp instanceof TurnComponent) {
241                     
242                 }
243             }
244             if (mergedTurnRadius.size() > this.getTurnRadiusArray().length) {
245                 double arr[] = new double[mergedTurnRadius.size()];
246                 for (int i = 0; i < mergedTurnRadius.size(); i++) {
247                     arr[i] = mergedTurnRadius.get(i);
248                 }
249                 this.setTurnRadiusArray(arr);
250             }
251         }
252         // Move components and control points
253         Collection<PipeControlPoint> pcps = r2.getControlPoints();
254         for (PipeControlPoint pcp : pcps) {
255             r2.deattachChild(pcp);
256             this.addChild(pcp);
257             PipelineComponent component = pcp.getPipelineComponent();
258             if (component != null) {
259                 if (!(component instanceof Nozzle)) {
260                     component.deattach();
261                     this.addChild(component);
262                 } else {
263                     Nozzle n = (Nozzle)component;
264                     n.setPipeRun(this);
265                 }
266             }
267         }
268         // Use new turn radii indexes 
269         if (turnIndexMap != null) {
270             for (PipeControlPoint pcp : pcps) {
271                 PipelineComponent component = pcp.getPipelineComponent();
272                 if (component instanceof TurnComponent) {
273                     TurnComponent tc = (TurnComponent)component;
274                     if (tc.getTurnRadiusIndex() == null || tc.getTurnRadiusIndex() < 0)
275                         continue;
276                     tc.setTurnRadiusIndex(turnIndexMap.get(tc.getTurnRadiusIndex()));
277                 }
278             }
279         }
280         r2.remove();
281         
282     }
283         
284         private class ComponentComparator implements Comparator<PipelineComponent> {
285                 @Override
286                 public int compare(PipelineComponent o1, PipelineComponent o2) {
287                         if (o1 == o2)
288                                 return 0;
289                         int i = 1;
290                         PipelineComponent c = o1.getPrevious();
291                         while (c != null) {
292                                 if (c == o2)
293                                         return i;
294                                 c = c.getPrevious();
295                                 i++;
296                         }
297                         i = -1;
298                         c = o1.getNext();
299                         while (c != null) {
300                                 if (c == o2)
301                                         return i;
302                                 c = c.getNext();
303                                 i--;
304                         }
305                         return 0;
306                         
307                 }
308         }
309         
310 }