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.ReversePipeRunAction;
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.PipeRun;
61 import org.simantics.plant3d.scenegraph.PipelineComponent;
62 import org.simantics.plant3d.scenegraph.SchemaBuilder;
63 import org.simantics.plant3d.scenegraph.TurnComponent;
64 import org.simantics.plant3d.scenegraph.controlpoint.ControlPointFactory;
65 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
66 import org.simantics.plant3d.utils.ComponentUtils;
67 import org.simantics.plant3d.utils.Item;
68 import org.simantics.plant3d.utils.P3DUtil;
69 import org.simantics.selectionview.StandardPropertyPage;
70 import org.simantics.ui.workbench.IPropertyPage;
71 import org.simantics.ui.workbench.IResourceEditorInput;
72 import org.simantics.ui.workbench.ResourceEditorPart;
73 import org.simantics.utils.threads.ThreadUtils;
74 import org.simantics.utils.ui.ExceptionUtils;
77 import vtk.vtkCameraPass;
78 import vtk.vtkDefaultPass;
79 import vtk.vtkGaussianBlurPass;
80 import vtk.vtkLightsPass;
82 import vtk.vtkRenderPassCollection;
83 import vtk.vtkRenderer;
84 import vtk.vtkSSAAPass;
85 import vtk.vtkSequencePass;
86 import vtk.vtkSimpleMotionBlurPass;
89 public class Plant3DEditor extends ResourceEditorPart {
91 private Composite parent;
92 private Resource input;
93 // private InteractiveVtkPanel panel;
94 // private SWTAWTComponent component;
95 private InteractiveVtkComposite panel;
97 private P3DRootNode rootNode;
98 private IMapping<Resource,INode> mapping;
100 protected NodeSelectionProvider2<Resource, INode> selectionProvider;
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 protected ReversePipeRunAction reversePipeRunAction;
115 private P3DNodeMap nodeMap;
118 public void createPartControl(Composite parent) {
119 this.parent = parent;
120 parent.setLayout (new FillLayout ());
121 // component = new SWTAWTComponent(parent,SWT.NONE) {
124 // protected Component createSwingComponent() {
125 // if (panel == null) {
126 // panel = new InteractiveVtkPanel();
127 // vtkPanelUtil.registerPanel(panel);
134 IResourceEditorInput rei = (IResourceEditorInput)getEditorInput();
135 input = rei.getResource();
137 panel = new InteractiveVtkComposite(parent);
140 //IActionBars actionBars = getEditorSite().getActionBars();
146 new ContextMenuListener(panel, contextMenu);
148 cameraAction = createCameraAction();
149 panel.setDefaultAction(cameraAction);
150 panel.useDefaultAction();
151 panel.setPickType(4);
154 ControlPointFactory.preloadCache(getLibraryUri());
155 ComponentUtils.preloadCache();
156 } catch (Exception e) {
157 ExceptionUtils.logAndShowError("Cannot open Plant3D editor",e);
162 getSession().syncRequest(new ReadRequest() {
165 public void run(ReadGraph graph) throws DatabaseException {
166 System.out.println("START PLANT3D LOAD");
167 PipingRules.setEnabled(false);
168 IMappingSchema<Resource,INode> 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.
175 P3DUtil.finalizeDBLoad(rootNode);
176 nodeMap = createNodeMap(getSession(), mapping, panel,rootNode);
178 } catch (Exception e) {
179 throw new DatabaseException(e);
182 System.out.println("END PLANT3D LOAD");
186 if (rootNode == null)
187 throw new RuntimeException("Scenegraph loading failed.");
190 selectionProvider = createSelectionProvider();
192 cameraAction.addSelectionChangedListener(selectionProvider);
194 cameraAction.addHoverChangedListener(createHoverHighlhighter());
195 selectionProvider.addSelectionChangedListener(createSelectionHighlighter());
197 getSite().setSelectionProvider(selectionProvider);
198 getSite().getPage().addPostSelectionListener(selectionProvider);
200 //outlinePage = new ScenegraphOutlinePage(rootNode);
203 parent.addDisposeListener(new DisposeListener() {
206 public void widgetDisposed(DisposeEvent e) {
207 getSite().getPage().removePostSelectionListener(selectionProvider);
209 PipingRules.setEnabled(false);
211 PipingRules.setEnabled(true);
213 // component.dispose();
214 //panel.getComponent().dispose();
218 } catch (DatabaseException e1) {
219 ExceptionUtils.logAndShowError("Cannot open Plant3D editor",e1);
227 protected vtkCameraAndSelectorAction createCameraAction() {
228 return new vtkCameraAndSelectorAction(panel);
231 protected NodeSelectionProvider2<Resource,INode> createSelectionProvider() {
232 return new NodeSelectionProvider2<Resource,INode>(this,mapping,nodeMap);
235 protected HoverHighlighter<Resource> createHoverHighlhighter() {
236 return new HoverHighlighter<>(panel,nodeMap);
239 protected SelectionHighlighter<Resource> createSelectionHighlighter() {
240 return new SelectionHighlighter<Resource>(panel,nodeMap);
243 protected String getLibraryUri() {
244 return Plant3D.URIs.Builtin;
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 removeSplitAction = new RemoveAndSplitAction(nodeMap);
255 routePipeAction = new RoutePipeAction(panel,rootNode);
256 addComponentAction = new AddComponentAction(panel, rootNode, getLibraryUri());
257 reversePipeRunAction = new ReversePipeRunAction(nodeMap);
260 public void populate() {
261 ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
266 panel.addListener(new RenderListener() {
269 public void preRender() {
274 public void postRender() {
276 P3DUtil.finalizeDBLoad2(rootNode);
277 if (nodeMap.isRangeModified());
278 nodeMap.commit("Load sync");
279 } catch (Exception e) {
280 //throw new DatabaseException(e);
282 panel.removeListener(this);
292 protected IMappingSchema<Resource, INode> getSchema(ReadGraph graph) throws DatabaseException {
293 IMappingSchema<Resource,INode> schema = SchemaBuilder.getSchema(graph);
297 protected P3DNodeMap createNodeMap(Session session, IMapping<Resource, INode> mapping, VtkView panel, P3DRootNode rootNode) {
298 return new P3DNodeMap(session, mapping, panel,rootNode);
302 public void setFocus() {
303 //component.setFocus();
304 panel.getComponent().setFocus();
307 private void createScene() {
308 vtkRenderer ren1 = panel.getRenderer();
310 boolean multiPass = false;
311 boolean blur = false;
312 boolean ssaa = false;
313 //boolean sobel = true;
314 boolean mblur = false;
317 vtkLightsPass lightsPass = new vtkLightsPass();
318 vtkDefaultPass defaultPass = new vtkDefaultPass();
321 vtkRenderPassCollection passes = new vtkRenderPassCollection();
322 passes.AddItem(lightsPass);
323 passes.AddItem(defaultPass);
325 vtkSequencePass seq = new vtkSequencePass();
326 seq.SetPasses(passes);
328 vtkCameraPass cameraPass = new vtkCameraPass();
329 cameraPass.SetDelegatePass(seq);
332 vtkGaussianBlurPass blurPass = new vtkGaussianBlurPass();
333 blurPass.SetDelegatePass(cameraPass);
334 ren1.SetPass(blurPass);
336 vtkSSAAPass ssaaPass = new vtkSSAAPass();
337 ssaaPass.SetDelegatePass(cameraPass);
338 ren1.SetPass(ssaaPass);
340 vtkSimpleMotionBlurPass mBlurPass = new vtkSimpleMotionBlurPass();
341 mBlurPass.SetDelegatePass(cameraPass);
342 ren1.SetPass(mBlurPass);
343 // } else if (sobel) {
344 // vtkSobelGradientMagnitudePass sobelPass = new vtkSobelGradientMagnitudePass();
345 // sobelPass.SetDelegatePass(sobelPass);
346 // ren1.SetPass(sobelPass);
348 ren1.SetPass(cameraPass);
352 // ren1.GetRenderWindow().LineSmoothingOn();
353 // ren1.GetRenderWindow().PointSmoothingOn();
354 // ren1.GetRenderWindow().PolygonSmoothingOn();
355 // ren1.GetRenderWindow().SetMultiSamples(2);
359 ren1.SetBackground2(1,1,1); // background color white
360 ren1.SetBackground(0.9,0.9,0.9);
361 ren1.SetGradientBackground(true);
363 // vtkActor grid = vtkShape.createGridActor(8,1.0,1|2|4);
364 vtkActor grid = vtkShape.createGridActor(8,1.0, 2 );
367 panel.addDeletable(grid);
369 AxesDisplay axesDisplay = new AxesDisplay(panel);
374 protected Menu contextMenu;
376 protected void hookContextMenu() {
377 MenuManager menuMgr = new MenuManager("#PopupMenu");
378 menuMgr.setRemoveAllWhenShown(true);
379 menuMgr.addMenuListener(new IMenuListener() {
380 public void menuAboutToShow(IMenuManager manager) {
381 createContextMenu(manager);
385 contextMenu = menuMgr.createContextMenu(parent);
388 protected void createContextMenu(IMenuManager m) {
389 List<INode> selected = selectionProvider.getSelectedNodes();
390 List<VTKSelectionItem<Resource>> selectedItems = selectionProvider.getSelectedItems();
391 if (selectedItems.size() > 0) {
392 List<vtkProp> props = new ArrayList<>();
393 for (VTKSelectionItem<Resource> i : selectedItems) {
394 vtkProp p = (vtkProp)i.getAdapter(vtkProp.class);
398 if (props.size() > 0) {
399 focusAction.setProps(props);
404 if (selected.size() == 0) {
405 for (Item eq : P3DUtil.getEquipments(getLibraryUri())) {
406 m.add(new AddEquipmentAction(rootNode, eq));
408 } else if (selected.size() == 1) {
409 IP3DNode node = (IP3DNode)selected.get(0);
410 if (node instanceof Equipment) {
411 m.add(translateAction);
413 for (Item eq : P3DUtil.getNozzles(getLibraryUri())) {
414 AddNozzleAction add = new AddNozzleAction(rootNode, eq);
415 add.setEquipment((Equipment)node);
419 } else if (node instanceof Nozzle) {
420 Nozzle nozzle = (Nozzle)node;
421 if (!nozzle.isFixed()) {
422 m.add(translateAction);
425 m.add(routePipeAction);
426 routePipeAction.setComponent(nozzle);
427 routePipeAction.setEnabled(nozzle.getNext() == null && nozzle.getPrevious() == null);
428 m.add(addComponentAction);
429 addComponentAction.setComponent(nozzle);
431 } else if (node instanceof TurnComponent) {
432 m.add(translateAction);
433 TurnComponent component = (TurnComponent)node;
434 m.add(routePipeAction);
435 routePipeAction.setComponent(component);
436 routePipeAction.setEnabled(component.getNext() == null || component.getPrevious() == null);
437 m.add(addComponentAction);
438 addComponentAction.setComponent(component);
440 m.add(removeSplitAction);
441 removeSplitAction.setNode(node);
442 } else if (node instanceof EndComponent) {
443 m.add(translateAction);
444 m.add(addComponentAction);
445 addComponentAction.setComponent((PipelineComponent)node);
447 } else if (node instanceof InlineComponent) {
448 //m.add(translateInlineAction);
449 InlineComponent component = (InlineComponent)node;
450 if (component.isVariableLength())
451 m.add(translateFreeVariableLengthAction);
453 m.add(translateInlineAction);
454 m.add(routePipeAction);
455 routePipeAction.setComponent(component);
456 m.add(addComponentAction);
457 addComponentAction.setComponent(component);
459 m.add(removeSplitAction);
460 removeSplitAction.setNode(node);
461 } else if (node instanceof PipeRun) {
462 m.add(reversePipeRunAction);
464 reversePipeRunAction.setNode(node);
470 translateAction.setNode(node);
471 translateInlineAction.setNode(node);
472 translateFreeVariableLengthAction.setNode(node);
473 rotateAction.setNode(node);
474 removeAction.setNode(node);
477 } catch (DatabaseException e) {
478 ExceptionUtils.logAndShowError(e);
482 private IContentOutlinePage createOutline() {
483 if (rootNode == null || selectionProvider == 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);
491 outlinePage.addSelectionChangedListener(new ISelectionChangedListener() {
494 public void selectionChanged(SelectionChangedEvent event) {
495 selectionProvider.selectionChanged(event);
502 public <T> T getAdapter(Class<T> adapter) {
503 if (adapter.isAssignableFrom(IPropertyPage.class))
504 return adapter.cast(new StandardPropertyPage(getSite(),getPropertyContexts()));
505 if (adapter.isAssignableFrom(ISelectionProvider.class))
506 return adapter.cast(selectionProvider);
507 if (adapter.isAssignableFrom(IContentOutlinePage.class)) {
508 return adapter.cast(createOutline());
510 if (adapter.isAssignableFrom(NodeMap.class)) {
511 return adapter.cast(nodeMap);
513 if (adapter.isAssignableFrom(INode.class)) {
514 return adapter.cast(rootNode);
516 if (adapter.isAssignableFrom(IMapping.class)) {
517 return adapter.cast(mapping);
519 // if (adapter.isAssignableFrom(InteractiveVtkPanel.class)) {
520 // return adapter.cast(panel);
522 if (adapter.isAssignableFrom(VtkView.class))
523 return adapter.cast(panel);
524 return super.getAdapter(adapter);
527 public Set<String> getPropertyContexts() {
528 Set<String> result = new HashSet<String>();
529 result.add("http://www.simantics.org/Project-1.0/ProjectBrowseContext");
533 public InteractiveVtkComposite getPanel() {
537 public P3DRootNode getRootNode() {
541 public IMapping<Resource, INode> getMapping() {
545 public P3DNodeMap getNodeMap() {