]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java
53a0ed2c78ed1298bca72e551986d2fe2f3cd8fc
[simantics/3d.git] / org.simantics.plant3d / src / org / simantics / plant3d / editor / Plant3DEditor.java
1 package org.simantics.plant3d.editor;
2
3 import java.util.ArrayList;
4 import java.util.HashSet;
5 import java.util.List;
6 import java.util.Set;
7
8 import org.eclipse.jface.action.IMenuListener;
9 import org.eclipse.jface.action.IMenuManager;
10 import org.eclipse.jface.action.MenuManager;
11 import org.eclipse.jface.viewers.ISelectionChangedListener;
12 import org.eclipse.jface.viewers.ISelectionProvider;
13 import org.eclipse.jface.viewers.SelectionChangedEvent;
14 import org.eclipse.swt.events.DisposeEvent;
15 import org.eclipse.swt.events.DisposeListener;
16 import org.eclipse.swt.layout.FillLayout;
17 import org.eclipse.swt.widgets.Composite;
18 import org.eclipse.swt.widgets.Menu;
19 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
20 import org.simantics.db.ReadGraph;
21 import org.simantics.db.Resource;
22 import org.simantics.db.Session;
23 import org.simantics.db.common.request.ReadRequest;
24 import org.simantics.db.exception.DatabaseException;
25 import org.simantics.g3d.scenegraph.NodeMap;
26 import org.simantics.g3d.scenegraph.RenderListener;
27 import org.simantics.g3d.scenegraph.base.INode;
28 import org.simantics.g3d.vtk.action.RemoveAction;
29 import org.simantics.g3d.vtk.common.HoverHighlighter;
30 import org.simantics.g3d.vtk.common.NodeSelectionProvider2;
31 import org.simantics.g3d.vtk.common.SelectionHighlighter;
32 import org.simantics.g3d.vtk.common.VTKSelectionItem;
33 import org.simantics.g3d.vtk.common.VtkView;
34 import org.simantics.g3d.vtk.shape.vtkShape;
35 import org.simantics.g3d.vtk.swt.ContextMenuListener;
36 import org.simantics.g3d.vtk.swt.FocusAction;
37 import org.simantics.g3d.vtk.swt.InteractiveVtkComposite;
38 import org.simantics.g3d.vtk.swt.RotateAction;
39 import org.simantics.g3d.vtk.swt.TranslateAction;
40 import org.simantics.g3d.vtk.swt.vtkCameraAndSelectorAction;
41 import org.simantics.g3d.vtk.utils.AxesDisplay;
42 import org.simantics.objmap.graph.IMapping;
43 import org.simantics.objmap.graph.Mappings;
44 import org.simantics.objmap.graph.schema.IMappingSchema;
45 import org.simantics.plant3d.actions.AddComponentAction;
46 import org.simantics.plant3d.actions.AddEquipmentAction;
47 import org.simantics.plant3d.actions.AddNozzleAction;
48 import org.simantics.plant3d.actions.RemoveAndSplitAction;
49 import org.simantics.plant3d.actions.RoutePipeAction;
50 import org.simantics.plant3d.actions.TranslateFreeVariableLengthAction;
51 import org.simantics.plant3d.actions.TranslateInlineAction;
52 import org.simantics.plant3d.ontology.Plant3D;
53 import org.simantics.plant3d.scenegraph.EndComponent;
54 import org.simantics.plant3d.scenegraph.Equipment;
55 import org.simantics.plant3d.scenegraph.IP3DNode;
56 import org.simantics.plant3d.scenegraph.InlineComponent;
57 import org.simantics.plant3d.scenegraph.Nozzle;
58 import org.simantics.plant3d.scenegraph.P3DRootNode;
59 import org.simantics.plant3d.scenegraph.PipelineComponent;
60 import org.simantics.plant3d.scenegraph.SchemaBuilder;
61 import org.simantics.plant3d.scenegraph.TurnComponent;
62 import org.simantics.plant3d.scenegraph.controlpoint.ControlPointFactory;
63 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
64 import org.simantics.plant3d.utils.ComponentUtils;
65 import org.simantics.plant3d.utils.Item;
66 import org.simantics.plant3d.utils.P3DUtil;
67 import org.simantics.selectionview.StandardPropertyPage;
68 import org.simantics.ui.workbench.IPropertyPage;
69 import org.simantics.ui.workbench.IResourceEditorInput;
70 import org.simantics.ui.workbench.ResourceEditorPart;
71 import org.simantics.utils.threads.ThreadUtils;
72 import org.simantics.utils.ui.ExceptionUtils;
73
74 import vtk.vtkActor;
75 import vtk.vtkCameraPass;
76 import vtk.vtkDefaultPass;
77 import vtk.vtkGaussianBlurPass;
78 import vtk.vtkLightsPass;
79 import vtk.vtkProp;
80 import vtk.vtkRenderPassCollection;
81 import vtk.vtkRenderer;
82 import vtk.vtkSSAAPass;
83 import vtk.vtkSequencePass;
84 import vtk.vtkSimpleMotionBlurPass;
85 import vtk.vtkSobelGradientMagnitudePass;
86
87
88 public class Plant3DEditor extends ResourceEditorPart {
89
90         private Composite parent;
91         private Resource input;
92 //      private InteractiveVtkPanel panel;
93 //      private SWTAWTComponent component;
94         private InteractiveVtkComposite panel;
95         
96         private P3DRootNode rootNode;
97         private IMapping<Resource,INode> mapping;
98         
99         protected NodeSelectionProvider2<Resource, INode> selectionProvider;
100         
101         
102         protected vtkCameraAndSelectorAction cameraAction;
103         protected FocusAction focusAction;
104         protected TranslateAction translateAction;
105         protected TranslateInlineAction translateInlineAction;
106         protected TranslateFreeVariableLengthAction translateFreeVariableLengthAction;
107         protected RotateAction rotateAction;
108         protected RemoveAction removeAction;
109         protected RemoveAndSplitAction removeSplitAction;
110         protected RoutePipeAction routePipeAction;
111         protected AddComponentAction addComponentAction;
112         
113         private P3DNodeMap nodeMap;
114         
115         @Override
116         public void createPartControl(Composite parent) {
117                 this.parent = parent;
118                 parent.setLayout (new FillLayout ());
119 //              component = new SWTAWTComponent(parent,SWT.NONE) {
120 //                      
121 //                      @Override
122 //                      protected Component createSwingComponent() {
123 //                              if (panel == null) {
124 //                                      panel = new InteractiveVtkPanel();
125 //                                      vtkPanelUtil.registerPanel(panel);
126 //                                      createScene();
127 //                              }
128 //                              return panel;
129 //                      }
130 //              };
131
132                 IResourceEditorInput rei = (IResourceEditorInput)getEditorInput();
133                 input = rei.getResource();
134                 
135                 panel = new InteractiveVtkComposite(parent);
136                 
137                 
138                 //IActionBars actionBars = getEditorSite().getActionBars();
139
140                 hookContextMenu();
141                 
142                 createScene();
143                 
144                 new ContextMenuListener(panel, contextMenu);
145                 
146                 cameraAction = createCameraAction();
147                 panel.setDefaultAction(cameraAction);
148                 panel.useDefaultAction();
149                 panel.setPickType(4);
150                 
151                 try {
152                         ControlPointFactory.preloadCache(getLibraryUri());
153                         ComponentUtils.preloadCache();
154                 } catch (Exception e) {
155                         ExceptionUtils.logAndShowError("Cannot open Plant3D editor",e);
156                         return;
157                 }
158                 
159                 try {
160                         getSession().syncRequest(new ReadRequest() {
161                                 
162                                 @Override
163                                 public void run(ReadGraph graph) throws DatabaseException {
164                                     System.out.println("START PLANT3D LOAD");
165                                         PipingRules.setEnabled(false);
166                                         IMappingSchema<Resource,INode> schema = getSchema(graph);
167                                         mapping = Mappings.createWithListening(schema);
168                                         rootNode = (P3DRootNode)mapping.map(graph, input);
169                                         // update control points.
170                                         // TODO : this should be optimized.
171
172                                         try {
173                                             P3DUtil.finalizeDBLoad(rootNode);
174                                             nodeMap = createNodeMap(getSession(), mapping, panel,rootNode);
175                                            
176                     } catch (Exception e) {
177                         throw new DatabaseException(e);
178                     }
179                                         
180                                         System.out.println("END PLANT3D LOAD");
181                                 }
182                         });
183                         
184                         if (rootNode == null)
185                                 throw new RuntimeException("Scenegraph loading failed.");
186                         populate();
187                         
188                         selectionProvider = createSelectionProvider();
189
190                         cameraAction.addSelectionChangedListener(selectionProvider);
191
192                         cameraAction.addHoverChangedListener(createHoverHighlhighter());
193                         selectionProvider.addSelectionChangedListener(createSelectionHighlighter());
194                         
195                         getSite().setSelectionProvider(selectionProvider);
196                         getSite().getPage().addPostSelectionListener(selectionProvider);
197                         
198                         //outlinePage = new ScenegraphOutlinePage(rootNode);
199                         
200                         
201                         parent.addDisposeListener(new DisposeListener() {
202                                 
203                                 @Override
204                                 public void widgetDisposed(DisposeEvent e) {
205                                         getSite().getPage().removePostSelectionListener(selectionProvider);
206                                         
207                                         PipingRules.setEnabled(false);
208                                         nodeMap.delete();
209                                         PipingRules.setEnabled(true);
210                                         mapping.dispose();
211 //                                      component.dispose();
212                                         //panel.getComponent().dispose();
213                                         
214                                 }
215                         });
216                 } catch (DatabaseException e1) {
217                         ExceptionUtils.logAndShowError("Cannot open Plant3D editor",e1);
218                         return;
219                 }
220                 
221                 createActions();
222                 
223         }
224         
225         protected vtkCameraAndSelectorAction createCameraAction() {
226             return new vtkCameraAndSelectorAction(panel); 
227         }
228         
229         protected NodeSelectionProvider2<Resource,INode> createSelectionProvider() {
230             return new NodeSelectionProvider2<Resource,INode>(this,mapping,nodeMap);
231         }
232         
233         protected HoverHighlighter createHoverHighlhighter() {
234             return new HoverHighlighter(panel,nodeMap);
235         }
236         
237         protected SelectionHighlighter<Resource,INode> createSelectionHighlighter() {
238             return new SelectionHighlighter<Resource,INode>(panel,nodeMap);
239         }
240         
241         protected String getLibraryUri() {
242             return Plant3D.URIs.Builtin;
243         }
244         
245         protected void createActions() {
246             focusAction = new FocusAction(panel, cameraAction);
247                 translateAction = new TranslateAction(panel,nodeMap);
248                 translateInlineAction = new TranslateInlineAction(panel, nodeMap);
249                 translateFreeVariableLengthAction = new TranslateFreeVariableLengthAction(panel, getRootNode());
250                 rotateAction = new RotateAction(panel,nodeMap);
251                 removeAction = new RemoveAction(nodeMap);
252                 removeSplitAction = new RemoveAndSplitAction(nodeMap);
253                 routePipeAction = new RoutePipeAction(panel,rootNode);
254                 addComponentAction = new AddComponentAction(panel, rootNode, getLibraryUri());
255         }
256         
257         public void populate() {
258                 ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
259                         
260                         @Override
261                         public void run() {
262                                 nodeMap.populate();
263                                 panel.addListener(new RenderListener() {
264                     
265                     @Override
266                     public void preRender() {
267                    
268                     }
269                     
270                     @Override
271                     public void postRender() {
272                         try {
273                             P3DUtil.finalizeDBLoad2(rootNode);
274                             if (nodeMap.isRangeModified());
275                                 nodeMap.commit("Load sync");
276                         } catch (Exception e) {
277                             //throw new DatabaseException(e);
278                         }
279                         panel.removeListener(this);  
280                         
281                     }
282                 });
283                                 
284                         }
285                 });
286                 
287         }
288         
289         protected IMappingSchema<Resource, INode> getSchema(ReadGraph graph) throws DatabaseException {
290                 IMappingSchema<Resource,INode> schema = SchemaBuilder.getSchema(graph);
291                 return schema;
292         }
293         
294         protected P3DNodeMap createNodeMap(Session session, IMapping<Resource, INode> mapping, VtkView panel, P3DRootNode rootNode) {
295                 return new P3DNodeMap(session, mapping, panel,rootNode);
296         }
297         
298         @Override
299         public void setFocus() {
300                 //component.setFocus();
301                 panel.getComponent().setFocus();
302         }
303         
304         private void createScene() {
305                 vtkRenderer ren1 = panel.getRenderer();
306                 
307                 boolean multiPass = false;
308                 boolean blur = false;
309                 boolean ssaa = false;
310                 //boolean sobel = true;
311                 boolean mblur = false;
312                 if (multiPass) {
313                         
314                         vtkLightsPass lightsPass = new vtkLightsPass();
315                         vtkDefaultPass defaultPass = new vtkDefaultPass();
316                         
317                         
318                         vtkRenderPassCollection passes = new vtkRenderPassCollection();
319                         passes.AddItem(lightsPass);
320                         passes.AddItem(defaultPass);
321                         
322                         vtkSequencePass seq = new vtkSequencePass();
323                         seq.SetPasses(passes);
324                         
325                         vtkCameraPass cameraPass = new vtkCameraPass();
326                         cameraPass.SetDelegatePass(seq);
327                         
328                         if (blur) {
329                             vtkGaussianBlurPass blurPass = new vtkGaussianBlurPass();
330                             blurPass.SetDelegatePass(cameraPass);
331                             ren1.SetPass(blurPass);
332                         } else if (ssaa) {
333                             vtkSSAAPass ssaaPass = new vtkSSAAPass();
334                             ssaaPass.SetDelegatePass(cameraPass);
335                             ren1.SetPass(ssaaPass);
336                         } else if (mblur) {
337                             vtkSimpleMotionBlurPass mBlurPass = new vtkSimpleMotionBlurPass();
338                             mBlurPass.SetDelegatePass(cameraPass);
339                 ren1.SetPass(mBlurPass);
340 //                      } else if (sobel) {
341 //                          vtkSobelGradientMagnitudePass sobelPass = new vtkSobelGradientMagnitudePass();
342 //                          sobelPass.SetDelegatePass(sobelPass);
343 //                          ren1.SetPass(sobelPass);
344                 } else {
345                     ren1.SetPass(cameraPass);
346                 }
347                          
348                 }
349 //              ren1.GetRenderWindow().LineSmoothingOn();
350 //              ren1.GetRenderWindow().PointSmoothingOn();
351 //              ren1.GetRenderWindow().PolygonSmoothingOn();
352 //              ren1.GetRenderWindow().SetMultiSamples(2);
353
354                 
355
356                 ren1.SetBackground2(1,1,1); // background color white
357                 ren1.SetBackground(0.9,0.9,0.9);
358                 ren1.SetGradientBackground(true);
359
360                 // vtkActor grid = vtkShape.createGridActor(8,1.0,1|2|4);
361                 vtkActor grid = vtkShape.createGridActor(8,1.0, 2 );
362                 grid.SetPickable(0);
363                 ren1.AddActor(grid);
364                 panel.addDeletable(grid);
365                 
366                 AxesDisplay axesDisplay = new AxesDisplay(panel);
367                 axesDisplay.show();
368                 
369         }
370         
371         protected Menu contextMenu;
372         
373         protected void hookContextMenu() {
374                 MenuManager menuMgr = new MenuManager("#PopupMenu");
375                 menuMgr.setRemoveAllWhenShown(true);
376                 menuMgr.addMenuListener(new IMenuListener() {
377                         public void menuAboutToShow(IMenuManager manager) {             
378                                 createContextMenu(manager);
379                         }
380                 });
381
382                 contextMenu = menuMgr.createContextMenu(parent);
383         }
384         
385         protected void createContextMenu(IMenuManager m) {
386                 List<INode> selected = selectionProvider.getSelectedNodes();
387                 List<VTKSelectionItem<Resource>> selectedItems = selectionProvider.getSelectedItems();
388                 if (selectedItems.size() > 0) {
389                     List<vtkProp> props = new ArrayList<>();
390                     for (VTKSelectionItem<Resource> i : selectedItems) {
391                         vtkProp p = (vtkProp)i.getAdapter(vtkProp.class);
392                         if (p != null)
393                             props.add(p);
394                     }
395                     if (props.size() > 0) {
396                         focusAction.setProps(props);
397                         m.add(focusAction);
398                     }
399                 }
400                 try {
401                         if (selected.size() == 0) {
402                                 for (Item eq : P3DUtil.getEquipments(getLibraryUri())) {
403                                         m.add(new AddEquipmentAction(rootNode, eq));
404                                 }
405                         } else if (selected.size() == 1) {
406                                 IP3DNode node = (IP3DNode)selected.get(0);
407                                 if (node instanceof Equipment) {
408                                         m.add(translateAction);
409                                         m.add(rotateAction);
410                                         for (Item eq : P3DUtil.getNozzles(getLibraryUri())) {
411                                                 AddNozzleAction add = new AddNozzleAction(rootNode, eq);
412                                                 add.setEquipment((Equipment)node);
413                                                 m.add(add);
414                                         }
415                                         m.add(removeAction);
416                                 } else if (node instanceof Nozzle) {
417                                         Nozzle nozzle = (Nozzle)node;
418                                         if (!nozzle.isFixed()) {
419                                                 m.add(translateAction);
420                                                 m.add(rotateAction);
421                                         }
422                                         m.add(routePipeAction);
423                                         routePipeAction.setComponent(nozzle);
424                                         routePipeAction.setEnabled(nozzle.getNext() == null && nozzle.getPrevious() == null);
425                                         m.add(addComponentAction);
426                                         addComponentAction.setComponent(nozzle);
427                                         m.add(removeAction);
428                                 } else if (node instanceof TurnComponent) {
429                                         m.add(translateAction);
430                                         TurnComponent component = (TurnComponent)node;
431                                         m.add(routePipeAction);
432                                         routePipeAction.setComponent(component);
433                                         routePipeAction.setEnabled(component.getNext() == null || component.getPrevious() == null);
434                                         m.add(addComponentAction);
435                                         addComponentAction.setComponent(component);
436                                         m.add(removeAction);
437                                         m.add(removeSplitAction);
438                                         removeSplitAction.setNode(node);
439                                 } else if (node instanceof EndComponent) {
440                                         m.add(translateAction);
441                                         m.add(addComponentAction);
442                                         addComponentAction.setComponent((PipelineComponent)node);
443                                         m.add(removeAction);
444                                 } else if (node instanceof InlineComponent) {
445                                         //m.add(translateInlineAction);
446                                         InlineComponent component = (InlineComponent)node;
447                                         if (component.isVariableLength())
448                                             m.add(translateFreeVariableLengthAction);
449                                         else
450                                             m.add(translateInlineAction);
451                                         m.add(routePipeAction);
452                                         routePipeAction.setComponent(component);
453                                         m.add(addComponentAction);
454                                         addComponentAction.setComponent(component);
455                                         m.add(removeAction);
456                                         m.add(removeSplitAction);
457                                         removeSplitAction.setNode(node);
458                                 } else {
459                                     m.add(removeAction);
460                                 }
461                                 
462                                 
463                                 translateAction.setNode(node);
464                                 translateInlineAction.setNode(node);
465                                 translateFreeVariableLengthAction.setNode(node);
466                                 rotateAction.setNode(node);
467                                 removeAction.setNode(node);
468                                 
469                         } 
470                 } catch (DatabaseException e) {
471                         ExceptionUtils.logAndShowError(e);
472                 }
473         }
474         
475         private IContentOutlinePage createOutline() {
476                 if (rootNode == null || selectionProvider == null)
477                         return null;
478                 //IContentOutlinePage outlinePage = new VTKContentOutlinePage<Resource,Object>(rootNode, selectionProvider);
479                 IContentOutlinePage outlinePage = new P3DContentOutlinePage(rootNode, selectionProvider) {
480                         protected void createContextMenu(IMenuManager manager) {
481                                 Plant3DEditor.this.createContextMenu(manager);
482                         };
483                 };
484                 outlinePage.addSelectionChangedListener(new ISelectionChangedListener() {
485                         
486                         @Override
487                         public void selectionChanged(SelectionChangedEvent event) {
488                                 selectionProvider.selectionChanged(event);
489                         }
490                 });
491                 return outlinePage;
492         }
493
494         @SuppressWarnings("rawtypes")
495         @Override
496         public Object getAdapter(Class adapter) {
497                 if (IPropertyPage.class.equals(adapter))
498                         return new StandardPropertyPage(getSite(),getPropertyContexts());
499                 if (IContentOutlinePage.class.equals(adapter)) {
500                         return createOutline();
501                 }
502                 if (NodeMap.class.equals(adapter)) {
503                         return nodeMap;
504                 }
505                 if (INode.class.equals(adapter)) {
506                         return rootNode;
507                 }
508                 if (IMapping.class.equals(adapter)) {
509                         return mapping;
510                 }
511 //              if (InteractiveVtkPanel.class.equals(adapter)) {
512 //                      return panel;
513 //              }
514                 if (VtkView.class.equals(adapter))
515                         return panel;
516                 if (ISelectionProvider.class.equals(adapter))
517                         return selectionProvider;
518                 return super.getAdapter(adapter);
519         }
520         
521         public Set<String> getPropertyContexts() {
522                 Set<String> result = new HashSet<String>();
523                 result.add("http://www.simantics.org/Project-1.0/ProjectBrowseContext");
524                 return result;
525         }
526         
527         public InteractiveVtkComposite getPanel() {
528         return panel;
529     }
530         
531         public P3DRootNode getRootNode() {
532                 return rootNode;
533         }
534         
535         public IMapping<Resource, INode> getMapping() {
536                 return mapping;
537         }
538         
539         public P3DNodeMap getNodeMap() {
540         return nodeMap;
541     }
542 }