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;
85 import vtk.vtkSobelGradientMagnitudePass;
88 public class Plant3DEditor extends ResourceEditorPart {
90 private Composite parent;
91 private Resource input;
92 // private InteractiveVtkPanel panel;
93 // private SWTAWTComponent component;
94 private InteractiveVtkComposite panel;
96 private P3DRootNode rootNode;
97 private IMapping<Resource,INode> mapping;
99 protected NodeSelectionProvider2<Resource, INode> selectionProvider;
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;
113 private P3DNodeMap nodeMap;
116 public void createPartControl(Composite parent) {
117 this.parent = parent;
118 parent.setLayout (new FillLayout ());
119 // component = new SWTAWTComponent(parent,SWT.NONE) {
122 // protected Component createSwingComponent() {
123 // if (panel == null) {
124 // panel = new InteractiveVtkPanel();
125 // vtkPanelUtil.registerPanel(panel);
132 IResourceEditorInput rei = (IResourceEditorInput)getEditorInput();
133 input = rei.getResource();
135 panel = new InteractiveVtkComposite(parent);
138 //IActionBars actionBars = getEditorSite().getActionBars();
144 new ContextMenuListener(panel, contextMenu);
146 cameraAction = createCameraAction();
147 panel.setDefaultAction(cameraAction);
148 panel.useDefaultAction();
149 panel.setPickType(4);
152 ControlPointFactory.preloadCache(getLibraryUri());
153 ComponentUtils.preloadCache();
154 } catch (Exception e) {
155 ExceptionUtils.logAndShowError("Cannot open Plant3D editor",e);
160 getSession().syncRequest(new ReadRequest() {
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.
173 P3DUtil.finalizeDBLoad(rootNode);
174 nodeMap = createNodeMap(getSession(), mapping, panel,rootNode);
176 } catch (Exception e) {
177 throw new DatabaseException(e);
180 System.out.println("END PLANT3D LOAD");
184 if (rootNode == null)
185 throw new RuntimeException("Scenegraph loading failed.");
188 selectionProvider = createSelectionProvider();
190 cameraAction.addSelectionChangedListener(selectionProvider);
192 cameraAction.addHoverChangedListener(createHoverHighlhighter());
193 selectionProvider.addSelectionChangedListener(createSelectionHighlighter());
195 getSite().setSelectionProvider(selectionProvider);
196 getSite().getPage().addPostSelectionListener(selectionProvider);
198 //outlinePage = new ScenegraphOutlinePage(rootNode);
201 parent.addDisposeListener(new DisposeListener() {
204 public void widgetDisposed(DisposeEvent e) {
205 getSite().getPage().removePostSelectionListener(selectionProvider);
207 PipingRules.setEnabled(false);
209 PipingRules.setEnabled(true);
211 // component.dispose();
212 //panel.getComponent().dispose();
216 } catch (DatabaseException e1) {
217 ExceptionUtils.logAndShowError("Cannot open Plant3D editor",e1);
225 protected vtkCameraAndSelectorAction createCameraAction() {
226 return new vtkCameraAndSelectorAction(panel);
229 protected NodeSelectionProvider2<Resource,INode> createSelectionProvider() {
230 return new NodeSelectionProvider2<Resource,INode>(this,mapping,nodeMap);
233 protected HoverHighlighter createHoverHighlhighter() {
234 return new HoverHighlighter(panel,nodeMap);
237 protected SelectionHighlighter<Resource,INode> createSelectionHighlighter() {
238 return new SelectionHighlighter<Resource,INode>(panel,nodeMap);
241 protected String getLibraryUri() {
242 return Plant3D.URIs.Builtin;
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());
257 public void populate() {
258 ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
263 panel.addListener(new RenderListener() {
266 public void preRender() {
271 public void postRender() {
273 P3DUtil.finalizeDBLoad2(rootNode);
274 if (nodeMap.isRangeModified());
275 nodeMap.commit("Load sync");
276 } catch (Exception e) {
277 //throw new DatabaseException(e);
279 panel.removeListener(this);
289 protected IMappingSchema<Resource, INode> getSchema(ReadGraph graph) throws DatabaseException {
290 IMappingSchema<Resource,INode> schema = SchemaBuilder.getSchema(graph);
294 protected P3DNodeMap createNodeMap(Session session, IMapping<Resource, INode> mapping, VtkView panel, P3DRootNode rootNode) {
295 return new P3DNodeMap(session, mapping, panel,rootNode);
299 public void setFocus() {
300 //component.setFocus();
301 panel.getComponent().setFocus();
304 private void createScene() {
305 vtkRenderer ren1 = panel.getRenderer();
307 boolean multiPass = false;
308 boolean blur = false;
309 boolean ssaa = false;
310 //boolean sobel = true;
311 boolean mblur = false;
314 vtkLightsPass lightsPass = new vtkLightsPass();
315 vtkDefaultPass defaultPass = new vtkDefaultPass();
318 vtkRenderPassCollection passes = new vtkRenderPassCollection();
319 passes.AddItem(lightsPass);
320 passes.AddItem(defaultPass);
322 vtkSequencePass seq = new vtkSequencePass();
323 seq.SetPasses(passes);
325 vtkCameraPass cameraPass = new vtkCameraPass();
326 cameraPass.SetDelegatePass(seq);
329 vtkGaussianBlurPass blurPass = new vtkGaussianBlurPass();
330 blurPass.SetDelegatePass(cameraPass);
331 ren1.SetPass(blurPass);
333 vtkSSAAPass ssaaPass = new vtkSSAAPass();
334 ssaaPass.SetDelegatePass(cameraPass);
335 ren1.SetPass(ssaaPass);
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);
345 ren1.SetPass(cameraPass);
349 // ren1.GetRenderWindow().LineSmoothingOn();
350 // ren1.GetRenderWindow().PointSmoothingOn();
351 // ren1.GetRenderWindow().PolygonSmoothingOn();
352 // ren1.GetRenderWindow().SetMultiSamples(2);
356 ren1.SetBackground2(1,1,1); // background color white
357 ren1.SetBackground(0.9,0.9,0.9);
358 ren1.SetGradientBackground(true);
360 // vtkActor grid = vtkShape.createGridActor(8,1.0,1|2|4);
361 vtkActor grid = vtkShape.createGridActor(8,1.0, 2 );
364 panel.addDeletable(grid);
366 AxesDisplay axesDisplay = new AxesDisplay(panel);
371 protected Menu contextMenu;
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);
382 contextMenu = menuMgr.createContextMenu(parent);
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);
395 if (props.size() > 0) {
396 focusAction.setProps(props);
401 if (selected.size() == 0) {
402 for (Item eq : P3DUtil.getEquipments(getLibraryUri())) {
403 m.add(new AddEquipmentAction(rootNode, eq));
405 } else if (selected.size() == 1) {
406 IP3DNode node = (IP3DNode)selected.get(0);
407 if (node instanceof Equipment) {
408 m.add(translateAction);
410 for (Item eq : P3DUtil.getNozzles(getLibraryUri())) {
411 AddNozzleAction add = new AddNozzleAction(rootNode, eq);
412 add.setEquipment((Equipment)node);
416 } else if (node instanceof Nozzle) {
417 Nozzle nozzle = (Nozzle)node;
418 if (!nozzle.isFixed()) {
419 m.add(translateAction);
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);
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);
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);
444 } else if (node instanceof InlineComponent) {
445 //m.add(translateInlineAction);
446 InlineComponent component = (InlineComponent)node;
447 if (component.isVariableLength())
448 m.add(translateFreeVariableLengthAction);
450 m.add(translateInlineAction);
451 m.add(routePipeAction);
452 routePipeAction.setComponent(component);
453 m.add(addComponentAction);
454 addComponentAction.setComponent(component);
456 m.add(removeSplitAction);
457 removeSplitAction.setNode(node);
463 translateAction.setNode(node);
464 translateInlineAction.setNode(node);
465 translateFreeVariableLengthAction.setNode(node);
466 rotateAction.setNode(node);
467 removeAction.setNode(node);
470 } catch (DatabaseException e) {
471 ExceptionUtils.logAndShowError(e);
475 private IContentOutlinePage createOutline() {
476 if (rootNode == null || selectionProvider == 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);
484 outlinePage.addSelectionChangedListener(new ISelectionChangedListener() {
487 public void selectionChanged(SelectionChangedEvent event) {
488 selectionProvider.selectionChanged(event);
494 @SuppressWarnings("rawtypes")
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();
502 if (NodeMap.class.equals(adapter)) {
505 if (INode.class.equals(adapter)) {
508 if (IMapping.class.equals(adapter)) {
511 // if (InteractiveVtkPanel.class.equals(adapter)) {
514 if (VtkView.class.equals(adapter))
516 if (ISelectionProvider.class.equals(adapter))
517 return selectionProvider;
518 return super.getAdapter(adapter);
521 public Set<String> getPropertyContexts() {
522 Set<String> result = new HashSet<String>();
523 result.add("http://www.simantics.org/Project-1.0/ProjectBrowseContext");
527 public InteractiveVtkComposite getPanel() {
531 public P3DRootNode getRootNode() {
535 public IMapping<Resource, INode> getMapping() {
539 public P3DNodeMap getNodeMap() {