import java.util.List;
import java.util.Map;
+import javax.vecmath.Vector3d;
+
import org.simantics.Simantics;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.g3d.scenegraph.GeometryProvider;
import org.simantics.layer0.Layer0;
-import org.simantics.opencascade.SolidModelProvider;
import org.simantics.plant3d.ontology.Plant3D;
import org.simantics.plant3d.scenegraph.EndComponent;
+import org.simantics.plant3d.scenegraph.Equipment;
import org.simantics.plant3d.scenegraph.InlineComponent;
import org.simantics.plant3d.scenegraph.Nozzle;
import org.simantics.plant3d.scenegraph.P3DRootNode;
+import org.simantics.plant3d.scenegraph.PipeRun;
import org.simantics.plant3d.scenegraph.PipelineComponent;
import org.simantics.plant3d.scenegraph.TurnComponent;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
+import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Direction;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
+import org.simantics.plant3d.utils.Item.Type;
+import org.simantics.utils.ui.ExceptionUtils;
public class ComponentUtils {
private static Map<String,Class<? extends PipelineComponent>> clazzes = new HashMap<String, Class<? extends PipelineComponent>>();
- private static Map<String,SolidModelProvider> providers = new HashMap<String,SolidModelProvider>();
+ private static Map<String,GeometryProvider> providers = new HashMap<String,GeometryProvider>();
+ private static Map<String,String> names = new HashMap<String,String>();
public static void preloadCache() {
Simantics.getSession().asyncRequest(new ReadRequest() {
types.add(Plant3D.URIs.Builtin_Elbow);
types.add(Plant3D.URIs.Builtin_ConcentricReducer);
types.add(Plant3D.URIs.Builtin_BranchSplitComponent);
-// types.add(Plant3D.URIs.Builtin_EccentricReducer);
+ types.add(Plant3D.URIs.Builtin_EccentricReducer);
for (String typeURI : types) {
load(graph, typeURI);
});
}
- private static SolidModelProvider getProvider(ReadGraph graph, Resource type) throws DatabaseException {
+ private static GeometryProvider getProvider(ReadGraph graph, Resource type) throws DatabaseException {
Layer0 l0 = Layer0.getInstance(graph);
Plant3D p3d = Plant3D.getInstance(graph);
}
}
if (geom != null) {
- SolidModelProvider provider = graph.adapt(geom, SolidModelProvider.class);
+ GeometryProvider provider = graph.adapt(geom, GeometryProvider.class);
return provider;
}
return null;
Plant3D p3d = Plant3D.getInstance(graph);
Resource type = graph.getResource(typeURI);
- SolidModelProvider provider = getProvider(graph, type);
+ GeometryProvider provider = getProvider(graph, type);
if (provider != null || graph.hasStatement(type,p3d.NonVisibleComponent)) {
providers.put(typeURI, provider);
- ComponentUtils.clazzes.put(typeURI,getClazz(graph, type));
+ if (graph.isInheritedFrom(type, p3d.PipelineComponent))
+ clazzes.put(typeURI,getClazz(graph, type));
+ names.put(typeURI, NameUtils.getSafeName(graph, type));
return;
}
throw new DatabaseException("Cannot find component for " + typeURI);
});
}
+ /**
+ * Creates a component
+ *
+ * Does not set the name or add the component to a piperun.
+ * @param root
+ * @param typeURI
+ * @return
+ * @throws Exception
+ */
public static PipelineComponent createComponent(P3DRootNode root, String typeURI) throws Exception {
Class<? extends PipelineComponent> type = clazzes.get(typeURI);
- SolidModelProvider provider = providers.get(typeURI);
+ GeometryProvider provider = providers.get(typeURI);
if (type == null || provider == null) {
load(typeURI);
type = clazzes.get(typeURI);
return component;
}
+ /**
+ * Creates a equipment
+ *
+ * Does not set the name
+ *
+ * @param root
+ * @param typeURI
+ * @return
+ * @throws Exception
+ */
+
+ public static Equipment createEquipment(P3DRootNode root, String typeURI) throws Exception {
+ GeometryProvider provider = providers.get(typeURI);
+ if (provider == null) {
+ load(typeURI);
+ provider = providers.get(typeURI);
+ }
+ Equipment equipment = root.createEquipment();
+ equipment.setType(typeURI);
+ equipment.setGeometry(provider);
+ root.addChild(equipment);
+ return equipment;
+ }
+
public static InlineComponent createStraight(P3DRootNode root) throws Exception{
InlineComponent component = root.createInline();
component.setType(Plant3D.URIs.Builtin_Straight);
component.setType(Plant3D.URIs.Builtin_BranchSplitComponent);
return component;
}
+
+ public static Equipment createEquipment(P3DRootNode root, Item equipmentType) throws Exception {
+ Equipment equipment = createEquipment(root, equipmentType.getUri());
+ String n = root.getUniqueName(equipmentType.getName());
+ equipment.setName(n);
+ root.addChild(equipment);
+ return equipment;
+ }
+
+
+
+ public static Nozzle createDefaultNozzle(P3DRootNode root, Equipment equipment) throws Exception {
+ return createNozzle(root, equipment, new Item(Plant3D.URIs.Builtin_Nozzle, "Nozzle"));
+ }
+
+ public static Nozzle createNozzle(P3DRootNode root, Equipment equipment, Item nozzleType) throws Exception {
+ Nozzle nozzle = root.createNozzle();
+ nozzle.setType(nozzleType.getUri());
+ String n = root.getUniqueName(nozzleType.getName());
+ nozzle.setName(n);
+ PipeRun pipeRun = new PipeRun();
+ n = root.getUniqueName("PipeRun");
+ pipeRun.setName(n);
+ nozzle.setPipeRun(pipeRun);
+
+ equipment.addChild(nozzle);
+ root.addChild(pipeRun);
+ // root.getNodeMap().commit("Add nozzle " + n);
+ return nozzle;
+ }
+
+ public static class InsertInstruction {
+ public String typeUri;
+
+ public PositionType position = PositionType.NEXT;
+ public PositionType insertPosition = PositionType.NEXT;
+
+ // Reducer requires pipe specs
+ public Double diameter;
+ public Double turnRadius;
+
+ // Variable length
+ public Double length;
+
+ // Variable angle
+ public Double angle;
+
+ public String getTypeUri() {
+ return typeUri;
+ }
+
+ public void setTypeUri(String typeUri) {
+ this.typeUri = typeUri;
+ }
+
+ public PositionType getPosition() {
+ return position;
+ }
+
+ public void setPosition(PositionType position) {
+ this.position = position;
+ }
+
+ public PositionType getInsertPosition() {
+ return insertPosition;
+ }
+
+ public void setInsertPosition(PositionType insertPosition) {
+ this.insertPosition = insertPosition;
+ }
+
+ public Double getDiameter() {
+ return diameter;
+ }
+
+ public void setDiameter(Double diameter) {
+ this.diameter = diameter;
+ }
+
+ public Double getTurnRadius() {
+ return turnRadius;
+ }
+
+ public void setTurnRadius(Double turnRadius) {
+ this.turnRadius = turnRadius;
+ }
+
+ public Double getLength() {
+ return length;
+ }
+
+ public void setLength(Double length) {
+ this.length = length;
+ }
+
+ public Double getAngle() {
+ return angle;
+ }
+
+ public void setAngle(Double angle) {
+ this.angle = angle;
+ }
+
+ }
+
+ public static PipelineComponent addComponent(P3DRootNode root, PipelineComponent component, InsertInstruction inst) throws Exception {
+
+ PipelineComponent newComponent = ComponentUtils.createComponent(root, inst.typeUri);
+ PipeControlPoint newPcp = newComponent.getControlPoint();
+
+ PipeControlPoint toPcp = component.getControlPoint();
+ PipeRun pipeRun = toPcp.getPipeRun();
+
+ String typeName = names.get(inst.typeUri);
+ if (typeName == null)
+ typeName = "Component";
+
+ Vector3d dir = null;
+ Vector3d pos = null;
+
+ PositionType position = inst.position;
+ PositionType insertPosition = inst.insertPosition;
+ boolean lengthAdjustable = false;
+ if (newComponent instanceof InlineComponent) {
+ lengthAdjustable = ((InlineComponent)newComponent).isVariableLength();
+ }
+ boolean insertAdjustable = false;
+ if (component instanceof InlineComponent) {
+ insertAdjustable = ((InlineComponent)component).isVariableLength();
+ }
+ boolean sizeChange = false;
+ if (newComponent instanceof InlineComponent) {
+ sizeChange = ((InlineComponent)newComponent).isSizeChange();
+ }
+
+ if (toPcp.isInline()) {
+ switch (position) {
+ case NEXT:
+ if (toPcp.isDualInline())
+ toPcp = toPcp.getSubPoint().get(0);
+
+ break;
+ case PREVIOUS:
+ if (toPcp.isDualSub())
+ toPcp = toPcp.parent;
+ }
+ Vector3d start = new Vector3d();
+ Vector3d end = new Vector3d();
+ dir = new Vector3d();
+ toPcp.getInlineControlPointEnds(start, end, dir);
+ dir.normalize();
+ switch (position) {
+ case NEXT:
+ pos = new Vector3d(end);
+ break;
+ case PREVIOUS:
+ pos = new Vector3d(start);
+ break;
+ case SPLIT:
+ pos = new Vector3d(toPcp.getWorldPosition());
+ break;
+ }
+
+ } else if (toPcp.isDirected()) {
+ dir = new Vector3d(toPcp.getDirection(Direction.NEXT));
+ pos = new Vector3d(toPcp.getWorldPosition());
+ } else if (toPcp.isTurn() && toPcp.isFixed()) {
+ dir = new Vector3d(toPcp.getDirection(position == PositionType.NEXT ? Direction.NEXT : Direction.PREVIOUS));
+ pos = new Vector3d(toPcp.getWorldPosition());
+ if (!lengthAdjustable) {
+ Vector3d v = new Vector3d(dir);
+ v.scale(toPcp.getInlineLength());
+ pos.add(v);
+ } else {
+ if (insertPosition == PositionType.NEXT) {
+ Vector3d v = new Vector3d(dir);
+ v.scale(toPcp.getInlineLength());
+ pos.add(v);
+ } else if (insertPosition == PositionType.SPLIT) {
+ // scale 0.5*length so that we don't remove the length twice from the new component
+ Vector3d v = new Vector3d(dir);
+ v.scale(toPcp.getInlineLength()*0.5);
+ pos.add(v);
+ }
+ }
+ }
+
+
+ if (!sizeChange) {
+ String name = component.getPipeRun().getUniqueName(typeName);
+ newComponent.setName(name);
+
+ pipeRun.addChild(newComponent);
+ // TODO: these options are not stored into DB. Should they?!
+ if (newComponent instanceof InlineComponent && ((InlineComponent)newComponent).isVariableLength()) {
+ newPcp.setLength(inst.length);
+ } else if (newComponent instanceof TurnComponent && ((TurnComponent)newComponent).isVariableAngle()) {
+ newPcp.setTurnAngle(inst.angle);
+ }
+
+ newComponent.updateParameters();
+
+ Vector3d v = new Vector3d(dir);
+ if (insertAdjustable) {
+ if (insertPosition == PositionType.NEXT)
+ v.scale(newComponent.getControlPoint().getInlineLength());
+ else if (insertPosition == PositionType.SPLIT)
+ v.set(0, 0, 0);
+ else if (insertPosition == PositionType.PREVIOUS)
+ v.scale(-newComponent.getControlPoint().getInlineLength());
+ } else {
+ v.scale(newComponent.getControlPoint().getInlineLength());
+ }
+ switch (position) {
+ case NEXT:
+ pos.add(v);
+ break;
+ case PREVIOUS:
+ pos.sub(v);
+ break;
+ case SPLIT:
+ break;
+ }
+
+ switch (position) {
+ case NEXT:
+ if (toPcp.isDualInline())
+ toPcp = toPcp.getSubPoint().get(0);
+ newPcp.insert(toPcp, Direction.NEXT);
+ newPcp.setWorldPosition(pos);
+ break;
+ case PREVIOUS:
+ if (toPcp.isDualSub())
+ toPcp = toPcp.parent;
+ newPcp.insert(toPcp, Direction.PREVIOUS);
+ newPcp.setWorldPosition(pos);
+ break;
+ case SPLIT:
+ PipingRules.splitVariableLengthComponent(newComponent, (InlineComponent)component, true);
+ }
+ } else {
+ PipeRun other = new PipeRun();
+ String n = root.getUniqueName("PipeRun");
+ other.setName(n);
+ other.setPipeDiameter(inst.diameter);
+ other.setTurnRadius(inst.turnRadius);
+ root.addChild(other);
+
+
+ if (position == PositionType.NEXT) {
+ PipingRules.addSizeChange(false, pipeRun, other, (InlineComponent)newComponent, toPcp, null);
+ } else if (position == PositionType.PREVIOUS){
+ PipingRules.addSizeChange(true, pipeRun, other, (InlineComponent)newComponent, toPcp, null);
+ }
+ newPcp.setWorldPosition(pos);
+ // TODO : chicken-egg problem
+ newComponent.updateParameters();
+ Vector3d v = new Vector3d(dir);
+ v.scale(newComponent.getControlPoint().getLength()*0.5);
+ switch (position) {
+ case NEXT:
+ pos.add(v);
+ break;
+ case PREVIOUS:
+ pos.sub(v);
+ break;
+ case SPLIT:
+ break;
+ }
+ newPcp.setWorldPosition(pos);
+
+ }
+
+
+ return newComponent;
+ }
}