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