]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.csg/src/org/simantics/g3d/csg/editor/CSGEditor2.java
3D framework (Simca 2012)
[simantics/3d.git] / org.simantics.g3d.csg / src / org / simantics / g3d / csg / editor / CSGEditor2.java
1 package org.simantics.g3d.csg.editor;\r
2 \r
3 import java.awt.Component;\r
4 import java.util.ArrayList;\r
5 import java.util.Collection;\r
6 import java.util.HashSet;\r
7 import java.util.List;\r
8 import java.util.Set;\r
9 \r
10 import org.eclipse.jface.action.IMenuListener;\r
11 import org.eclipse.jface.action.IMenuManager;\r
12 import org.eclipse.jface.action.MenuManager;\r
13 import org.eclipse.jface.viewers.ISelectionChangedListener;\r
14 import org.eclipse.jface.viewers.SelectionChangedEvent;\r
15 import org.eclipse.swt.SWT;\r
16 import org.eclipse.swt.events.DisposeEvent;\r
17 import org.eclipse.swt.events.DisposeListener;\r
18 import org.eclipse.swt.layout.FillLayout;\r
19 import org.eclipse.swt.widgets.Composite;\r
20 import org.eclipse.swt.widgets.Display;\r
21 import org.eclipse.swt.widgets.Menu;\r
22 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;\r
23 import org.simantics.db.ReadGraph;\r
24 import org.simantics.db.Resource;\r
25 import org.simantics.db.common.request.ReadRequest;\r
26 import org.simantics.db.exception.DatabaseException;\r
27 import org.simantics.g3d.csg.actions.AddBooleanOpAction2;\r
28 import org.simantics.g3d.csg.actions.AddPrimitiveAction2;\r
29 import org.simantics.g3d.csg.actions.SplitBooleanOpAction2;\r
30 import org.simantics.g3d.csg.scenegraph2.BarrelNode;\r
31 import org.simantics.g3d.csg.scenegraph2.BoxNode;\r
32 import org.simantics.g3d.csg.scenegraph2.CSGparentNode;\r
33 import org.simantics.g3d.csg.scenegraph2.CSGrootNode;\r
34 import org.simantics.g3d.csg.scenegraph2.ConeNode;\r
35 import org.simantics.g3d.csg.scenegraph2.CylinderNode;\r
36 import org.simantics.g3d.csg.scenegraph2.DifferenceNode;\r
37 import org.simantics.g3d.csg.scenegraph2.EllipticCylinderNode;\r
38 import org.simantics.g3d.csg.scenegraph2.ICSGnode;\r
39 import org.simantics.g3d.csg.scenegraph2.IntersectionNode;\r
40 import org.simantics.g3d.csg.scenegraph2.RectangularSolidNode;\r
41 import org.simantics.g3d.csg.scenegraph2.RegularPrismNode;\r
42 import org.simantics.g3d.csg.scenegraph2.SchemaBuilder;\r
43 import org.simantics.g3d.csg.scenegraph2.SphereNode;\r
44 import org.simantics.g3d.csg.scenegraph2.TorusNode;\r
45 import org.simantics.g3d.csg.scenegraph2.UnionNode;\r
46 import org.simantics.g3d.scenegraph.IG3DNode;\r
47 import org.simantics.g3d.scenegraph.NodeMap;\r
48 import org.simantics.g3d.scenegraph.base.INode;\r
49 import org.simantics.g3d.vtk.action.RemoveAction;\r
50 import org.simantics.g3d.vtk.action.RotateAction;\r
51 import org.simantics.g3d.vtk.action.TranslateAction;\r
52 import org.simantics.g3d.vtk.action.vtkCameraAndSelectorAction;\r
53 import org.simantics.g3d.vtk.common.HoverHighlighter;\r
54 import org.simantics.g3d.vtk.common.InteractiveVtkPanel;\r
55 import org.simantics.g3d.vtk.common.NodeSelectionProvider2;\r
56 import org.simantics.g3d.vtk.common.SelectionHighlighter;\r
57 import org.simantics.g3d.vtk.common.VTKContentOutlinePage;\r
58 import org.simantics.g3d.vtk.shape.vtkShape;\r
59 import org.simantics.g3d.vtk.utils.vtkPanelUtil;\r
60 import org.simantics.objmap.graph.IMapping;\r
61 import org.simantics.objmap.graph.Mappings;\r
62 import org.simantics.objmap.graph.schema.IMappingSchema;\r
63 import org.simantics.selectionview.StandardPropertyPage;\r
64 import org.simantics.ui.workbench.IPropertyPage;\r
65 import org.simantics.ui.workbench.IResourceEditorInput;\r
66 import org.simantics.ui.workbench.ResourceEditorPart;\r
67 import org.simantics.utils.threads.AWTThread;\r
68 import org.simantics.utils.threads.ThreadUtils;\r
69 import org.simantics.utils.ui.ExceptionUtils;\r
70 import org.simantics.utils.ui.SWTAWTComponent;\r
71 \r
72 import vtk.vtkActor;\r
73 import vtk.vtkCameraPass;\r
74 import vtk.vtkDefaultPass;\r
75 import vtk.vtkLightsPass;\r
76 import vtk.vtkRenderPassCollection;\r
77 import vtk.vtkRenderer;\r
78 import vtk.vtkSequencePass;\r
79 \r
80 public class CSGEditor2  extends ResourceEditorPart {\r
81         private Composite parent;\r
82         private Resource input;\r
83         private InteractiveVtkPanel panel;\r
84         private SWTAWTComponent component;\r
85         \r
86         private CSGrootNode rootNode;\r
87         private IMapping<Resource,Object> mapping;\r
88         \r
89         private NodeSelectionProvider2<Resource,Object> selectionProvider;\r
90         \r
91         private vtkCameraAndSelectorAction cameraAction;\r
92         private TranslateAction translateAction;\r
93         private RotateAction rotateAction;\r
94         private RemoveAction removeAction;\r
95         \r
96         //private  ScenegraphOutlinePage outlinePage;\r
97         \r
98         private CSGNodeMap nodeMap;\r
99 \r
100 \r
101 \r
102         @Override\r
103         public void createPartControl(Composite parent) {\r
104                 this.parent = parent;\r
105                 parent.setLayout (new FillLayout ());\r
106                 component = new SWTAWTComponent(parent,SWT.NONE) {\r
107                         \r
108                         @Override\r
109                         protected Component createSwingComponent() {\r
110                                 if (panel == null) {\r
111                                         panel = new InteractiveVtkPanel();\r
112                                         vtkPanelUtil.registerPanel(panel);\r
113                                         createScene();\r
114                                 }\r
115                                 return panel;\r
116                         }\r
117                 };\r
118 \r
119                 IResourceEditorInput rei = (IResourceEditorInput)getEditorInput();\r
120                 input = rei.getResource();\r
121                 \r
122                 \r
123                 //IActionBars actionBars = getEditorSite().getActionBars();\r
124 \r
125                 hookContextMenu();\r
126                 \r
127                 component.syncPopulate();\r
128                 \r
129                 panel.addMouseListener(new java.awt.event.MouseAdapter() {\r
130                         @Override\r
131                         public void mouseClicked(final java.awt.event.MouseEvent e) {\r
132                                 if (e.getButton() == java.awt.event.MouseEvent.BUTTON3) {\r
133                                         Display.getDefault().asyncExec(new Runnable() {\r
134                                                 public void run() {\r
135                                                         contextMenu.setLocation(e.getXOnScreen(), e.getYOnScreen());\r
136                                                         contextMenu.setVisible(true);\r
137                                                 }\r
138                                         });\r
139                                 }\r
140                         }\r
141                 });\r
142                 \r
143 \r
144                 cameraAction = new vtkCameraAndSelectorAction(panel);   \r
145                 panel.setDefaultAction(cameraAction);\r
146                 panel.useDefaultAction();\r
147                 \r
148                 try {\r
149                         getSession().syncRequest(new ReadRequest() {\r
150                                 \r
151                                 @SuppressWarnings({ "rawtypes", "unchecked" })\r
152                                 @Override\r
153                                 public void run(ReadGraph graph) throws DatabaseException {\r
154                                         IMappingSchema schema = SchemaBuilder.getSchema(graph);\r
155                                         mapping = Mappings.createWithListening(schema);\r
156                                         rootNode = (CSGrootNode)mapping.map(graph, input);\r
157                                         nodeMap = new CSGNodeMap(getSession(), mapping, panel,(CSGrootNode)rootNode);\r
158                                 }\r
159                         });\r
160                         \r
161                         if (rootNode == null)\r
162                                 throw new RuntimeException("Scenegraph loading failed.");\r
163                         populate();\r
164                         \r
165                         selectionProvider = new NodeSelectionProvider2<Resource,Object>(this,mapping,nodeMap);\r
166 \r
167                         cameraAction.addSelectionChangedListener(selectionProvider);\r
168 \r
169                         cameraAction.addHoverChangedListener(new HoverHighlighter(panel,nodeMap));\r
170                         selectionProvider.addSelectionChangedListener(new SelectionHighlighter(panel,nodeMap));\r
171                         \r
172                         getSite().setSelectionProvider(selectionProvider);\r
173                         getSite().getPage().addPostSelectionListener(selectionProvider);\r
174                         \r
175                         //outlinePage = new ScenegraphOutlinePage(rootNode);\r
176                         \r
177                         \r
178                         parent.addDisposeListener(new DisposeListener() {\r
179                                 \r
180                                 @Override\r
181                                 public void widgetDisposed(DisposeEvent e) {\r
182                                         getSite().getPage().removePostSelectionListener(selectionProvider);\r
183                                         ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {\r
184                                                 \r
185                                                 @Override\r
186                                                 public void run() {\r
187                                                         nodeMap.delete();\r
188                                                         vtkPanelUtil.unregisterPanel(panel);\r
189 \r
190                                                 }\r
191                                         });\r
192                                         mapping.dispose();\r
193                                         component.dispose();\r
194                                         \r
195                                         \r
196                                 }\r
197                         });\r
198                 } catch (DatabaseException e1) {\r
199                         ExceptionUtils.logAndShowError("Cannot open CSG editor",e1);\r
200                         return;\r
201                 }\r
202                 \r
203                 translateAction = new TranslateAction(panel,nodeMap);\r
204                 rotateAction = new RotateAction(panel,nodeMap);\r
205                 removeAction = new RemoveAction(nodeMap) {\r
206                         public void setNode(IG3DNode node) {\r
207                                 super.setNode(node);\r
208                                 if (node.getParent() instanceof CSGparentNode)\r
209                                         setEnabled(false);\r
210                                 \r
211                         }\r
212                 };\r
213                 \r
214                 \r
215         }\r
216         \r
217         \r
218 \r
219         \r
220         public void populate() {\r
221                 ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {\r
222                         \r
223                         @Override\r
224                         public void run() {\r
225                                 nodeMap.populate();\r
226                         }\r
227                 });\r
228                 \r
229         }\r
230         \r
231         \r
232         \r
233         @Override\r
234         public void setFocus() {\r
235                 component.setFocus();\r
236         }\r
237         \r
238         private void createScene() {\r
239                 vtkRenderer ren1 = panel.GetRenderer();\r
240                 \r
241                 boolean multiPass = false;\r
242                 if (multiPass) {\r
243                         \r
244                         vtkLightsPass lightsPass = new vtkLightsPass();\r
245                         vtkDefaultPass defaultPass = new vtkDefaultPass();\r
246                         \r
247                         \r
248                         vtkRenderPassCollection passes = new vtkRenderPassCollection();\r
249                         passes.AddItem(lightsPass);\r
250                         passes.AddItem(defaultPass);\r
251                         \r
252                         vtkSequencePass seq = new vtkSequencePass();\r
253                         seq.SetPasses(passes);\r
254                         \r
255                 \r
256                         \r
257                         vtkCameraPass cameraPass = new vtkCameraPass();\r
258                         cameraPass.SetDelegatePass(seq);\r
259                         \r
260                         ren1.SetPass(cameraPass);\r
261                         \r
262                 }\r
263 //              ren1.GetRenderWindow().LineSmoothingOn();\r
264 //              ren1.GetRenderWindow().PointSmoothingOn();\r
265 //              ren1.GetRenderWindow().PolygonSmoothingOn();\r
266 //              ren1.GetRenderWindow().SetMultiSamples(2);\r
267 \r
268                 \r
269 \r
270                 ren1.SetBackground2(1,1,1); // background color white\r
271                 ren1.SetBackground(0.9,0.9,0.9);\r
272                 ren1.SetGradientBackground(true);\r
273 \r
274            // vtkActor grid = vtkShape.createGridActor(8,1.0,1|2|4);\r
275             vtkActor grid = vtkShape.createGridActor(8,1.0, 2 );\r
276             grid.SetPickable(0);\r
277             ren1.AddActor(grid);\r
278             panel.addDeletable(grid);\r
279             \r
280 \r
281                 \r
282         }\r
283         \r
284         protected Menu contextMenu;\r
285         \r
286         protected void hookContextMenu() {\r
287         MenuManager menuMgr = new MenuManager("#PopupMenu");\r
288         menuMgr.setRemoveAllWhenShown(true);\r
289         menuMgr.addMenuListener(new IMenuListener() {\r
290             public void menuAboutToShow(IMenuManager manager) {\r
291                 final IMenuManager m = manager;\r
292                         List<IG3DNode> selected = selectionProvider.getSelectedNodes();\r
293                         if (selected.size() == 0) {\r
294                                 m.add(new AddPrimitiveAction2(rootNode, BarrelNode.class));\r
295                                 m.add(new AddPrimitiveAction2(rootNode, BoxNode.class));\r
296                                 m.add(new AddPrimitiveAction2(rootNode, ConeNode.class));\r
297                                 m.add(new AddPrimitiveAction2(rootNode, CylinderNode.class));\r
298                                 m.add(new AddPrimitiveAction2(rootNode, EllipticCylinderNode.class));\r
299                                 m.add(new AddPrimitiveAction2(rootNode, RectangularSolidNode.class));\r
300                                 m.add(new AddPrimitiveAction2(rootNode, RegularPrismNode.class));\r
301                                 m.add(new AddPrimitiveAction2(rootNode, SphereNode.class));\r
302                                 m.add(new AddPrimitiveAction2(rootNode, TorusNode.class));\r
303                         } else if (selected.size() == 1) {\r
304                                 m.add(translateAction);\r
305                                         m.add(rotateAction);\r
306                                         m.add(removeAction);\r
307                                         ICSGnode node = (ICSGnode)selected.get(0);\r
308                                         translateAction.setNode(node);\r
309                                         rotateAction.setNode(node);\r
310                                         removeAction.setNode(node);\r
311                                         if (node instanceof CSGparentNode) {\r
312                                                 m.add(new SplitBooleanOpAction2(rootNode,(CSGparentNode)node));\r
313                                         }\r
314                         } else if (selected.size() == 2) {\r
315                                 if (selected.get(0).getParent().equals(rootNode) && selected.get(1).getParent().equals(rootNode)) {\r
316                                         Collection<ICSGnode> nodes = new ArrayList<ICSGnode>();\r
317                                         for (IG3DNode n : selected)\r
318                                                 nodes.add((ICSGnode)n);\r
319                                         m.add(new AddBooleanOpAction2(rootNode, DifferenceNode.class, nodes));\r
320                                         m.add(new AddBooleanOpAction2(rootNode, IntersectionNode.class, nodes));\r
321                                         m.add(new AddBooleanOpAction2(rootNode, UnionNode.class, nodes));\r
322                                 }\r
323                         }\r
324 //              try {\r
325 //                                      SimanticsUI.getSession().syncRequest(new ReadRequest() {\r
326 //                                              \r
327 //                                              @Override\r
328 //                                              public void run(ReadGraph graph) throws DatabaseException {\r
329 //                                                      Layer0 l0 = Layer0.getInstance(graph);\r
330 //                                                      CSG csg = CSG.getInstance(graph);\r
331 //                                                      Resource ontology = graph.getResource("http://www.simantics.org/CSG-0.1");\r
332 //                                                      \r
333 //                                                      if (selectionProvider.getSelectedResources().size() == 0) {\r
334 //                                                              List<NamedResource> primitives = new ArrayList<NamedResource>();\r
335 //                                                              for (Resource r : graph.getObjects(ontology, l0.ConsistsOf)) {\r
336 //                                                                      if (graph.isInheritedFrom(r, csg.Primitive) && !r.equals(csg.Primitive)) {\r
337 //                                                                              primitives.add(new NamedResource((String)graph.getRelatedValue(r, l0.HasName), r));\r
338 //                                                                      }\r
339 //                                                              }\r
340 //                                                              \r
341 //                                                              Collections.sort(primitives);\r
342 //                                                              for (NamedResource n : primitives) {\r
343 //                                                                      m.add(new AddPrimitiveAction(graph, n.getResource(),input));\r
344 //                                                              }\r
345 //                                                      }\r
346 //                                                      if (selectionProvider.getSelectedResources().size() == 2) {\r
347 //                                                              List<NamedResource> booleanOps = new ArrayList<NamedResource>();\r
348 //                                                              for (Resource r : graph.getObjects(ontology, l0.ConsistsOf)) {\r
349 //                                                                      if (graph.isInheritedFrom(r, csg.BooleanOperation) && !r.equals(csg.BooleanOperation)) {\r
350 //                                                                              booleanOps.add(new NamedResource((String)graph.getRelatedValue(r, l0.HasName), r));\r
351 //                                                                      }\r
352 //                                                              }\r
353 //                                                              \r
354 //                                                              Collections.sort(booleanOps);\r
355 //                                                              for (NamedResource n : booleanOps) {\r
356 //                                                                      m.add(new AddBooleanOpAction(graph, n.getResource(), input, selectionProvider.getSelectedResources()));\r
357 //                                                              }\r
358 //                                                      }\r
359 //                                                      if (selectionProvider.getSelectedResources().size() == 1) {\r
360 //                                                              m.add(translateAction);\r
361 //                                                              m.add(rotateAction);\r
362 //                                                              m.add(removeAction);\r
363 //                                                              Resource selected = selectionProvider.getSelectedResources().get(0);\r
364 //                                                              translateAction.setNode((IG3DNode2)mapping.get(selected));\r
365 //                                                              rotateAction.setNode((IG3DNode2)mapping.get(selected));\r
366 //                                                              removeAction.setNode((IG3DNode2)mapping.get(selected));\r
367 //                                                              if (graph.isInstanceOf(selected, csg.BooleanOperation)) {\r
368 //                                                                      m.add(new SplitBooleanOpAction(input,selected));\r
369 //                                                              }\r
370 //                                                              \r
371 //                                                              \r
372 //                                                      }\r
373 //                                                      \r
374 //                                              }\r
375 //                                      });\r
376 //                              } catch (DatabaseException e) {\r
377 //                                      // TODO Auto-generated catch block\r
378 //                                      e.printStackTrace();\r
379 //                              }\r
380                 \r
381             }\r
382         });\r
383 \r
384         contextMenu = menuMgr.createContextMenu(parent);\r
385     }\r
386         \r
387         private IContentOutlinePage createOutline() {\r
388                 if (rootNode == null || selectionProvider == null)\r
389                         return null;\r
390                 IContentOutlinePage outlinePage = new VTKContentOutlinePage<Resource,Object>(rootNode, selectionProvider);\r
391                 outlinePage.addSelectionChangedListener(new ISelectionChangedListener() {\r
392                         \r
393                         @Override\r
394                         public void selectionChanged(SelectionChangedEvent event) {\r
395                                 selectionProvider.selectionChanged(event);\r
396                         }\r
397                 });\r
398                 return outlinePage;\r
399         }\r
400 \r
401         @SuppressWarnings("rawtypes")\r
402         @Override\r
403         public Object getAdapter(Class adapter) {\r
404                 if (IPropertyPage.class.equals(adapter))\r
405                         return new StandardPropertyPage(getSite(),getPropertyContexts());\r
406                 if (IContentOutlinePage.class.equals(adapter)) {\r
407                         return createOutline();\r
408                 }\r
409                 if (NodeMap.class.equals(adapter)) {\r
410                         return nodeMap;\r
411                 }\r
412                 if (INode.class.equals(adapter)) {\r
413                         return rootNode;\r
414                 }\r
415                 if (IMapping.class.equals(adapter)) {\r
416                         return mapping;\r
417                 }\r
418                 if (InteractiveVtkPanel.class.equals(adapter)) {\r
419                         return panel;\r
420                 }\r
421                 return super.getAdapter(adapter);\r
422         }\r
423         \r
424         public Set<String> getPropertyContexts() {\r
425                 Set<String> result = new HashSet<String>();\r
426                 result.add("http://www.simantics.org/Project-1.0/ProjectBrowseContext");\r
427                 return result;\r
428         }\r
429 }\r