package org.simantics.plant3d.scenegraph; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.vecmath.Quat4d; import javax.vecmath.Vector3d; import org.simantics.g3d.math.MathTools; import org.simantics.g3d.property.annotations.CompoundGetPropertyValue; import org.simantics.g3d.property.annotations.CompoundSetPropertyValue; import org.simantics.g3d.scenegraph.GeometryProvider; import org.simantics.objmap.graph.annotations.CompoundRelatedGetValue; import org.simantics.objmap.graph.annotations.CompoundRelatedSetValue; import org.simantics.objmap.graph.annotations.DynamicGraphType; import org.simantics.objmap.graph.annotations.GetType; import org.simantics.objmap.graph.annotations.RelatedElementsAdd; import org.simantics.objmap.graph.annotations.RelatedElementsGet; import org.simantics.objmap.graph.annotations.RelatedElementsRem; import org.simantics.objmap.graph.annotations.SetType; import org.simantics.plant3d.geometry.FixedNozzleProvider; import org.simantics.plant3d.ontology.Plant3D; import org.simantics.plant3d.scenegraph.controlpoint.PipingRules; @DynamicGraphType(Plant3D.URIs.Equipment) public class Equipment extends P3DParentGeometryNode { private String type; private FixedNozzleProvider fnp; @GetType(Plant3D.URIs.Equipment) public String getType() { return type; } @SetType(Plant3D.URIs.Equipment) public void setType(String type) { this.type = type; } @RelatedElementsAdd(Plant3D.URIs.HasNozzle) public void addChild(Nozzle node) { Collection children = getChild(); if (numberOfFixedNozzles() > 0 && children.size() >= numberOfFixedNozzles()) throw new RuntimeException("Equipment has already all fixed nozzles"); Set ids = new HashSet(); for (Nozzle n : children) { ids.add(n.getNozzleId()); } int newId = 0; while (ids.contains(newId)) newId++; addNode(Plant3D.URIs.HasNozzle,node); node.setNozzleId(newId); if (fnp != null) syncNozzles(); } @RelatedElementsGet(Plant3D.URIs.HasNozzle) public Collection getChild() { return getNodes(Plant3D.URIs.HasNozzle); } @RelatedElementsRem(Plant3D.URIs.HasNozzle) public void remChild(Nozzle node) { removeNode(Plant3D.URIs.HasNozzle, node); } @Override @CompoundRelatedGetValue(objRelation=Plant3D.URIs.hasParameter,objType=Plant3D.URIs.Parameter,valRelation=Plant3D.URIs.hasParameterValue) @CompoundGetPropertyValue(name="Parameters",tabId="Parameters",value="parameters") public Map getParameterMap() { return super.getParameterMap(); } @Override @CompoundRelatedSetValue(Plant3D.URIs.hasParameter) @CompoundSetPropertyValue(value="parameters") public void setParameterMap(Map parameters) { super.setParameterMap(parameters); syncNozzles(); } @Override public void setGeometry(GeometryProvider provider) { super.setGeometry(provider); if (provider instanceof FixedNozzleProvider) { fnp = (FixedNozzleProvider)provider; syncNozzles(); } } public int numberOfFixedNozzles() { if (fnp == null) return 0; return fnp.numberOfNozzles(); } /** * Synchronizes fixed nozzles. * * Note: this method does not create nozzles, just sets their positions and names. */ public void syncNozzles() { if (fnp == null) return; updateParameters(); int count = fnp.numberOfNozzles(); List currentNozzles = getNodes(); for (int i = 0; i < count; i++) { if (i < currentNozzles.size()) { Nozzle nozzle = currentNozzles.get(i); nozzle.setName(fnp.getNozzleName(i)); fnp.updateNozzlePosition(i, nozzle); nozzle.setFixed(true); } } } @Override protected double[] getColor() { return new double[]{1,0,0}; } @Override protected double[] getSelectedColor() { return new double[]{0.5,0,0.5}; } @Override public void setPosition(Vector3d position) { if (MathTools.equals(position, getPosition())) return; super.setPosition(position); for (Nozzle n : getChild()) { n.getControlPoint()._setWorldPosition(n.getWorldPosition()); n.getControlPoint()._setWorldOrientation(n.getWorldOrientation()); } for (Nozzle n : getChild()) { try { PipingRules.requestUpdate(n.getControlPoint()); } catch (Exception e) { e.printStackTrace(); } } } @Override public void setOrientation(Quat4d orientation) { if (MathTools.equals(orientation, getOrientation())) return; super.setOrientation(orientation); for (Nozzle n : getChild()) { n.getControlPoint()._setWorldPosition(n.getWorldPosition()); n.getControlPoint()._setWorldOrientation(n.getWorldOrientation()); } for (Nozzle n : getChild()) { try { PipingRules.requestUpdate(n.getControlPoint()); } catch (Exception e) { e.printStackTrace(); } } } }