]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java
Allow PipeRun merges when diameters are the same
[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                 removeNode(Plant3D.URIs.children, node);
117         }
118
119         
120         public List<PipelineComponent> getSortedChild() {
121                 List<PipelineComponent> coll = new ArrayList<PipelineComponent>();
122                 for (IG3DNode n : getNodes(Plant3D.URIs.children)) {
123                         coll.add((PipelineComponent)n);
124                 }
125                 Collections.sort(coll, new ComponentComparator());
126                 return coll;
127         }
128         private static String PIPECP = "pipecp";
129         
130         public void addChild(PipeControlPoint node) {
131                 addNode(PIPECP,node);
132         }
133         
134         public void remChild(PipeControlPoint node) {
135                 removeNode(PIPECP, node);
136         }
137         
138         public void deattachChild(PipeControlPoint node) {
139                 deattachNode(PIPECP, node);
140         }
141         
142         public Collection<PipeControlPoint> getControlPoints() {
143                 Collection<PipeControlPoint> coll = new ArrayList<PipeControlPoint>();
144                 for (IG3DNode n : getNodes(PIPECP)) {
145                         coll.add((PipeControlPoint)n);
146                 }
147                 return coll;
148         }
149         
150         
151         public boolean equalSpecs(PipeRun other) {
152                 if (!MathTools.equals(pipeDiameter,other.pipeDiameter))
153                         return false;
154                 if (turnRadius.length != other.turnRadius.length)
155                     return false;
156                 for (int i = 0; i < turnRadius.length; i++) {
157                     if (!MathTools.equals(turnRadius[i],other.turnRadius[i]))
158                         return false;
159                 }
160                 return true;
161         }
162         
163         public boolean canMerge(PipeRun other) {
164             return MathTools.equals(pipeDiameter,other.pipeDiameter);
165         }
166         
167         /**
168          * Merges contents of PipeRun r2 to this PipeRun. Note: does not connect boundary components!
169          * @param r2
170          */
171         public void merge(PipeRun r2) {
172         Map<Integer, Integer> turnIndexMap = null;
173         if (!this.equalSpecs(r2)) {
174             if (!this.canMerge(r2))
175                 throw new IllegalArgumentException("PipeRuns cannot be merged");
176             // Merge turn radii.
177             turnIndexMap = new HashMap<>();
178             List<Double> mergedTurnRadius = new ArrayList<>();
179             for (double t : this.getTurnRadiusArray()) {
180                 mergedTurnRadius.add(t);
181             }
182             for (int i2 = 0; i2 < r2.getTurnRadiusArray().length; i2++) {
183                 double t2 = r2.getTurnRadiusArray()[i2];
184                 boolean found = false;
185                 for (int i = 0; i < mergedTurnRadius.size(); i++) {
186                     if (MathTools.equals(mergedTurnRadius.get(i), t2)) {
187                         turnIndexMap.put(i2, i);
188                         found = true;
189                         break;
190                     }
191                 }
192                 if (!found) {
193                     turnIndexMap.put(i2, mergedTurnRadius.size());
194                     mergedTurnRadius.add(t2);
195                 }
196             }
197             for (PipeControlPoint pcp : r2.getControlPoints()) {
198                 PipelineComponent comp = pcp.getPipelineComponent();
199                 if (comp instanceof TurnComponent) {
200                     
201                 }
202             }
203             if (mergedTurnRadius.size() > this.getTurnRadiusArray().length) {
204                 double arr[] = new double[mergedTurnRadius.size()];
205                 for (int i = 0; i < mergedTurnRadius.size(); i++) {
206                     arr[i] = mergedTurnRadius.get(i);
207                 }
208                 this.setTurnRadiusArray(arr);
209             }
210         }
211         // Move components and control points
212         Collection<PipeControlPoint> pcps = r2.getControlPoints();
213         for (PipeControlPoint pcp : pcps) {
214             r2.deattachChild(pcp);
215             this.addChild(pcp);
216             PipelineComponent component = pcp.getPipelineComponent();
217             if (component != null) {
218                 if (!(component instanceof Nozzle)) {
219                     component.deattach();
220                     this.addChild(component);
221                 } else {
222                     Nozzle n = (Nozzle)component;
223                     n.setPipeRun(this);
224                 }
225             }
226         }
227         // Use new turn radii indexes 
228         if (turnIndexMap != null) {
229             for (PipeControlPoint pcp : pcps) {
230                 PipelineComponent component = pcp.getPipelineComponent();
231                 if (component instanceof TurnComponent) {
232                     TurnComponent tc = (TurnComponent)component;
233                     if (tc.getTurnRadiusIndex() == null || tc.getTurnRadiusIndex() < 0)
234                         continue;
235                     tc.setTurnRadiusIndex(turnIndexMap.get(tc.getTurnRadiusIndex()));
236                 }
237             }
238         }
239         r2.remove();
240         
241     }
242         
243         private class ComponentComparator implements Comparator<PipelineComponent> {
244                 @Override
245                 public int compare(PipelineComponent o1, PipelineComponent o2) {
246                         if (o1 == o2)
247                                 return 0;
248                         int i = 1;
249                         PipelineComponent c = o1.getPrevious();
250                         while (c != null) {
251                                 if (c == o2)
252                                         return i;
253                                 c = c.getPrevious();
254                                 i++;
255                         }
256                         i = -1;
257                         c = o1.getNext();
258                         while (c != null) {
259                                 if (c == o2)
260                                         return i;
261                                 c = c.getNext();
262                                 i--;
263                         }
264                         return 0;
265                         
266                 }
267         }
268         
269 }