1 package org.simantics.plant3d.editor;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashSet;
9 import org.simantics.db.ReadGraph;
10 import org.simantics.db.Resource;
11 import org.simantics.db.Session;
12 import org.simantics.db.WriteGraph;
13 import org.simantics.db.exception.DatabaseException;
14 import org.simantics.g3d.ontology.G3D;
15 import org.simantics.g3d.scenegraph.base.INode;
16 import org.simantics.g3d.scenegraph.base.ParentNode;
17 import org.simantics.g3d.vtk.common.AbstractVTKNodeMap;
18 import org.simantics.g3d.vtk.common.VtkView;
19 import org.simantics.objmap.graph.IMapping;
20 import org.simantics.plant3d.ontology.Plant3D;
21 import org.simantics.plant3d.scenegraph.IP3DNode;
22 import org.simantics.plant3d.scenegraph.IP3DVisualNode;
23 import org.simantics.plant3d.scenegraph.P3DParentNode;
24 import org.simantics.plant3d.scenegraph.P3DRootNode;
25 import org.simantics.plant3d.scenegraph.ParameterizedNode;
26 import org.simantics.plant3d.scenegraph.PipeRun;
27 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
28 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
33 public class P3DNodeMap extends AbstractVTKNodeMap<Resource,INode> {
35 private static final boolean DEBUG = false;
37 public P3DNodeMap(Session session, IMapping<Resource,INode> mapping, VtkView panel, P3DRootNode rootNode) {
38 super(session, mapping, panel, rootNode);
39 rootNode.setNodeMap(this);
42 protected void updateActor(INode n, Set<String> ids) {
43 if (DEBUG) System.out.println("P3DNodeMap update " + debugString(n));
44 if (!(n instanceof IP3DVisualNode)) {
45 if (n instanceof PipeControlPoint) {
46 n = ((PipeControlPoint)n).getPipelineComponent();
54 IP3DVisualNode node = (IP3DVisualNode)n;
57 System.out.print("P3DNodeMap update " + debugString(node));
59 System.out.print(" " + s);
63 if (ids.contains(Plant3D.URIs.hasGeometry)) {
65 updateRenderObjectsFor(node);
66 updateTransform(node);
68 if (n instanceof ParameterizedNode) {
69 ParameterizedNode geom = (ParameterizedNode)n;
70 for (String id : geom.getParameterMap().keySet()) {
71 if (ids.contains(id)) {
73 updateRenderObjectsFor(node);
74 //updateTransform(node);
78 } else if (n instanceof PipeRun) {
79 PipeRun run = (PipeRun)n;
81 // Check for change to turn radii and update turn components
82 if (ids.contains(Plant3D.URIs.HasTurnRadiusArray) ||
83 ids.contains(Plant3D.URIs.HasTurnRadius)) {
84 requestTurnUpdates(run);
87 Set<String> ids2 = new HashSet<String>();
88 ids2.add(Plant3D.URIs.hasGeometry);
89 for (PipeControlPoint pcp : run.getControlPoints()) {
90 updateActor(pcp, ids2);
94 if (ids.contains(G3D.URIs.hasPosition) ||
95 ids.contains(G3D.URIs.hasOrientation) ||
96 ids.contains(G3D.URIs.hasWorldPosition) ||
97 ids.contains(G3D.URIs.hasWorldOrientation)) {
98 updateTransform(node);
100 if (ids.contains(Plant3D.URIs.HasTurnRadiusIndex)) {
101 node.visualize(view);
102 updateRenderObjectsFor(node);
106 private void requestTurnUpdates(PipeRun run) {
107 for (PipeControlPoint pcp : run.getControlPoints()) {
109 PipingRules.requestUpdate(pcp);
113 private void updateTransform(IP3DNode node) {
114 if (DEBUG) System.out.println("P3DNodeMap update Transform " + debugString(node));
116 node.update(view.getRenderer());
118 if (node instanceof ParentNode<?>) {
119 @SuppressWarnings("unchecked")
120 ParentNode<IP3DNode> p = (ParentNode<IP3DNode>)node;
121 for (IP3DNode n : p.getNodes())
127 protected Collection<vtkProp> getActors(INode n) {
128 List<vtkProp> props = new ArrayList<vtkProp>();
129 if (!(n instanceof IP3DVisualNode))
131 IP3DVisualNode node = (IP3DVisualNode)n;
132 for (vtkProp3D p : ((IP3DVisualNode)node).getActors())
139 protected void removeActor(INode n) {
140 if (DEBUG) System.out.println("P3DNodeMap.removeActor " + debugString(n));
141 if (!(n instanceof IP3DVisualNode))
143 IP3DVisualNode node = (IP3DVisualNode)n;
146 if (node instanceof P3DParentNode<?>) {
147 for (IP3DNode n2 : ((P3DParentNode<?>)node).getNodes())
148 if (n2 instanceof IP3DVisualNode)
149 removeActor((IP3DVisualNode)n2);
154 protected void addActor(INode n) {
155 if (DEBUG) System.out.println("P3DNodeMap.addActor " + debugString(n));
156 if (!(n instanceof IP3DVisualNode))
158 IP3DVisualNode node = (IP3DVisualNode)n;
160 if (hasActor(node)) {
161 if (DEBUG) System.out.println("Node already has an actor");
164 if (Thread.currentThread() != view.getThreadQueue().getThread())
165 throw new RuntimeException("Illegal thread.");
169 node.visualize(view);
171 map(node, node.getActors());
173 if (DEBUG) System.out.println("Added " + node.getActors().size() + " actors");
175 if (node instanceof P3DParentNode<?>) {
176 for (IP3DNode n2 : ((P3DParentNode<?>)node).getNodes())
177 if (n2 instanceof IP3DVisualNode)
178 addActor((IP3DVisualNode)n2);
181 updateTransform(node);
189 private boolean hasActor(IP3DVisualNode node) {
190 Collection<vtkProp> list = getRenderObjects(node);
191 if (list == null || list.size() == 0)
196 private void remActor(IP3DVisualNode node) {
197 if (Thread.currentThread() != view.getThreadQueue().getThread())
198 throw new RuntimeException("Illegal thread.");
200 Collection<vtkProp> list = getRenderObjects(node);
201 if (list.size() > 0) {
204 node.stopVisualize();
210 protected void update(ReadGraph graph) throws DatabaseException {
212 // System.out.println("Graph updates");
218 public void commit(String commitMessage) {
220 // System.out.println("Graph commit");
221 super.commit(commitMessage);
226 protected void commit(WriteGraph graph) throws DatabaseException {
228 validateGraph(graph);
231 protected void doCommit() {
232 // System.out.println("Do commit");
237 private void validate() {
238 for (INode node : rootNode.getNodes()) {
239 if (node instanceof PipeRun)
240 PipingRules.validate((PipeRun)node);
245 public synchronized void preRender() {
246 // System.out.println("P3DNodeMap preRender");
247 // super.preRender();
249 // boolean b = false;
250 // synchronized (syncMutex) {
251 // b = PipingRules.update();
254 // super.preRender();
258 b = PipingRules.update();
260 } catch (Exception e) {
266 protected void validateGraph(ReadGraph graph) throws DatabaseException {
267 Plant3D P3D = Plant3D.getInstance(graph);
268 Resource root = (Resource)mapping.inverseGet(rootNode);
269 if (!graph.isInstanceOf(root, P3D.Plant))
270 throw new DatabaseException("Root is not a Plant");
271 Set<Resource> equipment = new HashSet<>();
272 Set<Resource> pipeRuns = new HashSet<>();
273 for (Resource r : graph.getObjects(root, P3D.children)) {
274 if (graph.isInstanceOf(r, P3D.Equipment)) {
276 } else if (graph.isInstanceOf(r, P3D.PipeRun)) {
279 throw new DatabaseException("Unknown resource " + r+ " " + mapping.get(r));
282 Set<Resource> nozzles = new HashSet<>();
283 for (Resource e : equipment) {
284 for (Resource n : graph.getObjects(e, P3D.HasNozzle)) {
285 if (graph.isInstanceOf(n, P3D.Nozzle)) {
288 throw new DatabaseException("Unknown nozzle resource " + n+ " " + mapping.get(n));
293 Set<Resource> components = new HashSet<>();
294 for (Resource run : pipeRuns) {
295 for (Resource c : graph.getObjects(run, P3D.children)) {
296 if (graph.isInstanceOf(c, P3D.PipelineComponent)) {
299 throw new DatabaseException("Unknown component resource " + c + " " + mapping.get(c));
304 for (Resource c : components) {
305 for (Resource connected : graph.getObjects(c, P3D.Connects)) {
306 if (!components.contains(connected) && !nozzles.contains(connected)) {
307 throw new DatabaseException("Unbrowsable component resource " + connected + " " + mapping.get(connected) +" connected to " + c + " " + mapping.get(c));
309 Collection<Resource> connectedConnected = graph.getObjects(connected, P3D.Connects);
310 if (!connectedConnected.contains(c)) {
311 throw new DatabaseException("Component resource " + c + " " + mapping.get(c) + " is connected to " + connected + " " + mapping.get(connected) +", but its has no connection back.");