1 package org.simantics.plant3d.scenegraph;
3 import java.util.ArrayList;
4 import java.util.HashMap;
8 import javax.vecmath.Vector3d;
10 import org.simantics.g3d.math.MathTools;
11 import org.simantics.g3d.property.annotations.GetComboProperty;
12 import org.simantics.g3d.property.annotations.GetComboPropertyValue;
13 import org.simantics.g3d.property.annotations.GetPropertyValue;
14 import org.simantics.g3d.property.annotations.SetComboPropertyValue;
15 import org.simantics.g3d.property.annotations.SetPropertyValue;
16 import org.simantics.g3d.scenegraph.base.ParentNode;
17 import org.simantics.g3d.tools.NodeTools;
18 import org.simantics.objmap.graph.annotations.DynamicGraphType;
19 import org.simantics.objmap.graph.annotations.GetType;
20 import org.simantics.objmap.graph.annotations.RelatedGetValue;
21 import org.simantics.objmap.graph.annotations.RelatedSetValue;
22 import org.simantics.objmap.graph.annotations.SetType;
23 import org.simantics.plant3d.ontology.Plant3D;
24 import org.simantics.plant3d.scenegraph.controlpoint.ControlPointFactory;
25 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
26 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
28 @DynamicGraphType(Plant3D.URIs.TurnComponent)
29 public class TurnComponent extends PipelineComponent {
33 private PipeControlPoint controlPoint;
34 private Integer turnRadiusIndex;
36 @GetType(Plant3D.URIs.TurnComponent)
37 public String getType() {
41 @SetType(Plant3D.URIs.TurnComponent)
42 public void setType(String type) throws Exception{
44 controlPoint = ControlPointFactory.create(this);
48 public PipeControlPoint getControlPoint() {
53 public void setParent(ParentNode<?> parent, String name) {
54 super.setParent(parent, name);
55 setPipeRun((PipeRun)parent);
59 public Map<String, Object> updateParameterMap() {
60 Map<String,Object> map = new HashMap<String, Object>();
62 if (getPipeRun() != null) {
63 map.put("turnRadius", getTurnRadius());
64 map.put("radius", getDiameter() * 0.5);
66 if (controlPoint != null && controlPoint.getTurnAngle() != null && !Double.isNaN(controlPoint.getTurnAngle())) {
67 map.put("turnAngle", controlPoint.getTurnAngle());
72 public boolean isVariableAngle() {
73 return !controlPoint.isFixed();
77 public void updateParameters() {
78 super.updateParameters();
79 if (controlPoint.asFixedAngle()) {
80 Map<String,Object> calculated = getCalculatedParameters();
81 if (calculated.containsKey("length")) {
82 controlPoint.setLength((Double)calculated.get("length"));
84 PipingRules.requestUpdate(getControlPoint());
88 public Double getTurnAngle() {
89 return getControlPoint().getTurnAngle();
92 @RelatedGetValue(Plant3D.URIs.HasTurnAngle)
93 public Double _getTurnAngle() {
94 if (!getControlPoint().asFixedAngle())
96 return getControlPoint().getTurnAngle();
99 @RelatedSetValue(Plant3D.URIs.HasTurnAngle)
100 public void setTurnAngle(Double a) {
101 if (!getControlPoint().asFixedAngle())
103 getControlPoint().setTurnAngle(a);
106 @GetPropertyValue(name="Turn Angle", value="turn angle", tabId = "Default")
107 public Double getTurnAngleDeg() {
108 Double d = getControlPoint().getTurnAngle();
111 return MathTools.radToDeg(d);
114 public Vector3d getTurnAxis() {
115 return getControlPoint().getTurnAxis();
118 public Double getTurnRadius() {
119 if (turnRadiusIndex != null)
120 return getPipeRun().getTurnRadiusArray()[turnRadiusIndex];
121 return getPipeRun().getTurnRadiusArray()[0];
124 @RelatedGetValue(Plant3D.URIs.HasTurnRadiusIndex)
125 @GetComboPropertyValue(name="Turn Radius", value=Plant3D.URIs.HasTurnRadiusIndex, tabId = "Default")
126 public Integer getTurnRadiusIndex()
128 // TODO: For backwards compatibility, we do not accept null values.
129 // One development path would allow null index, and setting custom turn radius for the component.
130 if (turnRadiusIndex == null)
132 return turnRadiusIndex;
135 @RelatedSetValue(Plant3D.URIs.HasTurnRadiusIndex)
136 @SetComboPropertyValue(value=Plant3D.URIs.HasTurnRadiusIndex)
137 public void setTurnRadiusIndex(Integer turnRadiusIndex) {
138 if (this.turnRadiusIndex == turnRadiusIndex)
140 if (turnRadiusIndex == null)
142 if (turnRadiusIndex != null && getPipeRun() != null) {
143 if (getPipeRun().getTurnRadiusArray().length <= turnRadiusIndex)
146 this.turnRadiusIndex = turnRadiusIndex;
147 firePropertyChanged(Plant3D.URIs.HasTurnRadiusIndex);
148 PipingRules.requestUpdate(getControlPoint());
151 @GetComboProperty(value=Plant3D.URIs.HasTurnRadiusIndex)
152 public List<Double> _getTurnRadii() {
153 List<Double> values = new ArrayList<Double>();
154 for (double d : getPipeRun().getTurnRadiusArray())
160 @RelatedGetValue(Plant3D.URIs.HasRotationAngle)
161 @GetPropertyValue(name="Rotation Angle", value=Plant3D.URIs.HasRotationAngle, tabId = "Default")
162 public Double getRotationAngle() {
163 if (!controlPoint.asFixedAngle())
165 Double d = controlPoint.getRotationAngle();
168 return MathTools.radToDeg(d);
170 @RelatedSetValue(Plant3D.URIs.HasRotationAngle)
171 @SetPropertyValue(value=Plant3D.URIs.HasRotationAngle)
172 public void setRotationAngle(Double angle) {
173 if (!controlPoint.asFixedAngle())
176 if (angle == null || Double.isInfinite(angle) || Double.isNaN(angle)) {
179 angle = MathTools.degToRad(angle);
180 if (controlPoint.getRotationAngle() != null && Math.abs(controlPoint.getRotationAngle()-angle) < MathTools.NEAR_ZERO)
182 controlPoint.setRotationAngle(angle);
183 PipingRules.requestUpdate(getControlPoint());
186 @RelatedGetValue(Plant3D.URIs.IsReversed)
187 @GetPropertyValue(name="Reverse", value=Plant3D.URIs.IsReversed, tabId = "Default")
188 public Boolean isReversed() {
189 if (!controlPoint.asFixedAngle())
191 Boolean d = controlPoint._getReversed();
194 @RelatedSetValue(Plant3D.URIs.IsReversed)
195 public void setReversed(Boolean reverse) {
196 if (!controlPoint.asFixedAngle())
199 if (reverse == null) {
202 controlPoint.setReversed(reverse);
203 PipingRules.requestUpdate(getControlPoint());
207 protected double[] getColor() {
208 if (getControlPoint() == null || !getControlPoint().isFixed())
209 return new double[]{0.6,0.6,0.6};
211 return new double[]{1.0,0.0,0.0};
215 * Turn is a section of a circle; this method returns center of that circle.
218 public Vector3d getCenterPosition() {
219 // getPosition() is control point position, located outside of turn
220 // we need to calculate position in the middle of the turn
221 double t = Math.tan((Math.PI - getControlPoint().getTurnAngle()) * 0.5);
222 double tr = getTurnRadius();
224 if (t > MathTools.NEAR_ZERO)
226 Vector3d localC = new Vector3d(-R, 0.0, -tr);
227 // worldC is center of a circle
228 Vector3d worldC = NodeTools.getWorldPosition(this,localC);
233 * Returns position in the middle of turn component
236 public Vector3d getMiddlePosition() {
237 Vector3d pos = getWorldPosition();
238 Vector3d worldC = getCenterPosition();
240 // calculate vector from center to edge, which is middle of the turn
243 pos.scale(getTurnRadius());