1 package org.simantics.plant3d.scenegraph;
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;
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;
28 import vtk.vtkRenderer;
30 @GraphType(Plant3D.URIs.PipeRun)
31 @PropertyTabBlacklist("Transform")
32 public class PipeRun extends P3DParentNode<IP3DNode> {
34 private double pipeDiameter = 0.1;
35 private double pipeThickness = 0.0;
36 private double[] turnRadius = new double[] {0.2};
39 public void update(vtkRenderer ren) {
44 public void visualize(VtkView panel) {
49 public Collection<vtkProp3D> getActors() {
50 return Collections.emptyList();
54 public void stopVisualize() {
58 @SuppressWarnings("deprecation")
59 @RelatedGetValue(Plant3D.URIs.HasTurnRadius)
60 @GetPropertyValue(value=Plant3D.URIs.HasTurnRadius, name = "Elbow radius")
61 public double getTurnRadius() {
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)
71 this.turnRadius[0] = turnRadius;
72 firePropertyChanged(Plant3D.URIs.HasTurnRadius);
73 firePropertyChanged(Plant3D.URIs.HasTurnRadiusArray);
76 @RelatedGetValue(Plant3D.URIs.HasTurnRadiusArray)
77 @GetPropertyValue(value=Plant3D.URIs.HasTurnRadiusArray, name = "Elbow radius array")
78 public double[] getTurnRadiusArray() {
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))
87 this.turnRadius = turnRadiusArray;
88 firePropertyChanged(Plant3D.URIs.HasTurnRadiusArray);
91 @RelatedGetValue(Plant3D.URIs.HasPipeDiameter)
92 @GetPropertyValue(value=Plant3D.URIs.HasPipeDiameter, name = "Diameter")
93 public double getPipeDiameter() {
97 @RelatedSetValue(Plant3D.URIs.HasPipeDiameter)
98 @SetPropertyValue(Plant3D.URIs.HasPipeDiameter)
99 public void setPipeDiameter(double pipeDiameter) {
100 if (this.pipeDiameter == pipeDiameter)
103 this.pipeDiameter = pipeDiameter;
104 firePropertyChanged(Plant3D.URIs.HasPipeDiameter);
107 @RelatedGetValue(Plant3D.URIs.HasPipeThickness)
108 @GetPropertyValue(value=Plant3D.URIs.HasPipeThickness, name = "Wall Thickness")
109 public double getPipeThickness() {
110 return pipeThickness;
113 @RelatedSetValue(Plant3D.URIs.HasPipeThickness)
114 @SetPropertyValue(Plant3D.URIs.HasPipeThickness)
115 public void setPipeThickness(double pipeThickness) {
116 if (this.pipeThickness == pipeThickness)
119 this.pipeThickness = pipeThickness;
120 firePropertyChanged(Plant3D.URIs.HasPipeThickness);
123 public double getInsideDiameter() {
124 return pipeDiameter - 2 * pipeThickness;
127 @RelatedElementsAdd(Plant3D.URIs.children)
128 public void addChild(PipelineComponent node) {
129 addNode(Plant3D.URIs.children,node);
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);
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);
147 public void remChild(PipelineComponent node) {
148 removeNode(Plant3D.URIs.children, node);
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)
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);
166 Collections.sort(coll, new ComponentComparator());
169 private static String PIPECP = "pipecp";
171 public void addChild(PipeControlPoint node) {
172 addNode(PIPECP,node);
175 public void remChild(PipeControlPoint node) {
176 removeNode(PIPECP, node);
179 public void deattachChild(PipeControlPoint node) {
180 deattachNode(PIPECP, node);
183 public Collection<PipeControlPoint> getControlPoints() {
184 Collection<PipeControlPoint> coll = new ArrayList<PipeControlPoint>();
185 for (IG3DNode n : getNodes(PIPECP)) {
186 coll.add((PipeControlPoint)n);
192 public boolean equalSpecs(PipeRun other) {
193 if (!MathTools.equals(pipeDiameter,other.pipeDiameter))
195 if (turnRadius.length != other.turnRadius.length)
197 for (int i = 0; i < turnRadius.length; i++) {
198 if (!MathTools.equals(turnRadius[i],other.turnRadius[i]))
204 public boolean canMerge(PipeRun other) {
205 return MathTools.equals(pipeDiameter,other.pipeDiameter);
209 * Merges contents of PipeRun r2 to this PipeRun. Note: does not connect boundary components!
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");
218 turnIndexMap = new HashMap<>();
219 List<Double> mergedTurnRadius = new ArrayList<>();
220 for (double t : this.getTurnRadiusArray()) {
221 mergedTurnRadius.add(t);
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);
234 turnIndexMap.put(i2, mergedTurnRadius.size());
235 mergedTurnRadius.add(t2);
238 for (PipeControlPoint pcp : r2.getControlPoints()) {
239 PipelineComponent comp = pcp.getPipelineComponent();
240 if (comp instanceof TurnComponent) {
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);
249 this.setTurnRadiusArray(arr);
252 // Move components and control points
253 Collection<PipeControlPoint> pcps = r2.getControlPoints();
254 for (PipeControlPoint pcp : pcps) {
255 r2.deattachChild(pcp);
257 PipelineComponent component = pcp.getPipelineComponent();
258 if (component != null) {
259 if (!(component instanceof Nozzle)) {
260 component.deattach();
261 this.addChild(component);
263 Nozzle n = (Nozzle)component;
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)
276 tc.setTurnRadiusIndex(turnIndexMap.get(tc.getTurnRadiusIndex()));
284 private class ComponentComparator implements Comparator<PipelineComponent> {
286 public int compare(PipelineComponent o1, PipelineComponent o2) {
290 PipelineComponent c = o1.getPrevious();