package org.simantics.processeditor.adapters; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.simantics.db.Graph; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.layer0.utils.EntityFactory; import org.simantics.layer0.utils.IEntity; import org.simantics.layer0.utils.Property; import org.simantics.processeditor.ProcessResource; import org.simantics.processeditor.common.ControlPointTools; import org.simantics.processeditor.common.PipingRules; import org.simantics.processeditor.scenegraph.NonVisibleNode; import org.simantics.processeditor.scenegraph.PipeComponentNode; import org.simantics.processeditor.scenegraph.PipeRunNode; import org.simantics.processeditor.scenegraph.PipelineComponentNode; import org.simantics.processeditor.stubs.PipeControlPoint; import org.simantics.processeditor.stubs.PipeRun; import org.simantics.processeditor.stubs.Plant3DResource; import org.simantics.proconf.g3d.base.JmeRenderingComponent; import org.simantics.proconf.g3d.base.ScenegraphAdapterImpl; import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase; import org.simantics.proconf.g3d.scenegraph.IGeometryNode; import org.simantics.proconf.g3d.scenegraph.IGraphicsNode; import org.simantics.proconf.g3d.scenegraph.ISelectableNode; import org.simantics.proconf.g3d.scenegraph.ParameterizedModelNode; import org.simantics.proconf.g3d.stubs.G3DNode; import org.simantics.utils.ui.ErrorLogger; public class ProcessEditorAdapter extends ScenegraphAdapterImpl { private ThreeDimensionalEditorBase editor; public ProcessEditorAdapter(ThreeDimensionalEditorBase editor, Session session, JmeRenderingComponent component) { super(session, component); this.editor = editor; } private class NormalScenegraphQuery extends ScenegraphQuery { public NormalScenegraphQuery(Resource node) { super(node); } @Override public void shapeAdded(Graph graph, IGraphicsNode node) { // FIXME : this won't work like in previous ProConf } } private Map pipeRunQueries = new HashMap(); protected ScenegraphQuery newSubnodeListener(G3DNode node) { if (node.isInstanceOf(ProcessResource.plant3Dresource.PipeRun)) { PipeRunControlPointQuery query = new PipeRunControlPointQuery(node.getResource()); pipeRunQueries.put(node.getResource(), query); node.getGraph().performQuery(query); } return new NormalScenegraphQuery(node.getResource()); } @Override protected NodePropertyQuery newRootPropertyListener(G3DNode root) { // currently Plant does not have any properties. return null; } private class TransformationQuery extends NodeTransformationQuery { public TransformationQuery(Resource res) { super(res); } @Override public void shapeUpdated(Graph graph, IGraphicsNode shape) { //if (shape instanceof IGeometryNode) { // updateGeometry((IGeometryNode)shape); //} else { shape.updateTransform(graph); //} } } @Override protected NodeTransformationQuery newTransformationListener(G3DNode root) { return new TransformationQuery(root.getResource()); } private class NormalNodePropertyQuery extends org.simantics.proconf.g3d.base.ScenegraphAdapterImpl.NodePropertyQuery { public NormalNodePropertyQuery(Resource resource) { super(resource); } @Override public void shapeUpdated(Graph graph,IGraphicsNode shape) { if (shape instanceof IGeometryNode) { updateGeometry((IGeometryNode)shape); } else { shape.updateTransform(graph); } } } @Override protected NodePropertyQuery newPropertyListener(G3DNode node) { return new NormalNodePropertyQuery(node.getResource()); } @Override protected IGraphicsNode instantiateNode(IGraphicsNode parent, G3DNode node) { Plant3DResource p3r = ProcessResource.plant3Dresource; IGraphicsNode newNode = null; try { if (node.isInstanceOf(p3r.Equipment)) { newNode = new ParameterizedModelNode( editor, parent, node.getGraph(), node.getResource(), p3r.HasGraphics); } else if (node.isInstanceOf(p3r.PipeRun)) { newNode = new PipeRunNode(parent, node.getGraph(), node.getResource()); } else if (node.isInstanceOf(p3r.Nozzle)) { newNode = new ParameterizedModelNode( editor, parent, node.getGraph(), node.getResource(), p3r.HasGraphics); // CodedComponent must be handled first since it uses // hard-coded geometries // TODO : is this really necessary, or could we unify // PipeComponentNode, InlineComponentNode,... } else if (node.isInstanceOf(p3r.CodedComponent)) { newNode = new PipeComponentNode(editor, parent, node.getGraph(), node.getResource()); } else if (node.isInstanceOf(p3r.NonVisibleComponent)) { newNode = new NonVisibleNode(parent, node.getGraph(), node.getResource()); } else if (node.isInstanceOf(p3r.PipelineComponent)) { newNode = new PipelineComponentNode(editor, parent, node.getGraph(), node.getResource()); } // } else if (node instanceof Shape) // Markers (ar/mobile) // needed this // newNode = new ShapeNode(TestProcessEditor.this,parent,node); if (newNode != null) { if (newNode instanceof ISelectableNode) ((ISelectableNode) newNode).setVisible(true); if (newNode instanceof IGeometryNode) { updateGeometry((IGeometryNode) newNode); } return newNode; } } catch (Exception e) { ErrorLogger.defaultLogError("Cannot handle node " + node.getResource(), e); return null; } ErrorLogger.defaultLogError("Cannot handle node " + node.getResource(), null); return null; } /** * This is used to create elbows and straight pipes to pipeline TODO : * this should be done with rule-engine! * * * @author Marko Luukkainen * */ protected class PipeRunControlPointQuery extends NodeQuery { private List removed = new ArrayList(); private List added = new ArrayList(); public PipeRunControlPointQuery(Resource r) { super(r); if (DEBUG) System.out.println("Created PipeRunControlPointQuery for " + r); } @Override protected Object compute2(Graph graph) { PipeRun run = new PipeRun(graph, nodeResource); Collection cps = run .getRelatedObjects(ProcessResource.plant3Dresource.HasControlPoints); List res = new ArrayList(); for (IEntity t : cps) res.add(t.getResource()); return res; } @Override public boolean updated(Graph graph, Object oldResult, Object newResult) { removed.clear(); added.clear(); List oldCps = (List) oldResult; List newCps = (List) newResult; if (oldCps == null) oldCps = new ArrayList(); for (Resource r : oldCps) { if (!newCps.contains(r)) removed.add(r); } for (Resource r : newCps) { if (!oldCps.contains(r)) added.add(r); } for (Resource r : removed) removeControlPoint(graph, r); for (Resource r : added) { addControlPoint(graph, r); // ControlPointTools.addControlPoint(new // PipeRun(graph,pipeRun), new PipeControlPoint(graph, r)); } return (added.size() > 0 || removed.size() > 0); } @Override public void dispose() { super.dispose(); for (ControlPointPropertyQuery q : controlPointPropertyQueries.values()) q.dispose(); controlPointPropertyQueries.clear(); } private Map controlPointPropertyQueries = new HashMap(); private void addControlPoint(Graph graph, Resource resource) { ControlPointPropertyQuery query = new ControlPointPropertyQuery(resource); graph.performQuery(query); controlPointPropertyQueries.put(resource,query); } private void removeControlPoint(Graph graph, Resource resource) { ControlPointPropertyQuery query = controlPointPropertyQueries.remove(resource); query.dispose(); ControlPointTools.removeControlPoint(new PipeControlPoint( graph, resource)); } } protected class ControlPointPropertyQuery extends NodeQuery { boolean initialized = false; public ControlPointPropertyQuery(Resource r) { super(r); if (DEBUG) System.out.println("Created ControlPointPropertyQuery for " + r); } @Override public List compute2(Graph g) { IEntity t = EntityFactory.create(g,nodeResource); Collection properties = t.getRelatedProperties(ProcessResource.builtins.HasProperty); List propertyValues = new ArrayList(); p(properties,propertyValues); return propertyValues; } private void p(Collection properties, List propertyValues) { for (Property p : properties) { Collection subProperties = p.getRelatedProperties(p.getGraph().getBuiltins().HasProperty); if (subProperties.size() != 0) { p(subProperties,propertyValues); } if (p.hasValue()){ propertyValues.add(p.getValue()); } } } @Override public boolean updated(Graph graph, Object oldResult, Object newResult) { PipingRules.pipeControlPointPositionUpdate(graph, this.nodeResource); if (initialized) { //PipingRules.pipeControlPointPositionUpdate(graph, this.nodeResource); } else { initialized = true; } return true; } } @Override protected void removeNode(Resource parent, Resource r) { super.removeNode(parent, r); PipeRunControlPointQuery q = pipeRunQueries.get(r); if (q != null) q.dispose(); } @Override public void dispose() { super.dispose(); } }