]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java
Add a wall thickness property to pipe runs.
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / utils / ComponentUtils.java
index 4e3571444ae3bf759436fe01054330cf586b197b..6bbabe1e251c9feaf3f10e1767a56ce827ec91f0 100644 (file)
@@ -1,14 +1,17 @@
 package org.simantics.plant3d.utils;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 import javax.vecmath.Vector3d;
 
 import org.simantics.Simantics;
 import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
 import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.common.utils.NameUtils;
@@ -30,34 +33,41 @@ import org.simantics.plant3d.scenegraph.TurnComponent;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Direction;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
 
 public class ComponentUtils {
 
+       private final static Logger LOGGER = LoggerFactory.getLogger(ComponentUtils.class);
        
        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() {
-                       
-                       @Override
-                       public void run(ReadGraph graph) throws DatabaseException {
-                               List<String> types = new ArrayList<String>();
-                               types.add(Plant3D.URIs.Builtin_Straight);
-                               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_Elbow45);
-                               types.add(Plant3D.URIs.Builtin_Elbow90);
+       public static void preloadCache(RequestProcessor session) {
+               try {
+                       session.syncRequest(new ReadRequest() {
                                
-                               for (String typeURI : types) {
-                                       load(graph, typeURI);
+                               @Override
+                               public void run(ReadGraph graph) throws DatabaseException {
+                                       List<String> types = new ArrayList<String>();
+                                       types.add(Plant3D.URIs.Builtin_Straight);
+                                       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_Elbow45);
+                                       types.add(Plant3D.URIs.Builtin_Elbow90);
+                                       
+                                       for (String typeURI : types) {
+                                               load(graph, typeURI);
+                                       }
                                }
-                       }
-               });
+                       });
+               } catch (DatabaseException e) {
+                       LOGGER.error("ComponentUtils.preloadCache() failed unexpectedly", e);
+               }
        }
        
        private static GeometryProvider getProvider(ReadGraph graph, Resource type) throws DatabaseException {
@@ -180,6 +190,25 @@ public class ComponentUtils {
                return equipment;
        }
        
+       public static Equipment createEquipmentWithNozzles(P3DRootNode root, String typeURI, String nozzleTypeUri) 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);
+        
+        for (int i = 0; i < equipment.numberOfFixedNozzles(); i++) {
+            createNozzle(root, equipment, new Item(nozzleTypeUri, "Nozzle"));
+            
+        }
+        
+        return equipment;
+    }
+       
        public static InlineComponent createStraight(P3DRootNode root) throws Exception{
                InlineComponent component = root.createInline();
                component.setType(Plant3D.URIs.Builtin_Straight);
@@ -214,7 +243,12 @@ public class ComponentUtils {
                return equipment;
        }
        
-       
+       public static Equipment createEquipmentWithNozzles(P3DRootNode root, Item equipmentType, Item nozzleType) throws Exception {
+        Equipment equipment = createEquipmentWithNozzles(root, equipmentType.getUri(), nozzleType.getUri());
+        String n = root.getUniqueName(equipmentType.getName());
+        equipment.setName(n);
+        return equipment;
+    }
        
        public static Nozzle createDefaultNozzle(P3DRootNode root, Equipment equipment) throws Exception {
                return createNozzle(root, equipment, new Item(Plant3D.URIs.Builtin_Nozzle, "Nozzle"));
@@ -241,9 +275,13 @@ public class ComponentUtils {
                
                public PositionType position = PositionType.NEXT;
                public PositionType insertPosition = PositionType.NEXT;
+
+               // Component name
+               public String name;
                
                // Reducer requires pipe specs
                public Double diameter;
+               public Double thickness;
                public Double turnRadius;
                
                // Variable length 
@@ -251,6 +289,9 @@ public class ComponentUtils {
                
                // Variable angle
                public Double angle;
+               
+               // Rotation angle used with turns and rotated inline.
+               public Double rotationAngle;
 
                public String getTypeUri() {
                        return typeUri;
@@ -276,6 +317,14 @@ public class ComponentUtils {
                        this.insertPosition = insertPosition;
                }
 
+               public String getName() {
+                       return name;
+               }
+
+               public void setName(String name) {
+                       this.name = name;
+               }
+
                public Double getDiameter() {
                        return diameter;
                }
@@ -283,6 +332,14 @@ public class ComponentUtils {
                public void setDiameter(Double diameter) {
                        this.diameter = diameter;
                }
+               
+               public double getThickness() {
+                       return thickness;
+               }
+               
+               public void setThickness(double thickness) {
+                       this.thickness = thickness;
+               }
 
                public Double getTurnRadius() {
                        return turnRadius;
@@ -307,12 +364,23 @@ public class ComponentUtils {
                public void setAngle(Double angle) {
                        this.angle = angle;
                }
+               
+               public Double getRotationAngle() {
+            return rotationAngle;
+        }
+               
+               public void setRotationAngle(Double rotationAngle) {
+            this.rotationAngle = rotationAngle;
+        }
 
        }
        
        public static PipelineComponent addComponent(P3DRootNode root, PipelineComponent component,  InsertInstruction inst) throws Exception {
                
                PipelineComponent newComponent = ComponentUtils.createComponent(root, inst.typeUri);
+               if (inst.name != null)
+                       newComponent.setName(inst.name);
+               
                PipeControlPoint newPcp = newComponent.getControlPoint();
                
                PipeControlPoint toPcp = component.getControlPoint();
@@ -329,7 +397,7 @@ public class ComponentUtils {
                PositionType insertPosition = inst.insertPosition;
                boolean lengthAdjustable = false;
                if (newComponent instanceof InlineComponent) {
-                       lengthAdjustable = ((InlineComponent)newComponent).isVariableLength(); 
+                       lengthAdjustable = ((InlineComponent)newComponent).isVariableLength() || ((InlineComponent)newComponent).isModifialble()
                }
                boolean insertAdjustable = false;
                if (component instanceof InlineComponent) {
@@ -344,7 +412,7 @@ public class ComponentUtils {
                        switch (position) {
                        case NEXT: 
                                if (toPcp.isDualInline()) {
-                                       toPcp = toPcp.getSubPoint().get(0);
+                                       toPcp = toPcp.getDualSub();
                                        pipeRun = toPcp.getPipeRun();
                                }
                                
@@ -401,101 +469,112 @@ public class ComponentUtils {
                        }
                }
                
-               
-               if (!sizeChange) {
-                       String name = component.getPipeRun().getUniqueName(typeName);
-                       newComponent.setName(name);
+               String name = component.getPipeRun().getUniqueName(typeName);
+               newComponent.setName(name);
+
+               pipeRun.addChild(newComponent);
+               if (newPcp.isSizeChange())
+                       newComponent.setAlternativePipeRun(pipeRun);
 
-                       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()) {
+               if (newComponent instanceof InlineComponent) {
+                   InlineComponent inlineComponent = (InlineComponent)newComponent;
+                   if (inlineComponent.isVariableLength()|| inlineComponent.isModifialble()) {
+                       newPcp.setLength(inst.length);
+                       newComponent.setParameter("length", inst.length);
+                   }
+                   if (inst.rotationAngle != null)
+                       ((InlineComponent) newComponent).setRotationAngle(inst.rotationAngle);
+               } else if (newComponent instanceof TurnComponent) {
+                   TurnComponent turnComponent = (TurnComponent)newComponent;
+                   if  (turnComponent.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 {
+                               newComponent.setParameter("turnAngle", inst.angle);
+                   }
+                   if (inst.rotationAngle != null)
+                ((TurnComponent) newComponent).setRotationAngle(inst.rotationAngle);
+               }
+               
+               
+               newComponent.updateParameters();
+               
+               Vector3d v = new Vector3d(dir);
+               if (insertAdjustable) {
+                       if (insertPosition == PositionType.NEXT)
                                v.scale(newComponent.getControlPoint().getInlineLength());
-                       }
-                       switch (position) {
-                       case NEXT:
-                               pos.add(v);
-                               break;
-                       case PREVIOUS:
-                               pos.sub(v);
-                               break;
-                       case SPLIT:
-                               break;
-                       default:
-                               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);
-                       default:
-                               break;
-                       }
+                       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;
+               default:
+                       break;
+               }
+               
+               switch (position) {
+               case NEXT: 
+                       if (toPcp.isDualInline())
+                               toPcp = toPcp.getDualSub();
+                       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);
+               default:
+                       break;
+               }
+               
+               // Move the size change and the rest of the components in the pipe run to a new pipe run
+               if (sizeChange) {
                        PipeRun other = new PipeRun();
                        String n = root.getUniqueName("PipeRun");
                        other.setName(n);
                        other.setPipeDiameter(inst.diameter);
+                       other.setPipeThickness(inst.thickness);
                        other.setTurnRadius(inst.turnRadius);
                        root.addChild(other);
                        
+                       other.addChild(newComponent.getControlPoint().getDualSub());
+                       newComponent.setAlternativePipeRun(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;
-                       default:
-                               break;
+                       boolean forward = position != PositionType.PREVIOUS;
+                       PipelineComponent comp = forward ? newComponent.getNext() : newComponent.getPrevious();
+                       while (comp != null && comp.getPipeRun() == pipeRun) {
+                               if (comp.getParent() == pipeRun) {
+                                       comp.deattach();
+                                       other.addChild(comp);
+                               } else {
+                                       comp.setPipeRun(other);
+                               }
+                               
+                               // Reset parameters to match new pipe run
+                               comp.updateParameters();
+                               
+                               comp = forward ? comp.getNext() : comp.getPrevious();
                        }
-                       newPcp.setWorldPosition(pos);
                        
+                       newComponent.updateParameters();
                }
-                               
                
                return newComponent;
        }
+       
        public static boolean connect(PipelineComponent current, PipelineComponent endTo) throws Exception {
                return connect(current, endTo, null, null);
        }
@@ -538,7 +617,7 @@ public class ComponentUtils {
                                requiresReverse = true;
                        }
                        PipeRun other = endCP.getPipeRun();
-                       boolean mergeRuns = other == null ? true : pipeRun.equalSpecs(other);
+                       boolean mergeRuns = other == null ? true : pipeRun.canMerge(other);
                        
                        if (requiresReverse) {
                                // Pipe line must be traversible with next/previous relations without direction change.
@@ -546,10 +625,11 @@ public class ComponentUtils {
                                PipingRules.reverse(other);
                                
                        }
+
                        if (mergeRuns) {
                                // Runs have compatible specs and must be merged
                                if (other != null && pipeRun != other)
-                                       PipingRules.merge(pipeRun, other);
+                                       pipeRun.merge(other);
                                else if (other == null) {
                                        if (!(endTo instanceof Nozzle)) {
                                                pipeRun.addChild(endTo);
@@ -646,4 +726,14 @@ public class ComponentUtils {
                PipingRules.splitVariableLengthComponent(branchSplit, component, false);
                return branchSplit;
        }
+
+       public static Collection<String> getPipelineComponentNames(P3DRootNode root) {
+               Collection<String> usedNames = root.getChild().stream()
+                               .filter(n -> n instanceof PipeRun)
+                               .flatMap(n -> ((PipeRun)n).getChild().stream())
+                               .filter(n -> n instanceof PipelineComponent)
+                               .map(n -> ((PipelineComponent)n).getName())
+                               .collect(Collectors.toSet());
+               return usedNames;
+       }
 }