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