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 //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);
120 public void remChild(PipelineComponent node) {
121 removeNode(Plant3D.URIs.children, node);
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)
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);
139 Collections.sort(coll, new ComponentComparator());
142 private static String PIPECP = "pipecp";
144 public void addChild(PipeControlPoint node) {
145 addNode(PIPECP,node);
148 public void remChild(PipeControlPoint node) {
149 removeNode(PIPECP, node);
152 public void deattachChild(PipeControlPoint node) {
153 deattachNode(PIPECP, node);
156 public Collection<PipeControlPoint> getControlPoints() {
157 Collection<PipeControlPoint> coll = new ArrayList<PipeControlPoint>();
158 for (IG3DNode n : getNodes(PIPECP)) {
159 coll.add((PipeControlPoint)n);
165 public boolean equalSpecs(PipeRun other) {
166 if (!MathTools.equals(pipeDiameter,other.pipeDiameter))
168 if (turnRadius.length != other.turnRadius.length)
170 for (int i = 0; i < turnRadius.length; i++) {
171 if (!MathTools.equals(turnRadius[i],other.turnRadius[i]))
177 public boolean canMerge(PipeRun other) {
178 return MathTools.equals(pipeDiameter,other.pipeDiameter);
182 * Merges contents of PipeRun r2 to this PipeRun. Note: does not connect boundary components!
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");
191 turnIndexMap = new HashMap<>();
192 List<Double> mergedTurnRadius = new ArrayList<>();
193 for (double t : this.getTurnRadiusArray()) {
194 mergedTurnRadius.add(t);
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);
207 turnIndexMap.put(i2, mergedTurnRadius.size());
208 mergedTurnRadius.add(t2);
211 for (PipeControlPoint pcp : r2.getControlPoints()) {
212 PipelineComponent comp = pcp.getPipelineComponent();
213 if (comp instanceof TurnComponent) {
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);
222 this.setTurnRadiusArray(arr);
225 // Move components and control points
226 Collection<PipeControlPoint> pcps = r2.getControlPoints();
227 for (PipeControlPoint pcp : pcps) {
228 r2.deattachChild(pcp);
230 PipelineComponent component = pcp.getPipelineComponent();
231 if (component != null) {
232 if (!(component instanceof Nozzle)) {
233 component.deattach();
234 this.addChild(component);
236 Nozzle n = (Nozzle)component;
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)
249 tc.setTurnRadiusIndex(turnIndexMap.get(tc.getTurnRadiusIndex()));
257 private class ComponentComparator implements Comparator<PipelineComponent> {
259 public int compare(PipelineComponent o1, PipelineComponent o2) {
263 PipelineComponent c = o1.getPrevious();