1 /*******************************************************************************
\r
2 * Copyright (c) 2007- VTT Technical Research Centre of Finland.
\r
3 * All rights reserved. This program and the accompanying materials
\r
4 * are made available under the terms of the Eclipse Public License v1.0
\r
5 * which accompanies this distribution, and is available at
\r
6 * http://www.eclipse.org/legal/epl-v10.html
\r
9 * VTT Technical Research Centre of Finland - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package org.simantics.processeditor.adapters;
\r
13 import java.util.ArrayList;
\r
14 import java.util.Collection;
\r
15 import java.util.HashMap;
\r
16 import java.util.List;
\r
17 import java.util.Map;
\r
19 import org.simantics.db.Graph;
\r
20 import org.simantics.db.Resource;
\r
21 import org.simantics.db.Session;
\r
22 import org.simantics.layer0.utils.EntityFactory;
\r
23 import org.simantics.layer0.utils.IEntity;
\r
24 import org.simantics.layer0.utils.Property;
\r
25 import org.simantics.processeditor.ProcessResource;
\r
26 import org.simantics.processeditor.common.ControlPointTools;
\r
27 import org.simantics.processeditor.common.PipingRules;
\r
28 import org.simantics.processeditor.scenegraph.NonVisibleNode;
\r
29 import org.simantics.processeditor.scenegraph.PipeComponentNode;
\r
30 import org.simantics.processeditor.scenegraph.PipeRunNode;
\r
31 import org.simantics.processeditor.scenegraph.PipelineComponentNode;
\r
32 import org.simantics.processeditor.stubs.PipeControlPoint;
\r
33 import org.simantics.processeditor.stubs.PipeRun;
\r
34 import org.simantics.processeditor.stubs.Plant3DResource;
\r
35 import org.simantics.proconf.g3d.base.JmeRenderingComponent;
\r
36 import org.simantics.proconf.g3d.base.ScenegraphAdapterImpl;
\r
37 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;
\r
38 import org.simantics.proconf.g3d.scenegraph.IGeometryNode;
\r
39 import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;
\r
40 import org.simantics.proconf.g3d.scenegraph.ISelectableNode;
\r
41 import org.simantics.proconf.g3d.scenegraph.ParameterizedModelNode;
\r
42 import org.simantics.proconf.g3d.stubs.G3DNode;
\r
43 import org.simantics.utils.ui.ErrorLogger;
\r
45 public class ProcessEditorAdapter extends ScenegraphAdapterImpl {
\r
46 private ThreeDimensionalEditorBase editor;
\r
48 public ProcessEditorAdapter(ThreeDimensionalEditorBase editor, Session session, JmeRenderingComponent component) {
\r
49 super(session, component);
\r
50 this.editor = editor;
\r
53 private class NormalScenegraphQuery extends ScenegraphQuery {
\r
55 public NormalScenegraphQuery(Resource node) {
\r
61 public void shapeAdded(Graph graph, IGraphicsNode node) {
\r
62 // FIXME : this won't work like in previous ProConf
\r
66 private Map<Resource,PipeRunControlPointQuery> pipeRunQueries = new HashMap<Resource, PipeRunControlPointQuery>();
\r
68 protected ScenegraphQuery newSubnodeListener(G3DNode node) {
\r
69 if (node.isInstanceOf(ProcessResource.plant3Dresource.PipeRun)) {
\r
70 PipeRunControlPointQuery query = new PipeRunControlPointQuery(node.getResource());
\r
71 pipeRunQueries.put(node.getResource(), query);
\r
72 node.getGraph().performQuery(query);
\r
74 return new NormalScenegraphQuery(node.getResource());
\r
79 protected NodePropertyQuery newRootPropertyListener(G3DNode root) {
\r
80 // currently Plant does not have any properties.
\r
84 private class TransformationQuery extends NodeTransformationQuery {
\r
86 public TransformationQuery(Resource res) {
\r
91 public void shapeUpdated(Graph graph, IGraphicsNode shape) {
\r
92 //if (shape instanceof IGeometryNode) {
\r
93 // updateGeometry((IGeometryNode)shape);
\r
95 shape.updateTransform(graph);
\r
101 protected NodeTransformationQuery newTransformationListener(G3DNode root) {
\r
102 return new TransformationQuery(root.getResource());
\r
105 private class NormalNodePropertyQuery extends org.simantics.proconf.g3d.base.ScenegraphAdapterImpl.NodePropertyQuery {
\r
107 public NormalNodePropertyQuery(Resource resource) {
\r
112 public void shapeUpdated(Graph graph,IGraphicsNode shape) {
\r
113 if (shape instanceof IGeometryNode) {
\r
114 updateGeometry((IGeometryNode)shape);
\r
116 shape.updateTransform(graph);
\r
121 protected NodePropertyQuery newPropertyListener(G3DNode node) {
\r
122 return new NormalNodePropertyQuery(node.getResource());
\r
126 protected IGraphicsNode instantiateNode(IGraphicsNode parent,
\r
128 Plant3DResource p3r = ProcessResource.plant3Dresource;
\r
129 IGraphicsNode newNode = null;
\r
131 if (node.isInstanceOf(p3r.Equipment)) {
\r
132 newNode = new ParameterizedModelNode(
\r
133 editor, parent, node.getGraph(),
\r
134 node.getResource(), p3r.HasGraphics);
\r
135 } else if (node.isInstanceOf(p3r.PipeRun)) {
\r
136 newNode = new PipeRunNode(parent, node.getGraph(), node.getResource());
\r
137 } else if (node.isInstanceOf(p3r.Nozzle)) {
\r
138 newNode = new ParameterizedModelNode(
\r
139 editor, parent, node.getGraph(),
\r
140 node.getResource(), p3r.HasGraphics);
\r
141 // CodedComponent must be handled first since it uses
\r
142 // hard-coded geometries
\r
143 // TODO : is this really necessary, or could we unify
\r
144 // PipeComponentNode, InlineComponentNode,...
\r
145 } else if (node.isInstanceOf(p3r.CodedComponent)) {
\r
146 newNode = new PipeComponentNode(editor,
\r
147 parent, node.getGraph(), node.getResource());
\r
148 } else if (node.isInstanceOf(p3r.NonVisibleComponent)) {
\r
149 newNode = new NonVisibleNode(parent, node.getGraph(), node.getResource());
\r
150 } else if (node.isInstanceOf(p3r.PipelineComponent)) {
\r
151 newNode = new PipelineComponentNode(editor,
\r
152 parent, node.getGraph(), node.getResource());
\r
155 // } else if (node instanceof Shape) // Markers (ar/mobile)
\r
157 // newNode = new ShapeNode(TestProcessEditor.this,parent,node);
\r
158 if (newNode != null) {
\r
159 if (newNode instanceof ISelectableNode)
\r
160 ((ISelectableNode) newNode).setVisible(true);
\r
161 if (newNode instanceof IGeometryNode) {
\r
162 updateGeometry((IGeometryNode) newNode);
\r
166 } catch (Exception e) {
\r
167 ErrorLogger.defaultLogError("Cannot handle node " + node.getResource(), e);
\r
170 ErrorLogger.defaultLogError("Cannot handle node " + node.getResource(), null);
\r
176 * This is used to create elbows and straight pipes to pipeline TODO :
\r
177 * this should be done with rule-engine!
\r
180 * @author Marko Luukkainen
\r
183 protected class PipeRunControlPointQuery extends NodeQuery {
\r
184 private List<Resource> removed = new ArrayList<Resource>();
\r
185 private List<Resource> added = new ArrayList<Resource>();
\r
187 public PipeRunControlPointQuery(Resource r) {
\r
189 if (DEBUG) System.out.println("Created PipeRunControlPointQuery for " + r);
\r
194 protected Object compute2(Graph graph) {
\r
195 PipeRun run = new PipeRun(graph, nodeResource);
\r
196 Collection<IEntity> cps = run
\r
197 .getRelatedObjects(ProcessResource.plant3Dresource.HasControlPoints);
\r
198 List<Resource> res = new ArrayList<Resource>();
\r
199 for (IEntity t : cps)
\r
200 res.add(t.getResource());
\r
205 public boolean updated(Graph graph, Object oldResult,
\r
206 Object newResult) {
\r
211 List<Resource> oldCps = (List<Resource>) oldResult;
\r
212 List<Resource> newCps = (List<Resource>) newResult;
\r
213 if (oldCps == null)
\r
214 oldCps = new ArrayList<Resource>();
\r
216 for (Resource r : oldCps) {
\r
217 if (!newCps.contains(r))
\r
221 for (Resource r : newCps) {
\r
222 if (!oldCps.contains(r))
\r
225 for (Resource r : removed)
\r
226 removeControlPoint(graph, r);
\r
227 for (Resource r : added) {
\r
228 addControlPoint(graph, r);
\r
229 // ControlPointTools.addControlPoint(new
\r
230 // PipeRun(graph,pipeRun), new PipeControlPoint(graph, r));
\r
233 return (added.size() > 0 || removed.size() > 0);
\r
237 public void dispose() {
\r
239 for (ControlPointPropertyQuery q : controlPointPropertyQueries.values())
\r
241 controlPointPropertyQueries.clear();
\r
244 private Map<Resource,ControlPointPropertyQuery> controlPointPropertyQueries = new HashMap<Resource, ControlPointPropertyQuery>();
\r
246 private void addControlPoint(Graph graph, Resource resource) {
\r
247 ControlPointPropertyQuery query = new ControlPointPropertyQuery(resource);
\r
248 graph.performQuery(query);
\r
249 controlPointPropertyQueries.put(resource,query);
\r
252 private void removeControlPoint(Graph graph, Resource resource) {
\r
253 ControlPointPropertyQuery query = controlPointPropertyQueries.remove(resource);
\r
255 ControlPointTools.removeControlPoint(new PipeControlPoint(
\r
261 protected class ControlPointPropertyQuery extends NodeQuery {
\r
262 boolean initialized = false;
\r
264 public ControlPointPropertyQuery(Resource r) {
\r
266 if (DEBUG) System.out.println("Created ControlPointPropertyQuery for " + r);
\r
270 public List<Object> compute2(Graph g) {
\r
271 IEntity t = EntityFactory.create(g,nodeResource);
\r
273 Collection<Property> properties = t.getRelatedProperties(ProcessResource.builtins.HasProperty);
\r
274 List<Object> propertyValues = new ArrayList<Object>();
\r
275 p(properties,propertyValues);
\r
277 return propertyValues;
\r
280 private void p(Collection<Property> properties, List<Object> propertyValues) {
\r
281 for (Property p : properties) {
\r
282 Collection<Property> subProperties = p.getRelatedProperties(p.getGraph().getBuiltins().HasProperty);
\r
283 if (subProperties.size() != 0) {
\r
284 p(subProperties,propertyValues);
\r
287 propertyValues.add(p.getValue());
\r
293 public boolean updated(Graph graph, Object oldResult, Object newResult) {
\r
294 PipingRules.pipeControlPointPositionUpdate(graph, this.nodeResource);
\r
296 //PipingRules.pipeControlPointPositionUpdate(graph, this.nodeResource);
\r
298 initialized = true;
\r
305 protected void removeNode(Resource parent, Resource r) {
\r
306 super.removeNode(parent, r);
\r
307 PipeRunControlPointQuery q = pipeRunQueries.get(r);
\r
313 public void dispose() {
\r