X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.plant3d%2Fsrc%2Forg%2Fsimantics%2Fplant3d%2Fscenegraph%2FPipelineComponent.java;h=3f393364e3ccf456cc9ab63b53b8c01927ee6278;hb=refs%2Fchanges%2F58%2F3358%2F2;hp=6ddd7a09fc9ba3d68c83fd8bb6c6534d84485619;hpb=53d55c24c779745f188bdb18d32f71d20acb61b2;p=simantics%2F3d.git diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java index 6ddd7a09..3f393364 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipelineComponent.java @@ -14,7 +14,9 @@ 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.Direction; import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PointType; +import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType; import org.simantics.plant3d.scenegraph.controlpoint.PipingRules; /** @@ -386,6 +388,15 @@ public abstract class PipelineComponent extends GeometryNode { } 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() { @@ -467,4 +478,116 @@ public abstract class PipelineComponent extends GeometryNode { getControlPoint().getControlPointEnds(p1, p2); } + 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"); + } + } }