]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/TurnComponent.java
3d5fb5bf7fc27130d078414dde5da2a72bbd17c9
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / scenegraph / TurnComponent.java
1 package org.simantics.plant3d.scenegraph;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import javax.vecmath.Vector3d;
7
8 import org.simantics.g3d.math.MathTools;
9 import org.simantics.g3d.property.annotations.GetPropertyValue;
10 import org.simantics.g3d.property.annotations.SetPropertyValue;
11 import org.simantics.g3d.scenegraph.base.ParentNode;
12 import org.simantics.g3d.tools.NodeTools;
13 import org.simantics.objmap.graph.annotations.DynamicGraphType;
14 import org.simantics.objmap.graph.annotations.GetType;
15 import org.simantics.objmap.graph.annotations.RelatedGetValue;
16 import org.simantics.objmap.graph.annotations.RelatedSetValue;
17 import org.simantics.objmap.graph.annotations.SetType;
18 import org.simantics.plant3d.ontology.Plant3D;
19 import org.simantics.plant3d.scenegraph.controlpoint.ControlPointFactory;
20 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
21 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
22
23 @DynamicGraphType(Plant3D.URIs.TurnComponent)
24 public class TurnComponent extends PipelineComponent {
25
26         
27         private String type;
28         private PipeControlPoint controlPoint;
29         private Integer turnRadiusIndex;
30         
31         @GetType(Plant3D.URIs.TurnComponent)
32         public String getType() {
33                 return type;
34         }
35         
36         @SetType(Plant3D.URIs.TurnComponent)
37         public void setType(String type) throws Exception{
38                 this.type = type;
39                 controlPoint = ControlPointFactory.create(this);
40         }
41         
42         @Override
43         public PipeControlPoint getControlPoint() {
44                 return controlPoint;
45         }
46         
47         @Override
48         public void setParent(ParentNode<?> parent, String name) {
49                 super.setParent(parent, name);
50                 setPipeRun((PipeRun)parent);
51         }
52         
53         @Override
54         public Map<String, Object> updateParameterMap() {
55                 Map<String,Object> map = new HashMap<String, Object>();
56                 
57                 if (getPipeRun() != null) {
58                 map.put("turnRadius", getTurnRadius());
59                 map.put("radius", getDiameter() * 0.5);
60                 }
61                 if (controlPoint != null && controlPoint.getTurnAngle() != null  && !Double.isNaN(controlPoint.getTurnAngle())) {
62                         map.put("turnAngle", controlPoint.getTurnAngle());
63                 }
64                 return map;
65         }
66         
67         public boolean isVariableAngle() {
68                 return !controlPoint.isFixed();
69         }
70         
71         @Override
72         public void updateParameters() {
73                 super.updateParameters();
74                 if (controlPoint.asFixedAngle()) {
75                         Map<String,Object> calculated = getCalculatedParameters();
76                         if (calculated.containsKey("length")) {
77                                 controlPoint.setLength((Double)calculated.get("length"));
78                         }
79                         PipingRules.requestUpdate(getControlPoint());
80                 }
81         }
82         
83         @RelatedGetValue(Plant3D.URIs.HasTurnAngle)
84         public Double getTurnAngle() {
85             if (!getControlPoint().asFixedAngle())
86                 return null;
87                 return getControlPoint().getTurnAngle();
88         }
89         
90         @RelatedSetValue(Plant3D.URIs.HasTurnAngle)
91         public void setTurnAngle(Double a) {
92                 if (!getControlPoint().asFixedAngle())
93                         return;
94                 getControlPoint().setTurnAngle(a);            
95         }
96         
97         @GetPropertyValue(name="Turn Angle", value="turn angle", tabId = "Default")
98         public Double getTurnAngleDeg() {
99                 Double d = getControlPoint().getTurnAngle();
100                 if (d == null)
101                         return null;
102                 return MathTools.radToDeg(d);
103         }
104         
105         public Vector3d getTurnAxis() {
106                 return getControlPoint().getTurnAxis();
107         }
108         
109         @GetPropertyValue(name="Turn Radius", value="TurnRadius", tabId = "Default")
110         public Double getTurnRadius() {
111             if (turnRadiusIndex != null)
112                 return getPipeRun().getTurnRadiusArray()[turnRadiusIndex];
113             return getPipeRun().getTurnRadiusArray()[0];
114         }
115         
116         @RelatedGetValue(Plant3D.URIs.HasTurnRadiusIndex)
117         @GetPropertyValue(name="Turn Radius Index", value=Plant3D.URIs.HasTurnRadiusIndex, tabId = "Default")
118         public Integer getTurnRadiusIndex() 
119         {
120         // TODO: For backwards compatibility, we do not accept null values. 
121         //       One development path would allow null index, and setting custom turn radius for the component.
122         if (turnRadiusIndex == null)
123                 return 0;
124             return turnRadiusIndex;
125         }
126         
127         @RelatedSetValue(Plant3D.URIs.HasTurnRadiusIndex)
128         @SetPropertyValue(value=Plant3D.URIs.HasTurnRadiusIndex)
129     public void setTurnRadiusIndex(Integer turnRadiusIndex) {
130             if (this.turnRadiusIndex == turnRadiusIndex)
131                 return;
132             if (turnRadiusIndex == null)
133                 return;
134             if (turnRadiusIndex != null && getPipeRun() != null) {
135                 if (getPipeRun().getTurnRadiusArray().length <= turnRadiusIndex)
136                     return;
137             }
138             this.turnRadiusIndex = turnRadiusIndex;
139         firePropertyChanged(Plant3D.URIs.HasTurnRadiusIndex);
140         PipingRules.requestUpdate(getControlPoint());
141     }
142         
143         @RelatedGetValue(Plant3D.URIs.HasRotationAngle)
144         @GetPropertyValue(name="Rotation Angle", value=Plant3D.URIs.HasRotationAngle, tabId = "Default")
145         public Double getRotationAngle() {
146                 if (!controlPoint.asFixedAngle())
147                         return null;
148                 Double d = controlPoint.getRotationAngle();
149                 if (d == null)
150                         return 0.0;
151                 return MathTools.radToDeg(d);
152         }
153         @RelatedSetValue(Plant3D.URIs.HasRotationAngle)
154         @SetPropertyValue(value=Plant3D.URIs.HasRotationAngle)
155         public void setRotationAngle(Double angle) {
156                 if (!controlPoint.asFixedAngle())
157                         return;
158                 
159                 if (angle == null || Double.isInfinite(angle) || Double.isNaN(angle)) {
160                         return;
161                 }
162                 angle = MathTools.degToRad(angle);
163                 if (controlPoint.getRotationAngle() != null && Math.abs(controlPoint.getRotationAngle()-angle) < MathTools.NEAR_ZERO)
164                         return;
165                 controlPoint.setRotationAngle(angle);
166                 PipingRules.requestUpdate(getControlPoint());
167         }
168         
169         @RelatedGetValue(Plant3D.URIs.IsReversed)
170         @GetPropertyValue(name="Reverse", value=Plant3D.URIs.IsReversed, tabId = "Default")
171         public Boolean isReversed() {
172                 if (!controlPoint.asFixedAngle())
173                         return null;
174                 Boolean d = controlPoint._getReversed();
175                 return d;
176         }
177         @RelatedSetValue(Plant3D.URIs.IsReversed)
178         public void setReversed(Boolean reverse) {
179                 if (!controlPoint.asFixedAngle())
180                         return;
181                 
182                 if (reverse == null) {
183                         return;
184                 }
185                 controlPoint.setReversed(reverse);
186                 PipingRules.requestUpdate(getControlPoint()); 
187         }
188         
189         @Override
190         protected double[] getColor() {
191                 if (getControlPoint() == null || !getControlPoint().isFixed())
192                         return new double[]{0.6,0.6,0.6};
193                 else
194                         return new double[]{1.0,0.0,0.0};
195         }
196         
197         /**
198          * Turn is a section of a circle; this method returns center of that circle.
199          * @return
200          */
201         public Vector3d getCenterPosition() {
202             // getPosition() is control point position, located outside of turn
203         // we need to calculate position in the middle of the turn
204         double t = Math.tan((Math.PI - getControlPoint().getTurnAngle()) * 0.5);
205         double tr = getTurnRadius();
206         double R = 0.0;
207         if (t > MathTools.NEAR_ZERO)
208             R = tr / t;
209         Vector3d localC = new Vector3d(-R, 0.0, -tr);
210         // worldC is center of a circle
211         Vector3d worldC = NodeTools.getWorldPosition(this,localC);
212         return worldC;
213         }
214         
215         /**
216          * Returns position in the middle of turn component
217          * @return
218          */
219         public Vector3d getMiddlePosition() {
220             Vector3d pos = getWorldPosition();
221             Vector3d worldC = getCenterPosition();
222             
223             // calculate vector from center to edge, which is middle of the turn
224         pos.sub(worldC);
225         pos.normalize();
226         pos.scale(getTurnRadius());
227         pos.add(worldC);
228         return pos;
229         }
230 }