1 package org.simantics.plant3d.scenegraph;
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;
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;
27 import vtk.vtkRenderer;
29 @GraphType(Plant3D.URIs.PipeRun)
30 @PropertyTabBlacklist("Transform")
31 public class PipeRun extends P3DParentNode<IP3DNode> {
33 private double pipeDiameter = 0.1;
34 private double[] turnRadius = new double[] {0.2};
37 public void update(vtkRenderer ren) {
42 public void visualize(VtkView panel) {
47 public Collection<vtkProp3D> getActors() {
48 return Collections.emptyList();
52 public void stopVisualize() {
56 @SuppressWarnings("deprecation")
57 @RelatedGetValue(Plant3D.URIs.HasTurnRadius)
58 @GetPropertyValue(value=Plant3D.URIs.HasTurnRadius, name = "Elbow radius")
59 public double getTurnRadius() {
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);
72 @RelatedGetValue(Plant3D.URIs.HasTurnRadiusArray)
73 @GetPropertyValue(value=Plant3D.URIs.HasTurnRadiusArray, name = "Elbow radius array")
74 public double[] getTurnRadiusArray() {
78 @RelatedSetValue(Plant3D.URIs.HasTurnRadiusArray)
79 @SetPropertyValue(Plant3D.URIs.HasTurnRadiusArray)
80 public void setTurnRadiusArray(double[] turnRadiusArray) {
81 if (turnRadiusArray == null || turnRadiusArray.length == 0)
83 this.turnRadius = turnRadiusArray;
84 firePropertyChanged(Plant3D.URIs.HasTurnRadiusArray);
87 @RelatedGetValue(Plant3D.URIs.HasPipeDiameter)
88 @GetPropertyValue(value=Plant3D.URIs.HasPipeDiameter, name = "Diameter")
89 public double getPipeDiameter() {
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);
100 @RelatedElementsAdd(Plant3D.URIs.children)
101 public void addChild(PipelineComponent node) {
102 addNode(Plant3D.URIs.children,node);
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);
114 @RelatedElementsRem(Plant3D.URIs.children)
115 public void remChild(PipelineComponent node) {
116 removeNode(Plant3D.URIs.children, node);
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);
125 Collections.sort(coll, new ComponentComparator());
128 private static String PIPECP = "pipecp";
130 public void addChild(PipeControlPoint node) {
131 addNode(PIPECP,node);
134 public void remChild(PipeControlPoint node) {
135 removeNode(PIPECP, node);
138 public void deattachChild(PipeControlPoint node) {
139 deattachNode(PIPECP, node);
142 public Collection<PipeControlPoint> getControlPoints() {
143 Collection<PipeControlPoint> coll = new ArrayList<PipeControlPoint>();
144 for (IG3DNode n : getNodes(PIPECP)) {
145 coll.add((PipeControlPoint)n);
151 public boolean equalSpecs(PipeRun other) {
152 if (!MathTools.equals(pipeDiameter,other.pipeDiameter))
154 if (turnRadius.length != other.turnRadius.length)
156 for (int i = 0; i < turnRadius.length; i++) {
157 if (!MathTools.equals(turnRadius[i],other.turnRadius[i]))
163 public boolean canMerge(PipeRun other) {
164 return MathTools.equals(pipeDiameter,other.pipeDiameter);
168 * Merges contents of PipeRun r2 to this PipeRun. Note: does not connect boundary components!
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");
177 turnIndexMap = new HashMap<>();
178 List<Double> mergedTurnRadius = new ArrayList<>();
179 for (double t : this.getTurnRadiusArray()) {
180 mergedTurnRadius.add(t);
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);
193 turnIndexMap.put(i2, mergedTurnRadius.size());
194 mergedTurnRadius.add(t2);
197 for (PipeControlPoint pcp : r2.getControlPoints()) {
198 PipelineComponent comp = pcp.getPipelineComponent();
199 if (comp instanceof TurnComponent) {
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);
208 this.setTurnRadiusArray(arr);
211 // Move components and control points
212 Collection<PipeControlPoint> pcps = r2.getControlPoints();
213 for (PipeControlPoint pcp : pcps) {
214 r2.deattachChild(pcp);
216 PipelineComponent component = pcp.getPipelineComponent();
217 if (component != null) {
218 if (!(component instanceof Nozzle)) {
219 component.deattach();
220 this.addChild(component);
222 Nozzle n = (Nozzle)component;
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)
235 tc.setTurnRadiusIndex(turnIndexMap.get(tc.getTurnRadiusIndex()));
243 private class ComponentComparator implements Comparator<PipelineComponent> {
245 public int compare(PipelineComponent o1, PipelineComponent o2) {
249 PipelineComponent c = o1.getPrevious();