package org.simantics.plant3d.scenegraph;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
+import java.util.Map.Entry;
import javax.vecmath.Quat4d;
import javax.vecmath.Tuple3d;
import javax.vecmath.Vector3d;
import org.simantics.g3d.math.MathTools;
+import org.simantics.g3d.property.annotations.CompoundGetPropertyValue;
+import org.simantics.g3d.property.annotations.CompoundSetPropertyValue;
import org.simantics.g3d.property.annotations.GetPropertyValue;
import org.simantics.g3d.property.annotations.PropertyContributor;
+import org.simantics.objmap.graph.annotations.CompoundRelatedGetValue;
+import org.simantics.objmap.graph.annotations.CompoundRelatedSetValue;
import org.simantics.objmap.graph.annotations.RelatedGetObj;
import org.simantics.objmap.graph.annotations.RelatedSetObj;
import org.simantics.plant3d.ontology.Plant3D;
import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
-import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Type;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Direction;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PointType;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
/**
*/
@PropertyContributor
public abstract class PipelineComponent extends GeometryNode {
+
+ private static boolean DEBUG = false;
private PipeRun pipeRun;
private PipelineComponent next;
private PipelineComponent previous;
+ public PipeRun getPipeRun() {
+ return pipeRun;
+ }
+
/**
* Sets the pipe run.
*
super.updateParameters();
}
+ @Override
+ @CompoundRelatedGetValue(objRelation=Plant3D.URIs.hasParameter,objType=Plant3D.URIs.Parameter,valRelation=Plant3D.URIs.hasParameterValue)
+ @CompoundGetPropertyValue(name="Parameters",tabId="Parameters",value="parameters")
+ public Map<String, Object> getParameterMap() {
+ return super.getParameterMap();
+ }
+
+ @Override
+ @CompoundRelatedSetValue(Plant3D.URIs.hasParameter)
+ public void setParameterMap(Map<String, Object> parameters) {
+ super.setParameterMap(parameters);
+ }
+
+ @CompoundGetPropertyValue(name="Parameters",tabId="Parameters",value="parameters")
+ public Map<String,Object> getParameterMapUI() {
+ // TODO : how to filter parameters that are calculated by geometry provider?
+ Map<String,Object> map = new HashMap<String, Object>(getParameterMap());
+ map.remove("radius");
+ return map;
+ }
+
+ @CompoundSetPropertyValue(value="parameters")
+ public void setParameterMapUI(Map<String, Object> parameters) {
+ Map<String, Object> curr = getParameterMap();
+ for (Entry<String, Object> entry : curr.entrySet()) {
+ if (!parameters.containsKey(entry.getKey()))
+ parameters.put(entry.getKey(), entry.getValue());
+ }
+ setParameterMap(parameters);
+ }
+
public abstract void setType(String typeURI) throws Exception;
@RelatedGetObj(Plant3D.URIs.HasNext)
if (next == comp)
return;
if (this.next != null)
- this.next._removeRef(this);
+ this.next._removeRef(this);
this.next = comp;
this.syncnext = false;
+ if (DEBUG) System.out.println(this + " next " + comp);
syncNext();
firePropertyChanged(Plant3D.URIs.HasNext);
if (comp != null)
comp.sync();
-// System.out.println(this + " next " + comp);
+
}
if (previous == comp)
return;
if (this.previous != null)
- this.previous._removeRef(this);
+ this.previous._removeRef(this);
this.previous = comp;
this.syncprev = false;
+ if (DEBUG) System.out.println(this + " prev " + comp);
syncPrevious();
firePropertyChanged(Plant3D.URIs.HasPrevious);
if (comp != null)
comp.sync();
-// System.out.println(this + " prev " + comp);
+
}
private PipelineComponent branch0;
if (branch0 == comp)
return;
if (this.branch0 != null)
- this.branch0._removeRef(this);
+ this.branch0._removeRef(this);
this.branch0 = comp;
this.syncbr0 = false;
+ if (DEBUG) System.out.println(this + " br0 " + comp);
syncBranch0();
firePropertyChanged(Plant3D.URIs.HasBranch0);
if (comp != null)
comp.sync();
-// System.out.println(this + " next " + comp);
}
@GetPropertyValue(name="Previous",tabId="Debug",value=Plant3D.URIs.HasPrevious)
- public String getPreviousDebug() {
- if (previous == null)
- return null;
- return previous.getName();
- }
-
- @GetPropertyValue(name="Next",tabId="Debug",value=Plant3D.URIs.HasNext)
- public String getNextDebug() {
- if (next == null)
- return null;
- return next.getName();
- }
-
+ public String getPreviousDebug() {
+ if (previous == null)
+ return null;
+ return previous.getName();
+ }
+
+ @GetPropertyValue(name="Next",tabId="Debug",value=Plant3D.URIs.HasNext)
+ public String getNextDebug() {
+ if (next == null)
+ return null;
+ return next.getName();
+ }
+
@GetPropertyValue(name="Branch0",tabId="Debug",value=Plant3D.URIs.HasBranch0)
- public String getBR0Debug() {
- if (branch0 == null)
- return null;
- return branch0.getName();
- }
+ public String getBR0Debug() {
+ if (branch0 == null)
+ return null;
+ return branch0.getName();
+ }
return null;
branchPoint = new PipeControlPoint(this,branch0.getPipeRun());
branchPoint.setFixed(false);
- branchPoint.setType(Type.END);
+ branchPoint.setType(PointType.END);
branchPoint.parent = getControlPoint();
getControlPoint().children.add(branchPoint);
branchPoint.setWorldOrientation(getControlPoint().getWorldOrientation());
// When link to a component is removed, also link to the other direction must be removed at the same time, or
// Control point structure is left into illegal state.
private void _removeRef(PipelineComponent comp) {
- if (next == comp) {
- next = null;
- syncnext = false;
- syncNext();
- } else if (previous == comp) {
- previous = null;
- syncprev = false;
- syncPrevious();
- } else if (branch0 == comp) {
- branch0 = null;
- syncbr0 = false;
- syncBranch0();
- }
+ if (next == comp) {
+ next = null;
+ syncnext = false;
+ firePropertyChanged(Plant3D.URIs.HasNext);
+ syncNext();
+ } else if (previous == comp) {
+ previous = null;
+ syncprev = false;
+ firePropertyChanged(Plant3D.URIs.HasPrevious);
+ syncPrevious();
+ } else if (branch0 == comp) {
+ branch0 = null;
+ syncbr0 = false;
+ firePropertyChanged(Plant3D.URIs.HasBranch0);
+ syncBranch0();
+ }
}
boolean syncnext = false;
- private void syncNext() {
- if (syncnext)
- return;
- syncnext = _syncNext();
- }
+ private void syncNext() {
+ if (syncnext)
+ return;
+ syncnext = _syncNext();
+ }
private boolean _syncNext() {
- PipeControlPoint pcp = getControlPoint();
+ PipeControlPoint pcp = getControlPoint();
if (pcp != null) {
-
+
if (next != null ) {
if (next.getControlPoint() != null) {
} else if (br0) {
return _connectNext(pcp, next.getBranchPoint());
} else {
- return false;
+ return false;
}
} else {
return false;
}
} else if (pcp.getNext() != null) {
- pcp.setNext(null);
- return true;
+ pcp.setNext(null);
+ return true;
}
} else {
return false;
}
boolean syncprev = false;
- private void syncPrevious() {
- if (syncprev)
- return;
- syncprev = _syncPrevious();
- }
+ private void syncPrevious() {
+ if (syncprev)
+ return;
+ syncprev = _syncPrevious();
+ }
private boolean _syncPrevious() {
- PipeControlPoint pcp = getControlPoint();
+ PipeControlPoint pcp = getControlPoint();
if (pcp != null) {
if (previous != null ) {
if (previous.getControlPoint() != null) {
} else if (br0) {
return _connectPrev(pcp, previous.getBranchPoint());
} else {
- return false;
+ return false;
}
} else {
return false;
}
} else if (pcp.getPrevious() != null) {
- pcp.setPrevious(null);
- return true;
+ pcp.setPrevious(null);
+ return true;
}
} else {
return false;
boolean syncbr0 = false;
private void syncBranch0() {
- if (syncbr0)
- return;
- syncbr0 = _syncBranch0();
+ if (syncbr0)
+ return;
+ syncbr0 = _syncBranch0();
}
private boolean _syncBranch0() {
if (branch0 != null) {
if (branch0.getControlPoint() != null) {
PipeControlPoint branchPoint = getBranchPoint();
+ if (branchPoint == null)
+ return false;
PipeControlPoint pcp = branch0.getControlPoint();
// TODO, relying that the other direction is connected.
boolean next = branch0.getPrevious() == this; // this --> branch0
} else if (prev){
_connectPrev(branchPoint, pcp);
} else {
- return false;
+ return false;
}
} else {
}
} else if (getControlPoint().getSubPoint().size() > 0) { // TODO : this may cause problems? (Removes branch point, before branch has been set?)
- getControlPoint().getSubPoint().get(0).remove();
- getControlPoint().children.clear();
+ //getControlPoint().getSubPoint().get(0).remove();
+ //getControlPoint().children.clear();
return true;
}
} else {
return Collections.EMPTY_MAP;
}
- public PipeRun getPipeRun() {
- return pipeRun;
- }
-
public abstract String getType();
public abstract PipeControlPoint getControlPoint();
@Override
public void remove() {
+ if (DEBUG) System.out.println(this + " remove");
PipeControlPoint pcp = getControlPoint();
// Second check is needed, when remove process is initiated from control point.
if (pcp != null && pcp.getPipelineComponent() != null) {
}
super.remove();
}
+
+ public void removeAndSplit() {
+ PipeControlPoint pcp = getControlPoint();
+ // Second check is needed, when remove process is initiated from control point.
+ if (pcp != null && pcp.getPipelineComponent() != null) {
+ pcp.removeAndSplit();
+ }
+ super.remove();
+ }
@Override
protected double[] getColor() {
double a = pcp.getTurnAngle();
return a*r;
}
- default:
- return null;
+ default:
+ return null;
}
}
- public void getControlPointEnds(Tuple3d p1, Tuple3d p2) {
+ public void getEnds(Tuple3d p1, Tuple3d p2) {
getControlPoint().getControlPointEnds(p1, p2);
}
- public Vector3d getNormal() {
- Vector3d v = new Vector3d();
- MathTools.rotate(getWorldOrientation(), MathTools.Z_AXIS, v);
- return v;
+ public void getEndDirections(Tuple3d v1, Tuple3d v2) {
+ getControlPoint().getEndDirections(v1, v2);
}
+ public void getCentroid(Tuple3d p) {
+ PipeControlPoint pcp = getControlPoint();
+ if (pcp == null)
+ throw new IllegalStateException("No centroid defined");
+
+ switch (pcp.getType()) {
+ case INLINE:
+ case END:
+ // Just return the world location
+ if (!pcp.isSizeChange()) {
+ p.set(pcp.getWorldPosition());
+ return;
+ }
+
+ // Calculate center of mass for the frustum
+ double r1 = getPipeRun().getPipeDiameter();
+ double r2 = getAlternativePipeRun().getPipeDiameter();
+
+ Vector3d p1 = new Vector3d(), p2 = new Vector3d();
+ pcp.getInlineControlPointEnds(p1, p2);
+
+ // Squared sum of radii
+ double r12 = r1 + r2;
+ r12 *= r12;
+
+ // The larger of the radii form the base of a frustum
+ double rmax = Math.max(r1, r2);
+
+ // Relative distance from the base of the frustum
+ double h = (r12 + 2*rmax*rmax) / (4 * (r12 - r1*r2));
+
+ // Relative distance from p1 to p2
+ if (r1 < r2)
+ h = 1 - h;
+
+ p2.sub(p1);
+ p1.scaleAdd(h, p2);
+
+ p.set(p1);
+ return;
+ case TURN: {
+ Vector3d loc = pcp.getRealPosition(PositionType.PREVIOUS);
+
+ double r = getPipeRun().getTurnRadius();
+ double a = pcp.getTurnAngle();
+ double pipeRadius = pcp.getPipeRun().getPipeDiameter() / 2;
+
+ // Unit vector in inlet flow direction
+ Vector3d inletDir = pcp.getPathLegDirection(Direction.PREVIOUS);
+ inletDir.scale(-1.0);
+ inletDir.normalize();
+
+ // Normal to both inletDir and turn axis in world coordinates
+ Vector3d outletDir = pcp.getPathLegDirection(Direction.NEXT);
+ Vector3d normal = new Vector3d(inletDir);
+ normal.scaleAdd(-inletDir.dot(outletDir), outletDir);
+ normal.normalize();
+
+ // Location of turn axis
+ Vector3d center = new Vector3d(normal);
+ center.scaleAdd(r, loc);
+
+ // Add vector components from axis to centroid
+ double c = r + pipeRadius * pipeRadius / (4 * r);
+ double c1 = c * Math.sin(a) / a;
+ double c2 = c * (1 - Math.cos(a)) / a;
+ normal.scale(-c1);
+ inletDir.scale(c2);
+ center.add(normal);
+ center.add(inletDir);
+
+ // Return value
+ p.set(center);
+ return;
+ }
+ default:
+ throw new IllegalStateException("No centroid defined");
+ }
+ }
+
+ public double getVolume() {
+ PipeControlPoint pcp = getControlPoint();
+ if (pcp == null)
+ throw new IllegalStateException("No centroid defined");
+
+ double pipeRadius = getPipeRun().getPipeDiameter() / 2;
+
+ switch (pcp.getType()) {
+ case INLINE:
+ case END:
+ if (!pcp.isSizeChange()) {
+ // Just return the cylinder volume
+ return pcp.getLength() * Math.PI * pipeRadius * pipeRadius;
+ }
+
+ // Calculate center of mass for the frustum
+ double r1 = pipeRadius;
+ double r2 = getAlternativePipeRun().getPipeDiameter() / 2;
+ return pcp.getLength() * Math.PI * (r1*r1 + r1*r2 + r2*r2) / 4;
+ case TURN: {
+ double r = getPipeRun().getTurnRadius();
+ double a = pcp.getTurnAngle();
+ return r * a * Math.PI * pipeRadius * pipeRadius;
+ }
+ default:
+ throw new IllegalStateException("No centroid defined");
+ }
+ }
}