]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java
Very crude API for creating pipeline components
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / utils / ComponentUtils.java
index 2644ab0f33003ba9580c6d1b26ad9b9cfb75734d..4a4888090aff7a0dd08756d35b6ba8e4607bdd02 100644 (file)
@@ -5,26 +5,38 @@ import java.util.HashMap;
 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.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,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() {
@@ -85,7 +97,9 @@ public class ComponentUtils {
                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);
@@ -101,6 +115,15 @@ public class ComponentUtils {
                });
        }
        
+       /**
+        * 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);
                GeometryProvider provider = providers.get(typeURI);
@@ -125,6 +148,30 @@ public class ComponentUtils {
                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);
@@ -151,4 +198,280 @@ public class ComponentUtils {
                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;
+       }
 }