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