]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java
86f649aa136e49b6d0f7ac00cf956fb7de9e4392
[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 import java.util.Objects;
12
13 import org.simantics.g3d.math.MathTools;
14 import org.simantics.g3d.property.annotations.GetPropertyValue;
15 import org.simantics.g3d.property.annotations.PropertyTabBlacklist;
16 import org.simantics.g3d.property.annotations.SetPropertyValue;
17 import org.simantics.g3d.scenegraph.IG3DNode;
18 import org.simantics.g3d.vtk.common.VtkView;
19 import org.simantics.objmap.graph.annotations.GraphType;
20 import org.simantics.objmap.graph.annotations.RelatedElementsAdd;
21 import org.simantics.objmap.graph.annotations.RelatedElementsGet;
22 import org.simantics.objmap.graph.annotations.RelatedElementsRem;
23 import org.simantics.objmap.graph.annotations.RelatedGetValue;
24 import org.simantics.objmap.graph.annotations.RelatedSetValue;
25 import org.simantics.plant3d.ontology.Plant3D;
26 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
27
28 import vtk.vtkProp3D;
29 import vtk.vtkRenderer;
30
31 @GraphType(Plant3D.URIs.PipeRun)
32 @PropertyTabBlacklist("Transform")
33 public class PipeRun extends P3DParentNode<IP3DNode> {
34         
35         private double pipeDiameter = 0.1;
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 (Objects.equals(this.pipeDiameter, pipeDiameter))
101                         return;
102                 
103                 this.pipeDiameter = pipeDiameter;
104                 firePropertyChanged(Plant3D.URIs.HasPipeDiameter);
105         }
106         
107         @RelatedElementsAdd(Plant3D.URIs.children)
108         public void addChild(PipelineComponent node) {
109                 addNode(Plant3D.URIs.children,node);
110         }
111         
112         @RelatedElementsGet(Plant3D.URIs.children)
113         public Collection<PipelineComponent> getChild() {
114                 Collection<PipelineComponent> coll = new ArrayList<PipelineComponent>();
115                 for (IG3DNode n : getNodes(Plant3D.URIs.children)) {
116                         coll.add((PipelineComponent)n);
117                 }
118                 return coll;
119         }
120         
121         @RelatedElementsRem(Plant3D.URIs.children)
122         public void _remChild(PipelineComponent node) {
123                 //since we do not now, if DB remove is actually remove or detach, we have to use detach. NodeMap will handle Component removals.
124             deattachNode(Plant3D.URIs.children, node);
125         }
126         
127         public void remChild(PipelineComponent node) {
128             removeNode(Plant3D.URIs.children, node);
129         }
130         
131         @Override
132         public void remove() {
133             // since we do not now, if DB remove is actually remove or detach, we have to use detach. NodeMap will handle Component removals.
134             Collection<PipelineComponent> comps = getChild();
135             for (PipelineComponent c : comps)
136                 c.deattach();
137             super.remove();
138         }
139
140         
141         public List<PipelineComponent> getSortedChild() {
142                 List<PipelineComponent> coll = new ArrayList<PipelineComponent>();
143                 for (IG3DNode n : getNodes(Plant3D.URIs.children)) {
144                         coll.add((PipelineComponent)n);
145                 }
146                 Collections.sort(coll, new ComponentComparator());
147                 return coll;
148         }
149         private static String PIPECP = "pipecp";
150         
151         public void addChild(PipeControlPoint node) {
152                 addNode(PIPECP,node);
153         }
154         
155         public void remChild(PipeControlPoint node) {
156                 removeNode(PIPECP, node);
157         }
158         
159         public void deattachChild(PipeControlPoint node) {
160                 deattachNode(PIPECP, node);
161         }
162         
163         public Collection<PipeControlPoint> getControlPoints() {
164                 Collection<PipeControlPoint> coll = new ArrayList<PipeControlPoint>();
165                 for (IG3DNode n : getNodes(PIPECP)) {
166                         coll.add((PipeControlPoint)n);
167                 }
168                 return coll;
169         }
170         
171         
172         public boolean equalSpecs(PipeRun other) {
173                 if (!MathTools.equals(pipeDiameter,other.pipeDiameter))
174                         return false;
175                 if (turnRadius.length != other.turnRadius.length)
176                     return false;
177                 for (int i = 0; i < turnRadius.length; i++) {
178                     if (!MathTools.equals(turnRadius[i],other.turnRadius[i]))
179                         return false;
180                 }
181                 return true;
182         }
183         
184         public boolean canMerge(PipeRun other) {
185             return MathTools.equals(pipeDiameter,other.pipeDiameter);
186         }
187         
188         /**
189          * Merges contents of PipeRun r2 to this PipeRun. Note: does not connect boundary components!
190          * @param r2
191          */
192         public void merge(PipeRun r2) {
193         Map<Integer, Integer> turnIndexMap = null;
194         if (!this.equalSpecs(r2)) {
195             if (!this.canMerge(r2))
196                 throw new IllegalArgumentException("PipeRuns cannot be merged");
197             // Merge turn radii.
198             turnIndexMap = new HashMap<>();
199             List<Double> mergedTurnRadius = new ArrayList<>();
200             for (double t : this.getTurnRadiusArray()) {
201                 mergedTurnRadius.add(t);
202             }
203             for (int i2 = 0; i2 < r2.getTurnRadiusArray().length; i2++) {
204                 double t2 = r2.getTurnRadiusArray()[i2];
205                 boolean found = false;
206                 for (int i = 0; i < mergedTurnRadius.size(); i++) {
207                     if (MathTools.equals(mergedTurnRadius.get(i), t2)) {
208                         turnIndexMap.put(i2, i);
209                         found = true;
210                         break;
211                     }
212                 }
213                 if (!found) {
214                     turnIndexMap.put(i2, mergedTurnRadius.size());
215                     mergedTurnRadius.add(t2);
216                 }
217             }
218             for (PipeControlPoint pcp : r2.getControlPoints()) {
219                 PipelineComponent comp = pcp.getPipelineComponent();
220                 if (comp instanceof TurnComponent) {
221                     
222                 }
223             }
224             if (mergedTurnRadius.size() > this.getTurnRadiusArray().length) {
225                 double arr[] = new double[mergedTurnRadius.size()];
226                 for (int i = 0; i < mergedTurnRadius.size(); i++) {
227                     arr[i] = mergedTurnRadius.get(i);
228                 }
229                 this.setTurnRadiusArray(arr);
230             }
231         }
232         // Move components and control points
233         Collection<PipeControlPoint> pcps = r2.getControlPoints();
234         for (PipeControlPoint pcp : pcps) {
235             r2.deattachChild(pcp);
236             this.addChild(pcp);
237             PipelineComponent component = pcp.getPipelineComponent();
238             if (component != null) {
239                 if (!(component instanceof Nozzle)) {
240                     component.deattach();
241                     this.addChild(component);
242                 } else {
243                     Nozzle n = (Nozzle)component;
244                     n.setPipeRun(this);
245                 }
246             }
247         }
248         // Use new turn radii indexes 
249         if (turnIndexMap != null) {
250             for (PipeControlPoint pcp : pcps) {
251                 PipelineComponent component = pcp.getPipelineComponent();
252                 if (component instanceof TurnComponent) {
253                     TurnComponent tc = (TurnComponent)component;
254                     if (tc.getTurnRadiusIndex() == null || tc.getTurnRadiusIndex() < 0)
255                         continue;
256                     tc.setTurnRadiusIndex(turnIndexMap.get(tc.getTurnRadiusIndex()));
257                 }
258             }
259         }
260         r2.remove();
261         
262     }
263         
264         private class ComponentComparator implements Comparator<PipelineComponent> {
265                 @Override
266                 public int compare(PipelineComponent o1, PipelineComponent o2) {
267                         if (o1 == o2)
268                                 return 0;
269                         int i = 1;
270                         PipelineComponent c = o1.getPrevious();
271                         while (c != null) {
272                                 if (c == o2)
273                                         return i;
274                                 c = c.getPrevious();
275                                 i++;
276                         }
277                         i = -1;
278                         c = o1.getNext();
279                         while (c != null) {
280                                 if (c == o2)
281                                         return i;
282                                 c = c.getNext();
283                                 i--;
284                         }
285                         return 0;
286                         
287                 }
288         }
289         
290 }