1 package org.simantics.plant3d.editor;
3 import java.util.ArrayList;
4 import java.util.HashSet;
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;
75 import vtk.vtkCameraPass;
76 import vtk.vtkDefaultPass;
77 import vtk.vtkGaussianBlurPass;
78 import vtk.vtkLightsPass;
80 import vtk.vtkRenderPassCollection;
81 import vtk.vtkRenderer;
82 import vtk.vtkSSAAPass;
83 import vtk.vtkSequencePass;
84 import vtk.vtkSimpleMotionBlurPass;
87 public class Plant3DEditor extends ResourceEditorPart {
89 private Composite parent;
90 private Resource input;
91 // private InteractiveVtkPanel panel;
92 // private SWTAWTComponent component;
93 private InteractiveVtkComposite panel;
95 private P3DRootNode rootNode;
96 private IMapping<Resource,INode> mapping;
98 protected NodeSelectionProvider2<Resource, INode> selectionProvider;
101 protected vtkCameraAndSelectorAction cameraAction;
102 protected FocusAction focusAction;
103 protected TranslateAction translateAction;
104 protected TranslateInlineAction translateInlineAction;
105 protected TranslateFreeVariableLengthAction translateFreeVariableLengthAction;
106 protected RotateAction rotateAction;
107 protected RemoveAction removeAction;
108 protected RemoveAndSplitAction removeSplitAction;
109 protected RoutePipeAction routePipeAction;
110 protected AddComponentAction addComponentAction;
112 private P3DNodeMap nodeMap;
115 public void createPartControl(Composite parent) {
116 this.parent = parent;
117 parent.setLayout (new FillLayout ());
118 // component = new SWTAWTComponent(parent,SWT.NONE) {
121 // protected Component createSwingComponent() {
122 // if (panel == null) {
123 // panel = new InteractiveVtkPanel();
124 // vtkPanelUtil.registerPanel(panel);
131 IResourceEditorInput rei = (IResourceEditorInput)getEditorInput();
132 input = rei.getResource();
134 panel = new InteractiveVtkComposite(parent);
137 //IActionBars actionBars = getEditorSite().getActionBars();
143 new ContextMenuListener(panel, contextMenu);
145 cameraAction = createCameraAction();
146 panel.setDefaultAction(cameraAction);
147 panel.useDefaultAction();
148 panel.setPickType(4);
151 ControlPointFactory.preloadCache(getLibraryUri());
152 ComponentUtils.preloadCache();
153 } catch (Exception e) {
154 ExceptionUtils.logAndShowError("Cannot open Plant3D editor",e);
159 getSession().syncRequest(new ReadRequest() {
162 public void run(ReadGraph graph) throws DatabaseException {
163 System.out.println("START PLANT3D LOAD");
164 PipingRules.setEnabled(false);
165 IMappingSchema<Resource,INode> schema = getSchema(graph);
166 mapping = Mappings.createWithListening(schema);
167 rootNode = (P3DRootNode)mapping.map(graph, input);
168 // update control points.
169 // TODO : this should be optimized.
172 P3DUtil.finalizeDBLoad(rootNode);
173 nodeMap = createNodeMap(getSession(), mapping, panel,rootNode);
175 } catch (Exception e) {
176 throw new DatabaseException(e);
179 System.out.println("END PLANT3D LOAD");
183 if (rootNode == null)
184 throw new RuntimeException("Scenegraph loading failed.");
187 selectionProvider = createSelectionProvider();
189 cameraAction.addSelectionChangedListener(selectionProvider);
191 cameraAction.addHoverChangedListener(createHoverHighlhighter());
192 selectionProvider.addSelectionChangedListener(createSelectionHighlighter());
194 getSite().setSelectionProvider(selectionProvider);
195 getSite().getPage().addPostSelectionListener(selectionProvider);
197 //outlinePage = new ScenegraphOutlinePage(rootNode);
200 parent.addDisposeListener(new DisposeListener() {
203 public void widgetDisposed(DisposeEvent e) {
204 getSite().getPage().removePostSelectionListener(selectionProvider);
206 PipingRules.setEnabled(false);
208 PipingRules.setEnabled(true);
210 // component.dispose();
211 //panel.getComponent().dispose();
215 } catch (DatabaseException e1) {
216 ExceptionUtils.logAndShowError("Cannot open Plant3D editor",e1);
224 protected vtkCameraAndSelectorAction createCameraAction() {
225 return new vtkCameraAndSelectorAction(panel);
228 protected NodeSelectionProvider2<Resource,INode> createSelectionProvider() {
229 return new NodeSelectionProvider2<Resource,INode>(this,mapping,nodeMap);
232 protected HoverHighlighter<Resource> createHoverHighlhighter() {
233 return new HoverHighlighter<>(panel,nodeMap);
236 protected SelectionHighlighter<Resource> createSelectionHighlighter() {
237 return new SelectionHighlighter<Resource>(panel,nodeMap);
240 protected String getLibraryUri() {
241 return Plant3D.URIs.Builtin;
244 protected void createActions() {
245 focusAction = new FocusAction(panel, cameraAction);
246 translateAction = new TranslateAction(panel,nodeMap);
247 translateInlineAction = new TranslateInlineAction(panel, nodeMap);
248 translateFreeVariableLengthAction = new TranslateFreeVariableLengthAction(panel, getRootNode());
249 rotateAction = new RotateAction(panel,nodeMap);
250 removeAction = new RemoveAction(nodeMap);
251 removeSplitAction = new RemoveAndSplitAction(nodeMap);
252 routePipeAction = new RoutePipeAction(panel,rootNode);
253 addComponentAction = new AddComponentAction(panel, rootNode, getLibraryUri());
256 public void populate() {
257 ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
262 panel.addListener(new RenderListener() {
265 public void preRender() {
270 public void postRender() {
272 P3DUtil.finalizeDBLoad2(rootNode);
273 if (nodeMap.isRangeModified());
274 nodeMap.commit("Load sync");
275 } catch (Exception e) {
276 //throw new DatabaseException(e);
278 panel.removeListener(this);
288 protected IMappingSchema<Resource, INode> getSchema(ReadGraph graph) throws DatabaseException {
289 IMappingSchema<Resource,INode> schema = SchemaBuilder.getSchema(graph);
293 protected P3DNodeMap createNodeMap(Session session, IMapping<Resource, INode> mapping, VtkView panel, P3DRootNode rootNode) {
294 return new P3DNodeMap(session, mapping, panel,rootNode);
298 public void setFocus() {
299 //component.setFocus();
300 panel.getComponent().setFocus();
303 private void createScene() {
304 vtkRenderer ren1 = panel.getRenderer();
306 boolean multiPass = false;
307 boolean blur = false;
308 boolean ssaa = false;
309 //boolean sobel = true;
310 boolean mblur = false;
313 vtkLightsPass lightsPass = new vtkLightsPass();
314 vtkDefaultPass defaultPass = new vtkDefaultPass();
317 vtkRenderPassCollection passes = new vtkRenderPassCollection();
318 passes.AddItem(lightsPass);
319 passes.AddItem(defaultPass);
321 vtkSequencePass seq = new vtkSequencePass();
322 seq.SetPasses(passes);
324 vtkCameraPass cameraPass = new vtkCameraPass();
325 cameraPass.SetDelegatePass(seq);
328 vtkGaussianBlurPass blurPass = new vtkGaussianBlurPass();
329 blurPass.SetDelegatePass(cameraPass);
330 ren1.SetPass(blurPass);
332 vtkSSAAPass ssaaPass = new vtkSSAAPass();
333 ssaaPass.SetDelegatePass(cameraPass);
334 ren1.SetPass(ssaaPass);
336 vtkSimpleMotionBlurPass mBlurPass = new vtkSimpleMotionBlurPass();
337 mBlurPass.SetDelegatePass(cameraPass);
338 ren1.SetPass(mBlurPass);
339 // } else if (sobel) {
340 // vtkSobelGradientMagnitudePass sobelPass = new vtkSobelGradientMagnitudePass();
341 // sobelPass.SetDelegatePass(sobelPass);
342 // ren1.SetPass(sobelPass);
344 ren1.SetPass(cameraPass);
348 // ren1.GetRenderWindow().LineSmoothingOn();
349 // ren1.GetRenderWindow().PointSmoothingOn();
350 // ren1.GetRenderWindow().PolygonSmoothingOn();
351 // ren1.GetRenderWindow().SetMultiSamples(2);
355 ren1.SetBackground2(1,1,1); // background color white
356 ren1.SetBackground(0.9,0.9,0.9);
357 ren1.SetGradientBackground(true);
359 // vtkActor grid = vtkShape.createGridActor(8,1.0,1|2|4);
360 vtkActor grid = vtkShape.createGridActor(8,1.0, 2 );
363 panel.addDeletable(grid);
365 AxesDisplay axesDisplay = new AxesDisplay(panel);
370 protected Menu contextMenu;
372 protected void hookContextMenu() {
373 MenuManager menuMgr = new MenuManager("#PopupMenu");
374 menuMgr.setRemoveAllWhenShown(true);
375 menuMgr.addMenuListener(new IMenuListener() {
376 public void menuAboutToShow(IMenuManager manager) {
377 createContextMenu(manager);
381 contextMenu = menuMgr.createContextMenu(parent);
384 protected void createContextMenu(IMenuManager m) {
385 List<INode> selected = selectionProvider.getSelectedNodes();
386 List<VTKSelectionItem<Resource>> selectedItems = selectionProvider.getSelectedItems();
387 if (selectedItems.size() > 0) {
388 List<vtkProp> props = new ArrayList<>();
389 for (VTKSelectionItem<Resource> i : selectedItems) {
390 vtkProp p = (vtkProp)i.getAdapter(vtkProp.class);
394 if (props.size() > 0) {
395 focusAction.setProps(props);
400 if (selected.size() == 0) {
401 for (Item eq : P3DUtil.getEquipments(getLibraryUri())) {
402 m.add(new AddEquipmentAction(rootNode, eq));
404 } else if (selected.size() == 1) {
405 IP3DNode node = (IP3DNode)selected.get(0);
406 if (node instanceof Equipment) {
407 m.add(translateAction);
409 for (Item eq : P3DUtil.getNozzles(getLibraryUri())) {
410 AddNozzleAction add = new AddNozzleAction(rootNode, eq);
411 add.setEquipment((Equipment)node);
415 } else if (node instanceof Nozzle) {
416 Nozzle nozzle = (Nozzle)node;
417 if (!nozzle.isFixed()) {
418 m.add(translateAction);
421 m.add(routePipeAction);
422 routePipeAction.setComponent(nozzle);
423 routePipeAction.setEnabled(nozzle.getNext() == null && nozzle.getPrevious() == null);
424 m.add(addComponentAction);
425 addComponentAction.setComponent(nozzle);
427 } else if (node instanceof TurnComponent) {
428 m.add(translateAction);
429 TurnComponent component = (TurnComponent)node;
430 m.add(routePipeAction);
431 routePipeAction.setComponent(component);
432 routePipeAction.setEnabled(component.getNext() == null || component.getPrevious() == null);
433 m.add(addComponentAction);
434 addComponentAction.setComponent(component);
436 m.add(removeSplitAction);
437 removeSplitAction.setNode(node);
438 } else if (node instanceof EndComponent) {
439 m.add(translateAction);
440 m.add(addComponentAction);
441 addComponentAction.setComponent((PipelineComponent)node);
443 } else if (node instanceof InlineComponent) {
444 //m.add(translateInlineAction);
445 InlineComponent component = (InlineComponent)node;
446 if (component.isVariableLength())
447 m.add(translateFreeVariableLengthAction);
449 m.add(translateInlineAction);
450 m.add(routePipeAction);
451 routePipeAction.setComponent(component);
452 m.add(addComponentAction);
453 addComponentAction.setComponent(component);
455 m.add(removeSplitAction);
456 removeSplitAction.setNode(node);
462 translateAction.setNode(node);
463 translateInlineAction.setNode(node);
464 translateFreeVariableLengthAction.setNode(node);
465 rotateAction.setNode(node);
466 removeAction.setNode(node);
469 } catch (DatabaseException e) {
470 ExceptionUtils.logAndShowError(e);
474 private IContentOutlinePage createOutline() {
475 if (rootNode == null || selectionProvider == null)
477 //IContentOutlinePage outlinePage = new VTKContentOutlinePage<Resource,Object>(rootNode, selectionProvider);
478 IContentOutlinePage outlinePage = new P3DContentOutlinePage(rootNode, selectionProvider) {
479 protected void createContextMenu(IMenuManager manager) {
480 Plant3DEditor.this.createContextMenu(manager);
483 outlinePage.addSelectionChangedListener(new ISelectionChangedListener() {
486 public void selectionChanged(SelectionChangedEvent event) {
487 selectionProvider.selectionChanged(event);
494 public <T> T getAdapter(Class<T> adapter) {
495 if (adapter.isAssignableFrom(IPropertyPage.class))
496 return adapter.cast(new StandardPropertyPage(getSite(),getPropertyContexts()));
497 if (adapter.isAssignableFrom(ISelectionProvider.class))
498 return adapter.cast(selectionProvider);
499 if (adapter.isAssignableFrom(IContentOutlinePage.class)) {
500 return adapter.cast(createOutline());
502 if (adapter.isAssignableFrom(NodeMap.class)) {
503 return adapter.cast(nodeMap);
505 if (adapter.isAssignableFrom(INode.class)) {
506 return adapter.cast(rootNode);
508 if (adapter.isAssignableFrom(IMapping.class)) {
509 return adapter.cast(mapping);
511 // if (adapter.isAssignableFrom(InteractiveVtkPanel.class)) {
512 // return adapter.cast(panel);
514 if (adapter.isAssignableFrom(VtkView.class))
515 return adapter.cast(panel);
516 return super.getAdapter(adapter);
519 public Set<String> getPropertyContexts() {
520 Set<String> result = new HashSet<String>();
521 result.add("http://www.simantics.org/Project-1.0/ProjectBrowseContext");
525 public InteractiveVtkComposite getPanel() {
529 public P3DRootNode getRootNode() {
533 public IMapping<Resource, INode> getMapping() {
537 public P3DNodeMap getNodeMap() {