X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.plant3d%2Fsrc%2Forg%2Fsimantics%2Fplant3d%2Futils%2FComponentUtils.java;h=ea9f492f6b96e8144215cff483399e6ee7d9af32;hb=1c22d60d859f73fe6320ff1ed1cc6f753752d97a;hp=fb065f111f98b84c9d7ebf4ee27cb85ac4517190;hpb=a1e1faa6915445e786f482170576b9c9d0f5d982;p=simantics%2F3d.git diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java b/org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java index fb065f11..ea9f492f 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/utils/ComponentUtils.java @@ -1,15 +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.Point3d; 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; @@ -31,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> clazzes = new HashMap>(); private static Map providers = new HashMap(); private static Map names = new HashMap(); - public static void preloadCache() { - Simantics.getSession().asyncRequest(new ReadRequest() { - - @Override - public void run(ReadGraph graph) throws DatabaseException { - List types = new ArrayList(); - 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 types = new ArrayList(); + 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 { @@ -181,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); @@ -215,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")); @@ -242,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 @@ -252,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; @@ -277,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; } @@ -284,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; @@ -308,6 +364,14 @@ public class ComponentUtils { public void setAngle(Double angle) { this.angle = angle; } + + public Double getRotationAngle() { + return rotationAngle; + } + + public void setRotationAngle(Double rotationAngle) { + this.rotationAngle = rotationAngle; + } } @@ -330,7 +394,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) { @@ -341,11 +405,13 @@ public class ComponentUtils { sizeChange = ((InlineComponent)newComponent).isSizeChange(); } + // Calculate component position and direction vectors + // 'dir' is a unit vector that represents the direction from 'component' to 'newComponent' if (toPcp.isInline()) { switch (position) { case NEXT: if (toPcp.isDualInline()) { - toPcp = toPcp.getSubPoint().get(0); + toPcp = toPcp.getDualSub(); pipeRun = toPcp.getPipeRun(); } @@ -356,26 +422,30 @@ public class ComponentUtils { pipeRun = toPcp.getPipeRun(); } break; + default: + break; } Vector3d start = new Vector3d(); Vector3d end = new Vector3d(); - dir = new Vector3d(); - toPcp.getInlineControlPointEnds(start, end, dir); - dir.normalize(); + dir = toPcp.getInlineDir(); + toPcp.getControlPointEnds(start, end); switch (position) { case NEXT: pos = new Vector3d(end); break; case PREVIOUS: pos = new Vector3d(start); + dir.negate(); break; case SPLIT: pos = new Vector3d(toPcp.getWorldPosition()); break; + default: + break; } - } else if (toPcp.isDirected()) { - dir = new Vector3d(toPcp.getDirection(Direction.NEXT)); + // 'dir' always points out of a nozzle regardless of insertion direction + dir = new Vector3d(toPcp.getDirectedControlPointDirection()); pos = new Vector3d(toPcp.getWorldPosition()); } else if (toPcp.isTurn() && toPcp.asFixedAngle()) { dir = new Vector3d(toPcp.getDirection(position == PositionType.NEXT ? Direction.NEXT : Direction.PREVIOUS)); @@ -398,95 +468,125 @@ public class ComponentUtils { } } - - if (!sizeChange) { + if (inst.name != null) { + newComponent.setName(inst.name); + } else { 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(); + pipeRun.addChild(newComponent); + if (newPcp.isSizeChange()) + newComponent.setAlternativePipeRun(pipeRun); + + 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(Math.toRadians(inst.angle)); + newComponent.setParameter("turnAngle", inst.angle); + } + if (inst.rotationAngle != null) + ((TurnComponent) newComponent).setRotationAngle(inst.rotationAngle); + } + + newComponent.updateParameters(); + + Vector3d v = new Vector3d(dir); + if (insertAdjustable) { + // Prevent moving of adjacent components - always insert at end of a connected variable length component + if (position == PositionType.NEXT && component.getNext() != null || + position == PositionType.PREVIOUS && component.getPrevious() != null) + insertPosition = PositionType.PREVIOUS; - 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 { + 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; - } - - switch (position) { - case NEXT: - if (toPcp.isDualInline()) - toPcp = toPcp.getSubPoint().get(0); + 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: + case PREVIOUS: + pos.add(v); + break; + case SPLIT: + break; + default: + break; + } + + switch (position) { + case NEXT: + if (toPcp.isDualInline()) + toPcp = toPcp.getDualSub(); + newPcp.setWorldPosition(pos); + if (toPcp.getNext() != null) + PipingRules.splitVariableLengthComponent(newComponent, (InlineComponent)component, false); + else newPcp.insert(toPcp, Direction.NEXT); - newPcp.setWorldPosition(pos); - break; - case PREVIOUS: - if (toPcp.isDualSub()) - toPcp = toPcp.parent; + break; + case PREVIOUS: + if (toPcp.isDualSub()) + toPcp = toPcp.parent; + newPcp.setWorldPosition(pos); + if (toPcp.getPrevious() != null) + PipingRules.splitVariableLengthComponent(newComponent, (InlineComponent)component, false); + else newPcp.insert(toPcp, Direction.PREVIOUS); - newPcp.setWorldPosition(pos); - break; - case SPLIT: - PipingRules.splitVariableLengthComponent(newComponent, (InlineComponent)component, true); - } - } else { + 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; + 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); } @@ -529,7 +629,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. @@ -537,10 +637,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); @@ -559,7 +660,6 @@ public class ComponentUtils { // Runs do not have compatible specs, and a reducer must be attached in between. InlineComponent reducer = ComponentUtils.createReducer(root); PipeControlPoint pcp = reducer.getControlPoint(); - PipeControlPoint ocp = pcp.getSubPoint().get(0); Vector3d endPos = endCP.getWorldPosition(); Vector3d currentPos = currentCP.getWorldPosition(); @@ -638,4 +738,14 @@ public class ComponentUtils { PipingRules.splitVariableLengthComponent(branchSplit, component, false); return branchSplit; } + + public static Collection getPipelineComponentNames(P3DRootNode root) { + Collection 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; + } }