]> gerrit.simantics Code Review - simantics/3d.git/commitdiff
Using SWT thread with Plant3d 67/3067/5
authorMarko Luukkainen <marko.luukkainen@semantum.fi>
Wed, 7 Aug 2019 14:46:11 +0000 (17:46 +0300)
committerMarko Luukkainen <marko.luukkainen@semantum.fi>
Wed, 7 Aug 2019 15:07:47 +0000 (18:07 +0300)
gitlab #21

Change-Id: I15483236ec95a4e41622c71db182e0a2d6bbaaac

54 files changed:
org.simantics.g3d.csg/src/org/simantics/g3d/csg/editor/CSGEditor2.java
org.simantics.g3d.csg/src/org/simantics/g3d/csg/editor/CSGNodeMap.java
org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/CSGnode.java
org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/CSGparentNode.java
org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/ICSGnode.java
org.simantics.g3d.vtk/META-INF/MANIFEST.MF
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/vtkAction.java
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/ContextMenuListener.java [moved from org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/ContextMenuListener.java with 95% similarity]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/InteractiveVtkPanel.java [moved from org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/InteractiveVtkPanel.java with 93% similarity]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/RotateAction.java [moved from org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/RotateAction.java with 95% similarity]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/TranslateAction.java [moved from org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/TranslateAction.java with 96% similarity]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkAwtAction.java [new file with mode: 0644]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkCameraAndSelectorAction.java [moved from org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/vtkCameraAndSelectorAction.java with 98% similarity]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/AbstractVTKNodeMap.java
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/HoverHighlighter.java
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/SelectionHighlighter.java
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/VtkView.java [new file with mode: 0644]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/RotateAxisGizmo.java
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/TranslateAxisGizmo.java
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/vtkGizmo.java
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/handlers/CameraPositionHandler.java
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/handlers/ParallelPerspectiveHandler.java
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/property/VTKPropertyTabContributor.java
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/shape/vtkMeshObject.java
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/ContextMenuListener.java [new file with mode: 0644]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/InteractiveVtkComposite.java [new file with mode: 0644]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/RotateAction.java [new file with mode: 0644]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/TranslateAction.java [new file with mode: 0644]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java [new file with mode: 0644]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkSwtAction.java [new file with mode: 0644]
org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/utils/AxesDisplay.java
org.simantics.g3d/src/org/simantics/g3d/gizmo/Gizmo.java
org.simantics.g3d/src/org/simantics/g3d/property/AnnotatedPropertyTabContributorFactory.java
org.simantics.opencascade.vtk/META-INF/MANIFEST.MF
org.simantics.opencascade.vtk/src/org/simantics/opencascade/vtk/vtkSolidObject.java
org.simantics.plant3d/META-INF/MANIFEST.MF
org.simantics.plant3d/src/org/simantics/plant3d/actions/AddComponentAction.java
org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java
org.simantics.plant3d/src/org/simantics/plant3d/actions/TranslateInlineAction.java
org.simantics.plant3d/src/org/simantics/plant3d/editor/P3DNodeMap.java
org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java
org.simantics.plant3d/src/org/simantics/plant3d/gizmo/SplitPointSelectionGizmo.java
org.simantics.plant3d/src/org/simantics/plant3d/gizmo/TerminalSelectionGizmo.java
org.simantics.plant3d/src/org/simantics/plant3d/property/P3DSelectionProcessor.java
org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/GeometryComponent.java
org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/GeometryNode.java
org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/IP3DVisualNode.java
org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/P3DParentGeometryNode.java
org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java
pom.xml
vtk.lib.feature/feature.xml
vtk.lib.feature/pom.xml
vtk.rendering.win32.win32.x86_64/pom.xml [new file with mode: 0644]
vtk.rendering/pom.xml

index 8f5db6554a0808ffacf4d581c6a28352baa02f51..bed448737e623040ddf4ca9809f62e3d3135e3d5 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.csg.editor;\r
-\r
-import java.awt.Component;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-\r
-import org.eclipse.jface.action.IMenuListener;\r
-import org.eclipse.jface.action.IMenuManager;\r
-import org.eclipse.jface.action.MenuManager;\r
-import org.eclipse.jface.viewers.ISelectionChangedListener;\r
-import org.eclipse.jface.viewers.SelectionChangedEvent;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.events.DisposeEvent;\r
-import org.eclipse.swt.events.DisposeListener;\r
-import org.eclipse.swt.layout.FillLayout;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.Menu;\r
-import org.eclipse.ui.views.contentoutline.IContentOutlinePage;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.common.request.ReadRequest;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.g3d.csg.actions.AddBooleanOpAction2;\r
-import org.simantics.g3d.csg.actions.AddPrimitiveAction2;\r
-import org.simantics.g3d.csg.actions.SplitBooleanOpAction2;\r
-import org.simantics.g3d.csg.scenegraph2.BarrelNode;\r
-import org.simantics.g3d.csg.scenegraph2.BoxNode;\r
-import org.simantics.g3d.csg.scenegraph2.CSGparentNode;\r
-import org.simantics.g3d.csg.scenegraph2.CSGrootNode;\r
-import org.simantics.g3d.csg.scenegraph2.ConeNode;\r
-import org.simantics.g3d.csg.scenegraph2.CylinderNode;\r
-import org.simantics.g3d.csg.scenegraph2.DifferenceNode;\r
-import org.simantics.g3d.csg.scenegraph2.EllipticCylinderNode;\r
-import org.simantics.g3d.csg.scenegraph2.ICSGnode;\r
-import org.simantics.g3d.csg.scenegraph2.IntersectionNode;\r
-import org.simantics.g3d.csg.scenegraph2.RectangularSolidNode;\r
-import org.simantics.g3d.csg.scenegraph2.RegularPrismNode;\r
-import org.simantics.g3d.csg.scenegraph2.SchemaBuilder;\r
-import org.simantics.g3d.csg.scenegraph2.SphereNode;\r
-import org.simantics.g3d.csg.scenegraph2.TorusNode;\r
-import org.simantics.g3d.csg.scenegraph2.UnionNode;\r
-import org.simantics.g3d.scenegraph.IG3DNode;\r
-import org.simantics.g3d.scenegraph.NodeMap;\r
-import org.simantics.g3d.scenegraph.base.INode;\r
-import org.simantics.g3d.vtk.action.RemoveAction;\r
-import org.simantics.g3d.vtk.action.RotateAction;\r
-import org.simantics.g3d.vtk.action.TranslateAction;\r
-import org.simantics.g3d.vtk.action.vtkCameraAndSelectorAction;\r
-import org.simantics.g3d.vtk.common.HoverHighlighter;\r
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;\r
-import org.simantics.g3d.vtk.common.NodeSelectionProvider2;\r
-import org.simantics.g3d.vtk.common.SelectionHighlighter;\r
-import org.simantics.g3d.vtk.common.VTKContentOutlinePage;\r
-import org.simantics.g3d.vtk.shape.vtkShape;\r
-import org.simantics.g3d.vtk.utils.vtkPanelUtil;\r
-import org.simantics.objmap.graph.IMapping;\r
-import org.simantics.objmap.graph.Mappings;\r
-import org.simantics.objmap.graph.schema.IMappingSchema;\r
-import org.simantics.selectionview.StandardPropertyPage;\r
-import org.simantics.ui.workbench.IPropertyPage;\r
-import org.simantics.ui.workbench.IResourceEditorInput;\r
-import org.simantics.ui.workbench.ResourceEditorPart;\r
-import org.simantics.utils.threads.AWTThread;\r
-import org.simantics.utils.threads.ThreadUtils;\r
-import org.simantics.utils.ui.ExceptionUtils;\r
-import org.simantics.utils.ui.SWTAWTComponent;\r
-\r
-import vtk.vtkActor;\r
-import vtk.vtkCameraPass;\r
-import vtk.vtkDefaultPass;\r
-import vtk.vtkLightsPass;\r
-import vtk.vtkRenderPassCollection;\r
-import vtk.vtkRenderer;\r
-import vtk.vtkSequencePass;\r
-\r
-public class CSGEditor2  extends ResourceEditorPart {\r
-       private Composite parent;\r
-       private Resource input;\r
-       private InteractiveVtkPanel panel;\r
-       private SWTAWTComponent component;\r
-       \r
-       private CSGrootNode rootNode;\r
-       private IMapping<Resource,Object> mapping;\r
-       \r
-       private NodeSelectionProvider2<Resource,Object> selectionProvider;\r
-       \r
-       private vtkCameraAndSelectorAction cameraAction;\r
-       private TranslateAction translateAction;\r
-       private RotateAction rotateAction;\r
-       private RemoveAction removeAction;\r
-       \r
-       //private  ScenegraphOutlinePage outlinePage;\r
-       \r
-       private CSGNodeMap nodeMap;\r
-\r
-\r
-\r
-       @Override\r
-       public void createPartControl(Composite parent) {\r
-               this.parent = parent;\r
-               parent.setLayout (new FillLayout ());\r
-               component = new SWTAWTComponent(parent,SWT.NONE) {\r
-                       \r
-                       @Override\r
-                       protected Component createSwingComponent() {\r
-                               if (panel == null) {\r
-                                       panel = new InteractiveVtkPanel();\r
-                                       vtkPanelUtil.registerPanel(panel);\r
-                                       createScene();\r
-                               }\r
-                               return panel;\r
-                       }\r
-               };\r
-\r
-               IResourceEditorInput rei = (IResourceEditorInput)getEditorInput();\r
-               input = rei.getResource();\r
-               \r
-               \r
-               //IActionBars actionBars = getEditorSite().getActionBars();\r
-\r
-               hookContextMenu();\r
-               \r
-               component.syncPopulate();\r
-               \r
-               panel.addMouseListener(new java.awt.event.MouseAdapter() {\r
-                       @Override\r
-                       public void mouseClicked(final java.awt.event.MouseEvent e) {\r
-                               if (e.getButton() == java.awt.event.MouseEvent.BUTTON3) {\r
-                                       Display.getDefault().asyncExec(new Runnable() {\r
-                                               public void run() {\r
-                                                       contextMenu.setLocation(e.getXOnScreen(), e.getYOnScreen());\r
-                                                       contextMenu.setVisible(true);\r
-                                               }\r
-                                       });\r
-                               }\r
-                       }\r
-               });\r
-               \r
-\r
-               cameraAction = new vtkCameraAndSelectorAction(panel);   \r
-               panel.setDefaultAction(cameraAction);\r
-               panel.useDefaultAction();\r
-               \r
-               try {\r
-                       getSession().syncRequest(new ReadRequest() {\r
-                               \r
-                               @SuppressWarnings({ "rawtypes", "unchecked" })\r
-                               @Override\r
-                               public void run(ReadGraph graph) throws DatabaseException {\r
-                                       IMappingSchema schema = SchemaBuilder.getSchema(graph);\r
-                                       mapping = Mappings.createWithListening(schema);\r
-                                       rootNode = (CSGrootNode)mapping.map(graph, input);\r
-                                       nodeMap = new CSGNodeMap(getSession(), mapping, panel,(CSGrootNode)rootNode);\r
-                               }\r
-                       });\r
-                       \r
-                       if (rootNode == null)\r
-                               throw new RuntimeException("Scenegraph loading failed.");\r
-                       populate();\r
-                       \r
-                       selectionProvider = new NodeSelectionProvider2<Resource,Object>(this,mapping,nodeMap);\r
-\r
-                       cameraAction.addSelectionChangedListener(selectionProvider);\r
-\r
-                       cameraAction.addHoverChangedListener(new HoverHighlighter(panel,nodeMap));\r
-                       selectionProvider.addSelectionChangedListener(new SelectionHighlighter(panel,nodeMap));\r
-                       \r
-                       getSite().setSelectionProvider(selectionProvider);\r
-                       getSite().getPage().addPostSelectionListener(selectionProvider);\r
-                       \r
-                       //outlinePage = new ScenegraphOutlinePage(rootNode);\r
-                       \r
-                       \r
-                       parent.addDisposeListener(new DisposeListener() {\r
-                               \r
-                               @Override\r
-                               public void widgetDisposed(DisposeEvent e) {\r
-                                       getSite().getPage().removePostSelectionListener(selectionProvider);\r
-                                       ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {\r
-                                               \r
-                                               @Override\r
-                                               public void run() {\r
-                                                       nodeMap.delete();\r
-                                                       vtkPanelUtil.unregisterPanel(panel);\r
-\r
-                                               }\r
-                                       });\r
-                                       mapping.dispose();\r
-                                       component.dispose();\r
-                                       \r
-                                       \r
-                               }\r
-                       });\r
-               } catch (DatabaseException e1) {\r
-                       ExceptionUtils.logAndShowError("Cannot open CSG editor",e1);\r
-                       return;\r
-               }\r
-               \r
-               translateAction = new TranslateAction(panel,nodeMap);\r
-               rotateAction = new RotateAction(panel,nodeMap);\r
-               removeAction = new RemoveAction(nodeMap) {\r
-                       public void setNode(IG3DNode node) {\r
-                               super.setNode(node);\r
-                               if (node.getParent() instanceof CSGparentNode)\r
-                                       setEnabled(false);\r
-                               \r
-                       }\r
-               };\r
-               \r
-               \r
-       }\r
-       \r
-       \r
-\r
-       \r
-       public void populate() {\r
-               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {\r
-                       \r
-                       @Override\r
-                       public void run() {\r
-                               nodeMap.populate();\r
-                       }\r
-               });\r
-               \r
-       }\r
-       \r
-       \r
-       \r
-       @Override\r
-       public void setFocus() {\r
-               component.setFocus();\r
-       }\r
-       \r
-       private void createScene() {\r
-               vtkRenderer ren1 = panel.GetRenderer();\r
-               \r
-               boolean multiPass = false;\r
-               if (multiPass) {\r
-                       \r
-                       vtkLightsPass lightsPass = new vtkLightsPass();\r
-                       vtkDefaultPass defaultPass = new vtkDefaultPass();\r
-                       \r
-                       \r
-                       vtkRenderPassCollection passes = new vtkRenderPassCollection();\r
-                       passes.AddItem(lightsPass);\r
-                       passes.AddItem(defaultPass);\r
-                       \r
-                       vtkSequencePass seq = new vtkSequencePass();\r
-                       seq.SetPasses(passes);\r
-                       \r
-               \r
-                       \r
-                       vtkCameraPass cameraPass = new vtkCameraPass();\r
-                       cameraPass.SetDelegatePass(seq);\r
-                       \r
-                       ren1.SetPass(cameraPass);\r
-                       \r
-               }\r
-//             ren1.GetRenderWindow().LineSmoothingOn();\r
-//             ren1.GetRenderWindow().PointSmoothingOn();\r
-//             ren1.GetRenderWindow().PolygonSmoothingOn();\r
-//             ren1.GetRenderWindow().SetMultiSamples(2);\r
-\r
-               \r
-\r
-               ren1.SetBackground2(1,1,1); // background color white\r
-               ren1.SetBackground(0.9,0.9,0.9);\r
-               ren1.SetGradientBackground(true);\r
-\r
-          // vtkActor grid = vtkShape.createGridActor(8,1.0,1|2|4);\r
-           vtkActor grid = vtkShape.createGridActor(8,1.0, 2 );\r
-           grid.SetPickable(0);\r
-           ren1.AddActor(grid);\r
-           panel.addDeletable(grid);\r
-           \r
-\r
-               \r
-       }\r
-       \r
-       protected Menu contextMenu;\r
-       \r
-       protected void hookContextMenu() {\r
-        MenuManager menuMgr = new MenuManager("#PopupMenu");\r
-        menuMgr.setRemoveAllWhenShown(true);\r
-        menuMgr.addMenuListener(new IMenuListener() {\r
-            public void menuAboutToShow(IMenuManager manager) {\r
-               final IMenuManager m = manager;\r
-                       List<IG3DNode> selected = selectionProvider.getSelectedNodes();\r
-                       if (selected.size() == 0) {\r
-                               m.add(new AddPrimitiveAction2(rootNode, BarrelNode.class));\r
-                               m.add(new AddPrimitiveAction2(rootNode, BoxNode.class));\r
-                               m.add(new AddPrimitiveAction2(rootNode, ConeNode.class));\r
-                               m.add(new AddPrimitiveAction2(rootNode, CylinderNode.class));\r
-                               m.add(new AddPrimitiveAction2(rootNode, EllipticCylinderNode.class));\r
-                               m.add(new AddPrimitiveAction2(rootNode, RectangularSolidNode.class));\r
-                               m.add(new AddPrimitiveAction2(rootNode, RegularPrismNode.class));\r
-                               m.add(new AddPrimitiveAction2(rootNode, SphereNode.class));\r
-                               m.add(new AddPrimitiveAction2(rootNode, TorusNode.class));\r
-                       } else if (selected.size() == 1) {\r
-                               m.add(translateAction);\r
-                                       m.add(rotateAction);\r
-                                       m.add(removeAction);\r
-                                       ICSGnode node = (ICSGnode)selected.get(0);\r
-                                       translateAction.setNode(node);\r
-                                       rotateAction.setNode(node);\r
-                                       removeAction.setNode(node);\r
-                                       if (node instanceof CSGparentNode) {\r
-                                               m.add(new SplitBooleanOpAction2(rootNode,(CSGparentNode)node));\r
-                                       }\r
-                       } else if (selected.size() == 2) {\r
-                               if (selected.get(0).getParent().equals(rootNode) && selected.get(1).getParent().equals(rootNode)) {\r
-                                       Collection<ICSGnode> nodes = new ArrayList<ICSGnode>();\r
-                                       for (IG3DNode n : selected)\r
-                                               nodes.add((ICSGnode)n);\r
-                                       m.add(new AddBooleanOpAction2(rootNode, DifferenceNode.class, nodes));\r
-                                       m.add(new AddBooleanOpAction2(rootNode, IntersectionNode.class, nodes));\r
-                                       m.add(new AddBooleanOpAction2(rootNode, UnionNode.class, nodes));\r
-                               }\r
-                       }\r
-//             try {\r
-//                                     SimanticsUI.getSession().syncRequest(new ReadRequest() {\r
-//                                             \r
-//                                             @Override\r
-//                                             public void run(ReadGraph graph) throws DatabaseException {\r
-//                                                     Layer0 l0 = Layer0.getInstance(graph);\r
-//                                                     CSG csg = CSG.getInstance(graph);\r
-//                                                     Resource ontology = graph.getResource("http://www.simantics.org/CSG-0.1");\r
-//                                                     \r
-//                                                     if (selectionProvider.getSelectedResources().size() == 0) {\r
-//                                                             List<NamedResource> primitives = new ArrayList<NamedResource>();\r
-//                                                             for (Resource r : graph.getObjects(ontology, l0.ConsistsOf)) {\r
-//                                                                     if (graph.isInheritedFrom(r, csg.Primitive) && !r.equals(csg.Primitive)) {\r
-//                                                                             primitives.add(new NamedResource((String)graph.getRelatedValue(r, l0.HasName), r));\r
-//                                                                     }\r
-//                                                             }\r
-//                                                             \r
-//                                                             Collections.sort(primitives);\r
-//                                                             for (NamedResource n : primitives) {\r
-//                                                                     m.add(new AddPrimitiveAction(graph, n.getResource(),input));\r
-//                                                             }\r
-//                                                     }\r
-//                                                     if (selectionProvider.getSelectedResources().size() == 2) {\r
-//                                                             List<NamedResource> booleanOps = new ArrayList<NamedResource>();\r
-//                                                             for (Resource r : graph.getObjects(ontology, l0.ConsistsOf)) {\r
-//                                                                     if (graph.isInheritedFrom(r, csg.BooleanOperation) && !r.equals(csg.BooleanOperation)) {\r
-//                                                                             booleanOps.add(new NamedResource((String)graph.getRelatedValue(r, l0.HasName), r));\r
-//                                                                     }\r
-//                                                             }\r
-//                                                             \r
-//                                                             Collections.sort(booleanOps);\r
-//                                                             for (NamedResource n : booleanOps) {\r
-//                                                                     m.add(new AddBooleanOpAction(graph, n.getResource(), input, selectionProvider.getSelectedResources()));\r
-//                                                             }\r
-//                                                     }\r
-//                                                     if (selectionProvider.getSelectedResources().size() == 1) {\r
-//                                                             m.add(translateAction);\r
-//                                                             m.add(rotateAction);\r
-//                                                             m.add(removeAction);\r
-//                                                             Resource selected = selectionProvider.getSelectedResources().get(0);\r
-//                                                             translateAction.setNode((IG3DNode2)mapping.get(selected));\r
-//                                                             rotateAction.setNode((IG3DNode2)mapping.get(selected));\r
-//                                                             removeAction.setNode((IG3DNode2)mapping.get(selected));\r
-//                                                             if (graph.isInstanceOf(selected, csg.BooleanOperation)) {\r
-//                                                                     m.add(new SplitBooleanOpAction(input,selected));\r
-//                                                             }\r
-//                                                             \r
-//                                                             \r
-//                                                     }\r
-//                                                     \r
-//                                             }\r
-//                                     });\r
-//                             } catch (DatabaseException e) {\r
-//                                     // TODO Auto-generated catch block\r
-//                                     e.printStackTrace();\r
-//                             }\r
-                \r
-            }\r
-        });\r
-\r
-        contextMenu = menuMgr.createContextMenu(parent);\r
-    }\r
-       \r
-       private IContentOutlinePage createOutline() {\r
-               if (rootNode == null || selectionProvider == null)\r
-                       return null;\r
-               IContentOutlinePage outlinePage = new VTKContentOutlinePage<Resource,Object>(rootNode, selectionProvider);\r
-               outlinePage.addSelectionChangedListener(new ISelectionChangedListener() {\r
-                       \r
-                       @Override\r
-                       public void selectionChanged(SelectionChangedEvent event) {\r
-                               selectionProvider.selectionChanged(event);\r
-                       }\r
-               });\r
-               return outlinePage;\r
-       }\r
-\r
-       @SuppressWarnings("rawtypes")\r
-       @Override\r
-       public Object getAdapter(Class adapter) {\r
-               if (IPropertyPage.class.equals(adapter))\r
-                       return new StandardPropertyPage(getSite(),getPropertyContexts());\r
-               if (IContentOutlinePage.class.equals(adapter)) {\r
-                       return createOutline();\r
-               }\r
-               if (NodeMap.class.equals(adapter)) {\r
-                       return nodeMap;\r
-               }\r
-               if (INode.class.equals(adapter)) {\r
-                       return rootNode;\r
-               }\r
-               if (IMapping.class.equals(adapter)) {\r
-                       return mapping;\r
-               }\r
-               if (InteractiveVtkPanel.class.equals(adapter)) {\r
-                       return panel;\r
-               }\r
-               return super.getAdapter(adapter);\r
-       }\r
-       \r
-       public Set<String> getPropertyContexts() {\r
-               Set<String> result = new HashSet<String>();\r
-               result.add("http://www.simantics.org/Project-1.0/ProjectBrowseContext");\r
-               return result;\r
-       }\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.csg.editor;
+
+import java.awt.Component;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.g3d.csg.actions.AddBooleanOpAction2;
+import org.simantics.g3d.csg.actions.AddPrimitiveAction2;
+import org.simantics.g3d.csg.actions.SplitBooleanOpAction2;
+import org.simantics.g3d.csg.scenegraph2.BarrelNode;
+import org.simantics.g3d.csg.scenegraph2.BoxNode;
+import org.simantics.g3d.csg.scenegraph2.CSGparentNode;
+import org.simantics.g3d.csg.scenegraph2.CSGrootNode;
+import org.simantics.g3d.csg.scenegraph2.ConeNode;
+import org.simantics.g3d.csg.scenegraph2.CylinderNode;
+import org.simantics.g3d.csg.scenegraph2.DifferenceNode;
+import org.simantics.g3d.csg.scenegraph2.EllipticCylinderNode;
+import org.simantics.g3d.csg.scenegraph2.ICSGnode;
+import org.simantics.g3d.csg.scenegraph2.IntersectionNode;
+import org.simantics.g3d.csg.scenegraph2.RectangularSolidNode;
+import org.simantics.g3d.csg.scenegraph2.RegularPrismNode;
+import org.simantics.g3d.csg.scenegraph2.SchemaBuilder;
+import org.simantics.g3d.csg.scenegraph2.SphereNode;
+import org.simantics.g3d.csg.scenegraph2.TorusNode;
+import org.simantics.g3d.csg.scenegraph2.UnionNode;
+import org.simantics.g3d.scenegraph.IG3DNode;
+import org.simantics.g3d.scenegraph.NodeMap;
+import org.simantics.g3d.scenegraph.base.INode;
+import org.simantics.g3d.vtk.action.RemoveAction;
+import org.simantics.g3d.vtk.awt.InteractiveVtkPanel;
+import org.simantics.g3d.vtk.awt.RotateAction;
+import org.simantics.g3d.vtk.awt.TranslateAction;
+import org.simantics.g3d.vtk.awt.vtkCameraAndSelectorAction;
+import org.simantics.g3d.vtk.common.HoverHighlighter;
+import org.simantics.g3d.vtk.common.NodeSelectionProvider2;
+import org.simantics.g3d.vtk.common.SelectionHighlighter;
+import org.simantics.g3d.vtk.common.VTKContentOutlinePage;
+import org.simantics.g3d.vtk.common.VtkView;
+import org.simantics.g3d.vtk.shape.vtkShape;
+import org.simantics.g3d.vtk.utils.vtkPanelUtil;
+import org.simantics.objmap.graph.IMapping;
+import org.simantics.objmap.graph.Mappings;
+import org.simantics.objmap.graph.schema.IMappingSchema;
+import org.simantics.selectionview.StandardPropertyPage;
+import org.simantics.ui.workbench.IPropertyPage;
+import org.simantics.ui.workbench.IResourceEditorInput;
+import org.simantics.ui.workbench.ResourceEditorPart;
+import org.simantics.utils.threads.AWTThread;
+import org.simantics.utils.threads.ThreadUtils;
+import org.simantics.utils.ui.ExceptionUtils;
+import org.simantics.utils.ui.SWTAWTComponent;
+
+import vtk.vtkActor;
+import vtk.vtkCameraPass;
+import vtk.vtkDefaultPass;
+import vtk.vtkLightsPass;
+import vtk.vtkRenderPassCollection;
+import vtk.vtkRenderer;
+import vtk.vtkSequencePass;
+
+public class CSGEditor2  extends ResourceEditorPart {
+       private Composite parent;
+       private Resource input;
+       private InteractiveVtkPanel panel;
+       private SWTAWTComponent component;
+       
+       private CSGrootNode rootNode;
+       private IMapping<Resource,Object> mapping;
+       
+       private NodeSelectionProvider2<Resource,Object> selectionProvider;
+       
+       private vtkCameraAndSelectorAction cameraAction;
+       private TranslateAction translateAction;
+       private RotateAction rotateAction;
+       private RemoveAction removeAction;
+       
+       //private  ScenegraphOutlinePage outlinePage;
+       
+       private CSGNodeMap nodeMap;
+
+
+
+       @Override
+       public void createPartControl(Composite parent) {
+               this.parent = parent;
+               parent.setLayout (new FillLayout ());
+               component = new SWTAWTComponent(parent,SWT.NONE) {
+                       
+                       @Override
+                       protected Component createSwingComponent() {
+                               if (panel == null) {
+                                       panel = new InteractiveVtkPanel();
+                                       vtkPanelUtil.registerPanel(panel);
+                                       createScene();
+                               }
+                               return panel;
+                       }
+               };
+
+               IResourceEditorInput rei = (IResourceEditorInput)getEditorInput();
+               input = rei.getResource();
+               
+               
+               //IActionBars actionBars = getEditorSite().getActionBars();
+
+               hookContextMenu();
+               
+               component.syncPopulate();
+               
+               panel.addMouseListener(new java.awt.event.MouseAdapter() {
+                       @Override
+                       public void mouseClicked(final java.awt.event.MouseEvent e) {
+                               if (e.getButton() == java.awt.event.MouseEvent.BUTTON3) {
+                                       Display.getDefault().asyncExec(new Runnable() {
+                                               public void run() {
+                                                       contextMenu.setLocation(e.getXOnScreen(), e.getYOnScreen());
+                                                       contextMenu.setVisible(true);
+                                               }
+                                       });
+                               }
+                       }
+               });
+               
+
+               cameraAction = new vtkCameraAndSelectorAction(panel);   
+               panel.setDefaultAction(cameraAction);
+               panel.useDefaultAction();
+               
+               try {
+                       getSession().syncRequest(new ReadRequest() {
+                               
+                               @SuppressWarnings({ "rawtypes", "unchecked" })
+                               @Override
+                               public void run(ReadGraph graph) throws DatabaseException {
+                                       IMappingSchema schema = SchemaBuilder.getSchema(graph);
+                                       mapping = Mappings.createWithListening(schema);
+                                       rootNode = (CSGrootNode)mapping.map(graph, input);
+                                       nodeMap = new CSGNodeMap(getSession(), mapping, panel,(CSGrootNode)rootNode);
+                               }
+                       });
+                       
+                       if (rootNode == null)
+                               throw new RuntimeException("Scenegraph loading failed.");
+                       populate();
+                       
+                       selectionProvider = new NodeSelectionProvider2<Resource,Object>(this,mapping,nodeMap);
+
+                       cameraAction.addSelectionChangedListener(selectionProvider);
+
+                       cameraAction.addHoverChangedListener(new HoverHighlighter(panel,nodeMap));
+                       selectionProvider.addSelectionChangedListener(new SelectionHighlighter(panel,nodeMap));
+                       
+                       getSite().setSelectionProvider(selectionProvider);
+                       getSite().getPage().addPostSelectionListener(selectionProvider);
+                       
+                       //outlinePage = new ScenegraphOutlinePage(rootNode);
+                       
+                       
+                       parent.addDisposeListener(new DisposeListener() {
+                               
+                               @Override
+                               public void widgetDisposed(DisposeEvent e) {
+                                       getSite().getPage().removePostSelectionListener(selectionProvider);
+                                       ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+                                               
+                                               @Override
+                                               public void run() {
+                                                       nodeMap.delete();
+                                                       vtkPanelUtil.unregisterPanel(panel);
+
+                                               }
+                                       });
+                                       mapping.dispose();
+                                       component.dispose();
+                                       
+                                       
+                               }
+                       });
+               } catch (DatabaseException e1) {
+                       ExceptionUtils.logAndShowError("Cannot open CSG editor",e1);
+                       return;
+               }
+               
+               translateAction = new TranslateAction(panel,nodeMap);
+               rotateAction = new RotateAction(panel,nodeMap);
+               removeAction = new RemoveAction(nodeMap) {
+                       public void setNode(IG3DNode node) {
+                               super.setNode(node);
+                               if (node.getParent() instanceof CSGparentNode)
+                                       setEnabled(false);
+                               
+                       }
+               };
+               
+               
+       }
+       
+       
+
+       
+       public void populate() {
+               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+                       
+                       @Override
+                       public void run() {
+                               nodeMap.populate();
+                       }
+               });
+               
+       }
+       
+       
+       
+       @Override
+       public void setFocus() {
+               component.setFocus();
+       }
+       
+       private void createScene() {
+               vtkRenderer ren1 = panel.GetRenderer();
+               
+               boolean multiPass = false;
+               if (multiPass) {
+                       
+                       vtkLightsPass lightsPass = new vtkLightsPass();
+                       vtkDefaultPass defaultPass = new vtkDefaultPass();
+                       
+                       
+                       vtkRenderPassCollection passes = new vtkRenderPassCollection();
+                       passes.AddItem(lightsPass);
+                       passes.AddItem(defaultPass);
+                       
+                       vtkSequencePass seq = new vtkSequencePass();
+                       seq.SetPasses(passes);
+                       
+               
+                       
+                       vtkCameraPass cameraPass = new vtkCameraPass();
+                       cameraPass.SetDelegatePass(seq);
+                       
+                       ren1.SetPass(cameraPass);
+                       
+               }
+//             ren1.GetRenderWindow().LineSmoothingOn();
+//             ren1.GetRenderWindow().PointSmoothingOn();
+//             ren1.GetRenderWindow().PolygonSmoothingOn();
+//             ren1.GetRenderWindow().SetMultiSamples(2);
+
+               
+
+               ren1.SetBackground2(1,1,1); // background color white
+               ren1.SetBackground(0.9,0.9,0.9);
+               ren1.SetGradientBackground(true);
+
+          // vtkActor grid = vtkShape.createGridActor(8,1.0,1|2|4);
+           vtkActor grid = vtkShape.createGridActor(8,1.0, 2 );
+           grid.SetPickable(0);
+           ren1.AddActor(grid);
+           panel.addDeletable(grid);
+           
+
+               
+       }
+       
+       protected Menu contextMenu;
+       
+       protected void hookContextMenu() {
+        MenuManager menuMgr = new MenuManager("#PopupMenu");
+        menuMgr.setRemoveAllWhenShown(true);
+        menuMgr.addMenuListener(new IMenuListener() {
+            public void menuAboutToShow(IMenuManager manager) {
+               final IMenuManager m = manager;
+                       List<IG3DNode> selected = selectionProvider.getSelectedNodes();
+                       if (selected.size() == 0) {
+                               m.add(new AddPrimitiveAction2(rootNode, BarrelNode.class));
+                               m.add(new AddPrimitiveAction2(rootNode, BoxNode.class));
+                               m.add(new AddPrimitiveAction2(rootNode, ConeNode.class));
+                               m.add(new AddPrimitiveAction2(rootNode, CylinderNode.class));
+                               m.add(new AddPrimitiveAction2(rootNode, EllipticCylinderNode.class));
+                               m.add(new AddPrimitiveAction2(rootNode, RectangularSolidNode.class));
+                               m.add(new AddPrimitiveAction2(rootNode, RegularPrismNode.class));
+                               m.add(new AddPrimitiveAction2(rootNode, SphereNode.class));
+                               m.add(new AddPrimitiveAction2(rootNode, TorusNode.class));
+                       } else if (selected.size() == 1) {
+                               m.add(translateAction);
+                                       m.add(rotateAction);
+                                       m.add(removeAction);
+                                       ICSGnode node = (ICSGnode)selected.get(0);
+                                       translateAction.setNode(node);
+                                       rotateAction.setNode(node);
+                                       removeAction.setNode(node);
+                                       if (node instanceof CSGparentNode) {
+                                               m.add(new SplitBooleanOpAction2(rootNode,(CSGparentNode)node));
+                                       }
+                       } else if (selected.size() == 2) {
+                               if (selected.get(0).getParent().equals(rootNode) && selected.get(1).getParent().equals(rootNode)) {
+                                       Collection<ICSGnode> nodes = new ArrayList<ICSGnode>();
+                                       for (IG3DNode n : selected)
+                                               nodes.add((ICSGnode)n);
+                                       m.add(new AddBooleanOpAction2(rootNode, DifferenceNode.class, nodes));
+                                       m.add(new AddBooleanOpAction2(rootNode, IntersectionNode.class, nodes));
+                                       m.add(new AddBooleanOpAction2(rootNode, UnionNode.class, nodes));
+                               }
+                       }
+//             try {
+//                                     SimanticsUI.getSession().syncRequest(new ReadRequest() {
+//                                             
+//                                             @Override
+//                                             public void run(ReadGraph graph) throws DatabaseException {
+//                                                     Layer0 l0 = Layer0.getInstance(graph);
+//                                                     CSG csg = CSG.getInstance(graph);
+//                                                     Resource ontology = graph.getResource("http://www.simantics.org/CSG-0.1");
+//                                                     
+//                                                     if (selectionProvider.getSelectedResources().size() == 0) {
+//                                                             List<NamedResource> primitives = new ArrayList<NamedResource>();
+//                                                             for (Resource r : graph.getObjects(ontology, l0.ConsistsOf)) {
+//                                                                     if (graph.isInheritedFrom(r, csg.Primitive) && !r.equals(csg.Primitive)) {
+//                                                                             primitives.add(new NamedResource((String)graph.getRelatedValue(r, l0.HasName), r));
+//                                                                     }
+//                                                             }
+//                                                             
+//                                                             Collections.sort(primitives);
+//                                                             for (NamedResource n : primitives) {
+//                                                                     m.add(new AddPrimitiveAction(graph, n.getResource(),input));
+//                                                             }
+//                                                     }
+//                                                     if (selectionProvider.getSelectedResources().size() == 2) {
+//                                                             List<NamedResource> booleanOps = new ArrayList<NamedResource>();
+//                                                             for (Resource r : graph.getObjects(ontology, l0.ConsistsOf)) {
+//                                                                     if (graph.isInheritedFrom(r, csg.BooleanOperation) && !r.equals(csg.BooleanOperation)) {
+//                                                                             booleanOps.add(new NamedResource((String)graph.getRelatedValue(r, l0.HasName), r));
+//                                                                     }
+//                                                             }
+//                                                             
+//                                                             Collections.sort(booleanOps);
+//                                                             for (NamedResource n : booleanOps) {
+//                                                                     m.add(new AddBooleanOpAction(graph, n.getResource(), input, selectionProvider.getSelectedResources()));
+//                                                             }
+//                                                     }
+//                                                     if (selectionProvider.getSelectedResources().size() == 1) {
+//                                                             m.add(translateAction);
+//                                                             m.add(rotateAction);
+//                                                             m.add(removeAction);
+//                                                             Resource selected = selectionProvider.getSelectedResources().get(0);
+//                                                             translateAction.setNode((IG3DNode2)mapping.get(selected));
+//                                                             rotateAction.setNode((IG3DNode2)mapping.get(selected));
+//                                                             removeAction.setNode((IG3DNode2)mapping.get(selected));
+//                                                             if (graph.isInstanceOf(selected, csg.BooleanOperation)) {
+//                                                                     m.add(new SplitBooleanOpAction(input,selected));
+//                                                             }
+//                                                             
+//                                                             
+//                                                     }
+//                                                     
+//                                             }
+//                                     });
+//                             } catch (DatabaseException e) {
+//                                     // TODO Auto-generated catch block
+//                                     e.printStackTrace();
+//                             }
+                
+            }
+        });
+
+        contextMenu = menuMgr.createContextMenu(parent);
+    }
+       
+       private IContentOutlinePage createOutline() {
+               if (rootNode == null || selectionProvider == null)
+                       return null;
+               IContentOutlinePage outlinePage = new VTKContentOutlinePage<Resource,Object>(rootNode, selectionProvider);
+               outlinePage.addSelectionChangedListener(new ISelectionChangedListener() {
+                       
+                       @Override
+                       public void selectionChanged(SelectionChangedEvent event) {
+                               selectionProvider.selectionChanged(event);
+                       }
+               });
+               return outlinePage;
+       }
+
+       @SuppressWarnings("rawtypes")
+       @Override
+       public Object getAdapter(Class adapter) {
+               if (IPropertyPage.class.equals(adapter))
+                       return new StandardPropertyPage(getSite(),getPropertyContexts());
+               if (IContentOutlinePage.class.equals(adapter)) {
+                       return createOutline();
+               }
+               if (NodeMap.class.equals(adapter)) {
+                       return nodeMap;
+               }
+               if (INode.class.equals(adapter)) {
+                       return rootNode;
+               }
+               if (IMapping.class.equals(adapter)) {
+                       return mapping;
+               }
+               if (InteractiveVtkPanel.class.equals(adapter)) {
+                       return panel;
+               }
+               if (VtkView.class.equals(adapter))
+                       return panel;
+               return super.getAdapter(adapter);
+       }
+       
+       public Set<String> getPropertyContexts() {
+               Set<String> result = new HashSet<String>();
+               result.add("http://www.simantics.org/Project-1.0/ProjectBrowseContext");
+               return result;
+       }
+}
index a207d5f2829f0485c38fb97a7e76e632051c796d..b4eaa148903d71b793dd09335d2cb88caf178269 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.csg.editor;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.List;\r
-import java.util.Set;\r
-\r
-import org.simantics.db.Session;\r
-import org.simantics.g3d.csg.scenegraph2.CSGrootNode;\r
-import org.simantics.g3d.csg.scenegraph2.ICSGnode;\r
-import org.simantics.g3d.scenegraph.base.ParentNode;\r
-import org.simantics.g3d.vtk.common.AbstractVTKNodeMap;\r
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;\r
-import org.simantics.objmap.graph.IMapping;\r
-import org.simantics.utils.threads.AWTThread;\r
-\r
-import vtk.vtkProp;\r
-import vtk.vtkProp3D;\r
-import vtk.vtkRenderer;\r
-\r
-public class CSGNodeMap extends AbstractVTKNodeMap<ICSGnode> {\r
-       \r
-\r
-       \r
-       public CSGNodeMap(Session session, IMapping mapping, InteractiveVtkPanel panel, CSGrootNode rootNode) {\r
-               super(session, mapping, panel, rootNode);\r
-               rootNode.setNodeMap(this);\r
-       }\r
-       \r
-\r
-       @SuppressWarnings("unchecked")\r
-       protected void updateActor(ICSGnode node, Set<String> ids) {\r
-               //System.out.println("CSGNodeMap.updateActor " + node);\r
-               if (node.getParent() instanceof ICSGnode) {\r
-                       ICSGnode parent = (ICSGnode) node.getParent();\r
-                       if (!"child".equals(node.getParentRel())) {\r
-                               updateActor(parent,null);\r
-                               return;\r
-                       }\r
-               }\r
-               \r
-               if (node instanceof ParentNode<?>) {\r
-                       ParentNode<ICSGnode> p = (ParentNode<ICSGnode>)node;\r
-                       for (ICSGnode n : p.getNodes())\r
-                               remActor(n);\r
-               }\r
-               \r
-               remActor(node);\r
-               addActor(node);\r
-\r
-       }\r
-\r
-       @Override\r
-       protected Collection<vtkProp> getActors(ICSGnode node) {\r
-               List<vtkProp> props = new ArrayList<vtkProp>();\r
-               for (vtkProp3D p : ((ICSGnode)node).getActors())\r
-                       props.add(p);\r
-               return props;\r
-       }\r
-       \r
-       protected void removeActor(ICSGnode node) {\r
-               //System.out.println("CSGNodeMap.removeActor " + node);\r
-               remActor(node);\r
-               \r
-               if (!"child".equals(node.getParentRel())) {\r
-                       if (node.getParent() instanceof ICSGnode)\r
-                               updateActor((ICSGnode)node.getParent(),null);\r
-               }\r
-       }\r
-       \r
-       protected void addActor(ICSGnode node) {\r
-               //System.out.println("CSGNodeMap.addActor " + node);\r
-               if (hasActor(node))\r
-                       return;\r
-               if (Thread.currentThread() != AWTThread.getThreadAccess().getThread())\r
-                       throw new RuntimeException("Illegal thread.");\r
-               \r
-               panel.lock();\r
-               \r
-               node.visualize(panel);\r
-\r
-               for (vtkProp3D act : node.getActors()) {\r
-                       nodeToActor.add(node, act);\r
-            actorToNode.put(act, node);\r
-               }\r
-\r
-        panel.unlock();\r
-\r
-       }\r
-       \r
-       \r
-       \r
-       private boolean hasActor(ICSGnode node) {\r
-               List<vtkProp> list = nodeToActor.getValues(node);\r
-               if (list == null || list.size() == 0)\r
-                       return false;\r
-               return true;\r
-       }\r
-       \r
-       private void remActor(ICSGnode node) {\r
-               if (Thread.currentThread() != AWTThread.getThreadAccess().getThread())\r
-                       throw new RuntimeException("Illegal thread.");\r
-\r
-               List<vtkProp> list = nodeToActor.getValues(node);\r
-               if (list != null) {\r
-                       for (vtkProp obj : list) {\r
-                               actorToNode.remove(obj);        \r
-                       }\r
-                       nodeToActor.remove(node);\r
-                       panel.lock();\r
-                       \r
-                       node.stopVisualize();\r
-                       \r
-                       panel.unlock();\r
-               }\r
-       }\r
-       \r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.csg.editor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.simantics.db.Session;
+import org.simantics.g3d.csg.scenegraph2.CSGrootNode;
+import org.simantics.g3d.csg.scenegraph2.ICSGnode;
+import org.simantics.g3d.scenegraph.base.ParentNode;
+import org.simantics.g3d.vtk.awt.InteractiveVtkPanel;
+import org.simantics.g3d.vtk.common.AbstractVTKNodeMap;
+import org.simantics.objmap.graph.IMapping;
+
+import vtk.vtkProp;
+import vtk.vtkProp3D;
+
+public class CSGNodeMap extends AbstractVTKNodeMap<ICSGnode> {
+       
+
+       
+       public CSGNodeMap(Session session, IMapping mapping, InteractiveVtkPanel panel, CSGrootNode rootNode) {
+               super(session, mapping, panel, rootNode);
+               rootNode.setNodeMap(this);
+       }
+       
+
+       @SuppressWarnings("unchecked")
+       protected void updateActor(ICSGnode node, Set<String> ids) {
+               //System.out.println("CSGNodeMap.updateActor " + node);
+               if (node.getParent() instanceof ICSGnode) {
+                       ICSGnode parent = (ICSGnode) node.getParent();
+                       if (!"child".equals(node.getParentRel())) {
+                               updateActor(parent,null);
+                               return;
+                       }
+               }
+               
+               if (node instanceof ParentNode<?>) {
+                       ParentNode<ICSGnode> p = (ParentNode<ICSGnode>)node;
+                       for (ICSGnode n : p.getNodes())
+                               remActor(n);
+               }
+               
+               remActor(node);
+               addActor(node);
+
+       }
+
+       @Override
+       protected Collection<vtkProp> getActors(ICSGnode node) {
+               List<vtkProp> props = new ArrayList<vtkProp>();
+               for (vtkProp3D p : ((ICSGnode)node).getActors())
+                       props.add(p);
+               return props;
+       }
+       
+       protected void removeActor(ICSGnode node) {
+               //System.out.println("CSGNodeMap.removeActor " + node);
+               remActor(node);
+               
+               if (!"child".equals(node.getParentRel())) {
+                       if (node.getParent() instanceof ICSGnode)
+                               updateActor((ICSGnode)node.getParent(),null);
+               }
+       }
+       
+       protected void addActor(ICSGnode node) {
+               //System.out.println("CSGNodeMap.addActor " + node);
+               if (hasActor(node))
+                       return;
+               if (Thread.currentThread() != view.getThreadQueue().getThread())
+                       throw new RuntimeException("Illegal thread.");
+               
+               view.lock();
+               
+               node.visualize(view);
+
+               for (vtkProp3D act : node.getActors()) {
+                       nodeToActor.add(node, act);
+            actorToNode.put(act, node);
+               }
+
+        view.unlock();
+
+       }
+       
+       
+       
+       private boolean hasActor(ICSGnode node) {
+               List<vtkProp> list = nodeToActor.getValues(node);
+               if (list == null || list.size() == 0)
+                       return false;
+               return true;
+       }
+       
+       private void remActor(ICSGnode node) {
+               if (Thread.currentThread() != view.getThreadQueue().getThread())
+                       throw new RuntimeException("Illegal thread.");
+
+               List<vtkProp> list = nodeToActor.getValues(node);
+               if (list != null) {
+                       for (vtkProp obj : list) {
+                               actorToNode.remove(obj);        
+                       }
+                       nodeToActor.remove(node);
+                       view.lock();
+                       
+                       node.stopVisualize();
+                       
+                       view.unlock();
+               }
+       }
+       
+
+}
index a28e5a3a13abcab06c07f259c1dcc47640ccbf1d..68c1c015f2f1d67c610f858efb54ca44c26f2636 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.csg.scenegraph2;\r
-\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-\r
-import javax.vecmath.AxisAngle4d;\r
-import javax.vecmath.Quat4d;\r
-import javax.vecmath.Vector3d;\r
-\r
-import org.jcae.opencascade.jni.TopoDS_Shape;\r
-import org.simantics.g3d.property.annotations.GetPropertyValue;\r
-import org.simantics.g3d.property.annotations.SetPropertyValue;\r
-import org.simantics.g3d.scenegraph.G3DNode;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.objmap.graph.annotations.RelatedGetValue;\r
-import org.simantics.objmap.graph.annotations.RelatedSetValue;\r
-import org.simantics.opencascade.OccTriangulator;\r
-import org.simantics.opencascade.vtk.vtkSolidObject;\r
-import org.simantics.utils.threads.AWTThread;\r
-\r
-import vtk.vtkPanel;\r
-import vtk.vtkProp3D;\r
-import vtk.vtkRenderer;\r
-\r
-public abstract class CSGnode extends G3DNode implements ICSGnode {\r
-\r
-       public static final double MIN_VALUE = 0.001;\r
-       \r
-       private String name;\r
-       \r
-\r
-       @RelatedGetValue(Layer0.URIs.HasName)\r
-       @GetPropertyValue(value = Layer0.URIs.HasName, tabId = "Default", name = "Name")\r
-       public String getName() {\r
-               return name;\r
-       }\r
-       \r
-       @RelatedSetValue(Layer0.URIs.HasName)\r
-       @SetPropertyValue(Layer0.URIs.HasName)\r
-       public void setName(String name) {\r
-               if (name == null)\r
-                       return;\r
-               this.name = name;\r
-               firePropertyChanged(Layer0.URIs.HasName);\r
-       }\r
-       \r
-       @Override\r
-       public String toString() {\r
-               return getName();\r
-       }\r
-       \r
-       \r
-       private vtkSolidObject solidObject;\r
-       \r
-       @Override\r
-       public TopoDS_Shape getGeometry() {\r
-               TopoDS_Shape shape = getBaseGeometry();\r
-               if (shape == null)\r
-                       return null;\r
-               Quat4d q = getOrientation();\r
-               AxisAngle4d r = new AxisAngle4d();\r
-               r.set(q);\r
-               TopoDS_Shape tshape = OccTriangulator.makeRotation(shape, new double[] { 0.0, 0.0, 0.0, r.x, r.y, r.z }, r.angle);\r
-               shape.delete();\r
-               shape = tshape;\r
-               Vector3d p = getPosition();\r
-               tshape = OccTriangulator.makeTranslation(shape, p.x, p.y, p.z);\r
-               shape.delete();\r
-               return tshape;  \r
-       }\r
-       \r
-       public void visualize(vtkPanel panel) {\r
-               if (solidObject != null) {\r
-                       solidObject.delete();\r
-                       solidObject = null;\r
-               }\r
-               TopoDS_Shape shape = getGeometry();\r
-               if (shape == null)\r
-                       return;\r
-               solidObject = new vtkSolidObject(panel, shape);\r
-               solidObject.visualizeSolid(true, false);\r
-       }\r
-       \r
-       @SuppressWarnings("unchecked")\r
-       public Collection<vtkProp3D> getActors() {\r
-               if (solidObject == null)\r
-                       return Collections.EMPTY_LIST;\r
-               return solidObject.getActors();\r
-       }\r
-       \r
-       public void stopVisualize() {\r
-               if (solidObject != null) {\r
-                       if (Thread.currentThread() == AWTThread.getThreadAccess().getThread())\r
-                               solidObject.delete();\r
-                       else\r
-                               solidObject.dispose();\r
-                       solidObject = null;\r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public void cleanup() {\r
-               stopVisualize();\r
-               super.cleanup();\r
-       }\r
-       \r
-       \r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.csg.scenegraph2;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.vecmath.AxisAngle4d;
+import javax.vecmath.Quat4d;
+import javax.vecmath.Vector3d;
+
+import org.jcae.opencascade.jni.TopoDS_Shape;
+import org.simantics.g3d.property.annotations.GetPropertyValue;
+import org.simantics.g3d.property.annotations.SetPropertyValue;
+import org.simantics.g3d.scenegraph.G3DNode;
+import org.simantics.g3d.vtk.common.VtkView;
+import org.simantics.layer0.Layer0;
+import org.simantics.objmap.graph.annotations.RelatedGetValue;
+import org.simantics.objmap.graph.annotations.RelatedSetValue;
+import org.simantics.opencascade.OccTriangulator;
+import org.simantics.opencascade.vtk.vtkSolidObject;
+import org.simantics.utils.threads.AWTThread;
+
+import vtk.vtkProp3D;
+
+public abstract class CSGnode extends G3DNode implements ICSGnode {
+
+       public static final double MIN_VALUE = 0.001;
+       
+       private String name;
+       
+
+       @RelatedGetValue(Layer0.URIs.HasName)
+       @GetPropertyValue(value = Layer0.URIs.HasName, tabId = "Default", name = "Name")
+       public String getName() {
+               return name;
+       }
+       
+       @RelatedSetValue(Layer0.URIs.HasName)
+       @SetPropertyValue(Layer0.URIs.HasName)
+       public void setName(String name) {
+               if (name == null)
+                       return;
+               this.name = name;
+               firePropertyChanged(Layer0.URIs.HasName);
+       }
+       
+       @Override
+       public String toString() {
+               return getName();
+       }
+       
+       
+       private vtkSolidObject solidObject;
+       
+       @Override
+       public TopoDS_Shape getGeometry() {
+               TopoDS_Shape shape = getBaseGeometry();
+               if (shape == null)
+                       return null;
+               Quat4d q = getOrientation();
+               AxisAngle4d r = new AxisAngle4d();
+               r.set(q);
+               TopoDS_Shape tshape = OccTriangulator.makeRotation(shape, new double[] { 0.0, 0.0, 0.0, r.x, r.y, r.z }, r.angle);
+               shape.delete();
+               shape = tshape;
+               Vector3d p = getPosition();
+               tshape = OccTriangulator.makeTranslation(shape, p.x, p.y, p.z);
+               shape.delete();
+               return tshape;  
+       }
+       
+       public void visualize(VtkView panel) {
+               if (solidObject != null) {
+                       solidObject.delete();
+                       solidObject = null;
+               }
+               TopoDS_Shape shape = getGeometry();
+               if (shape == null)
+                       return;
+               solidObject = new vtkSolidObject(panel, shape);
+               solidObject.visualizeSolid(true, false);
+       }
+       
+       @SuppressWarnings("unchecked")
+       public Collection<vtkProp3D> getActors() {
+               if (solidObject == null)
+                       return Collections.EMPTY_LIST;
+               return solidObject.getActors();
+       }
+       
+       public void stopVisualize() {
+               if (solidObject != null) {
+                       if (Thread.currentThread() == AWTThread.getThreadAccess().getThread())
+                               solidObject.delete();
+                       else
+                               solidObject.dispose();
+                       solidObject = null;
+               }
+       }
+       
+       @Override
+       public void cleanup() {
+               stopVisualize();
+               super.cleanup();
+       }
+       
+       
+
+}
index 24f2ac4c94ddc3e055e2b446e91b4a9f35a53347..6f83fdbfc095f4cc362d94647b69f9b75e81dadb 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.csg.scenegraph2;\r
-\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-\r
-import javax.vecmath.AxisAngle4d;\r
-import javax.vecmath.Quat4d;\r
-import javax.vecmath.Vector3d;\r
-\r
-import org.jcae.opencascade.jni.TopoDS_Shape;\r
-import org.simantics.g3d.csg.ontology.CSG;\r
-import org.simantics.g3d.math.MathTools;\r
-import org.simantics.g3d.ontology.G3D;\r
-import org.simantics.g3d.property.annotations.GetPropertyValue;\r
-import org.simantics.g3d.property.annotations.PropertyContributor;\r
-import org.simantics.g3d.property.annotations.SetPropertyValue;\r
-import org.simantics.g3d.scenegraph.IG3DNode;\r
-import org.simantics.g3d.scenegraph.base.ParentNode;\r
-import org.simantics.g3d.tools.NodeTools;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.objmap.graph.annotations.RelatedElementsAdd;\r
-import org.simantics.objmap.graph.annotations.RelatedElementsGet;\r
-import org.simantics.objmap.graph.annotations.RelatedElementsRem;\r
-import org.simantics.objmap.graph.annotations.RelatedGetValue;\r
-import org.simantics.objmap.graph.annotations.RelatedSetValue;\r
-import org.simantics.opencascade.OccTriangulator;\r
-import org.simantics.opencascade.vtk.vtkSolidObject;\r
-import org.simantics.utils.threads.AWTThread;\r
-\r
-import vtk.vtkPanel;\r
-import vtk.vtkProp3D;\r
-\r
-@PropertyContributor\r
-public abstract class CSGparentNode extends ParentNode<ICSGnode> implements ICSGnode {\r
-\r
-       private String name;\r
-       \r
-\r
-       @RelatedGetValue(Layer0.URIs.HasName)\r
-       @GetPropertyValue(value = Layer0.URIs.HasName, tabId = "Default", name = "Name")\r
-       public String getName() {\r
-               return name;\r
-       }\r
-       \r
-       @RelatedSetValue(Layer0.URIs.HasName)\r
-       @SetPropertyValue(Layer0.URIs.HasName)\r
-       public void setName(String name) {\r
-               if (name == null)\r
-                       return;\r
-               this.name = name;\r
-               firePropertyChanged(Layer0.URIs.HasName);\r
-       }\r
-       \r
-       @Override\r
-       public String toString() {\r
-               return getName();\r
-       }\r
-       \r
-       private Vector3d position = new Vector3d();\r
-       private Quat4d orientation = MathTools.getIdentityQuat();\r
-       \r
-       @Override\r
-       @GetPropertyValue(value = G3D.URIs.hasOrientation, tabId = "Transform", name = "Orientation")\r
-       public Quat4d getOrientation() {\r
-               return orientation;\r
-       }\r
-       \r
-       @RelatedGetValue(G3D.URIs.hasOrientation)\r
-       public double[] getOrientationArr() {\r
-               double arr[] = new double[4];\r
-               orientation.get(arr);\r
-               return arr;\r
-               \r
-       }\r
-       \r
-       @Override\r
-       @GetPropertyValue(value = G3D.URIs.hasPosition, tabId = "Transform", name = "Position")\r
-       public Vector3d getPosition() {\r
-               return position;\r
-       }\r
-       \r
-       @RelatedGetValue(G3D.URIs.hasPosition)\r
-       public double[] getPositionArr() {\r
-               double arr[] = new double[3];\r
-               position.get(arr);\r
-               return arr;\r
-       }\r
-       \r
-       @RelatedElementsAdd(CSG.URIs.hasPrimaryShape)\r
-       public void addPrimaryChild(ICSGnode node) {\r
-               addNode("primary",node);\r
-       }\r
-       \r
-       @RelatedElementsGet(CSG.URIs.hasPrimaryShape)\r
-       public Collection<ICSGnode> getPrimaryChild() {\r
-               return getNodes("primary");\r
-       }\r
-       \r
-       @RelatedElementsRem(CSG.URIs.hasPrimaryShape)\r
-       public void remPrimaryChild(ICSGnode node) {\r
-               removeNode("primary", node);\r
-       }\r
-       \r
-       @RelatedElementsAdd(CSG.URIs.hasSecondaryShape)\r
-       public void addSecondaryChild(ICSGnode node) {\r
-               addNode("secondary",node);\r
-       }\r
-       \r
-       @RelatedElementsGet(CSG.URIs.hasSecondaryShape)\r
-       public Collection<ICSGnode> getSecondaryChild() {\r
-               return getNodes("secondary");\r
-       }\r
-       \r
-       @RelatedElementsRem(CSG.URIs.hasSecondaryShape)\r
-       public void remSecondaryChild(ICSGnode node) {\r
-               removeNode("secondary", node);\r
-       }\r
-       \r
-\r
-       @RelatedElementsAdd(CSG.URIs.hasChildShape)\r
-       public void addChild(ICSGnode node) {\r
-               addNode("child",node);\r
-       }\r
-       \r
-       @RelatedElementsGet(CSG.URIs.hasChildShape)\r
-       public Collection<ICSGnode> getChild() {\r
-               return getNodes("child");\r
-       }\r
-       \r
-       @RelatedElementsRem(CSG.URIs.hasChildShape)\r
-       public void remChild(ICSGnode node) {\r
-               removeNode("child", node);\r
-       }\r
-       \r
-       \r
-       \r
-       protected TopoDS_Shape getPrimary() {\r
-               for (ICSGnode node : getNodes("primary"))\r
-                       return node.getGeometry();\r
-               return null;\r
-       }\r
-       \r
-       protected TopoDS_Shape getSecondary() {\r
-               for (ICSGnode node : getNodes("secondary"))\r
-                       return node.getGeometry();\r
-               return null;\r
-       }\r
-       \r
-       @Override\r
-       public TopoDS_Shape getGeometry() {\r
-               TopoDS_Shape shape = getBaseGeometry();\r
-               if (shape == null)\r
-                       return null;\r
-               Quat4d q = getOrientation();\r
-               AxisAngle4d r = new AxisAngle4d();\r
-               r.set(q);\r
-               TopoDS_Shape tshape = OccTriangulator.makeRotation(shape, new double[] { 0.0, 0.0, 0.0, r.x, r.y, r.z }, r.angle);\r
-               shape.delete();\r
-               shape = tshape;\r
-               Vector3d p = getPosition();\r
-               tshape = OccTriangulator.makeTranslation(shape, p.x, p.y, p.z);\r
-               shape.delete();\r
-               return tshape;\r
-                       \r
-       }\r
-       \r
-\r
-       \r
-       @Override\r
-       @SetPropertyValue(G3D.URIs.hasOrientation)\r
-       public void setOrientation(Quat4d orientation) {\r
-               assert(orientation != null);\r
-               this.orientation = orientation;\r
-               \r
-               firePropertyChanged(G3D.URIs.hasOrientation);\r
-       }\r
-       \r
-       @Override\r
-       @SetPropertyValue(G3D.URIs.hasPosition)\r
-       public void setPosition(Vector3d position) {\r
-               assert(position != null);\r
-               this.position = position;\r
-               \r
-               firePropertyChanged(G3D.URIs.hasPosition);\r
-       }\r
-       \r
-       @RelatedSetValue(G3D.URIs.hasOrientation)\r
-       public void setOrientation(double[] arr) {\r
-               if (arr == null)\r
-                       return;\r
-               setOrientation(new Quat4d(arr));\r
-       }\r
-       \r
-       @RelatedSetValue(G3D.URIs.hasPosition)\r
-       public void setPosition(double[] arr) {\r
-               if (arr == null)\r
-                       return;\r
-               setPosition(new Vector3d(arr));\r
-       }\r
-       \r
-       @Override\r
-       @GetPropertyValue(value = G3D.URIs.hasWorldPosition, tabId = "Transform", name = "World Position")\r
-       public Vector3d getWorldPosition() {\r
-               IG3DNode parent = (IG3DNode) getParent();\r
-               if (parent == null)\r
-                       return position;\r
-               return NodeTools.getWorldPosition(parent, new Vector3d(position));\r
-       }\r
-\r
-       public Vector3d getWorldPosition(Vector3d localPosition) {\r
-               return NodeTools.getWorldPosition(this, localPosition);\r
-       }\r
-\r
-       \r
-       @Override\r
-       @GetPropertyValue(value = G3D.URIs.hasWorldOrientation, tabId = "Transform", name = "World Orientation")\r
-       public Quat4d getWorldOrientation() {\r
-               return getWorldOrientation(new Quat4d(orientation));\r
-       }\r
-       \r
-       public Quat4d getWorldOrientation(Quat4d localOrientation) {\r
-               IG3DNode parent = (IG3DNode)getParent();\r
-               if (parent == null)\r
-                       return localOrientation;\r
-               return NodeTools.getWorldOrientation(parent, localOrientation);\r
-       }\r
-       \r
-       @Override\r
-       public Vector3d getLocalPosition(Vector3d worldPosition) {\r
-               IG3DNode parent = (IG3DNode)getParent();\r
-               if (parent == null)\r
-                       return worldPosition;\r
-               return NodeTools.getLocalPosition(parent,new Vector3d(worldPosition));\r
-       }\r
-       \r
-       @Override\r
-       public Quat4d getLocalOrientation(Quat4d worldOrientation) {\r
-               IG3DNode parent = (IG3DNode)getParent();\r
-               if (parent == null)\r
-                       return worldOrientation;\r
-               return NodeTools.getLocalOrientation(parent, new Quat4d(worldOrientation));\r
-       }\r
-       \r
-       @Override\r
-       @SetPropertyValue(G3D.URIs.hasWorldPosition)\r
-       public void setWorldPosition(Vector3d position) {\r
-               Vector3d localPos = getLocalPosition(position);\r
-               setPosition(localPos);\r
-       }\r
-       \r
-       @Override\r
-       @SetPropertyValue(G3D.URIs.hasWorldOrientation)\r
-       public void setWorldOrientation(Quat4d orientation) {\r
-               Quat4d localOr = getLocalOrientation(orientation);\r
-               setOrientation(localOr);\r
-       }\r
-\r
-\r
-       private vtkSolidObject solidObject;\r
-       \r
-       \r
-       public void visualize(vtkPanel panel) {\r
-               if (solidObject != null) {\r
-                       solidObject.delete();\r
-                       solidObject = null;\r
-               }\r
-               TopoDS_Shape shape = getGeometry();\r
-               if (shape == null)\r
-                       return;\r
-               solidObject = new vtkSolidObject(panel, shape);\r
-               solidObject.visualizeSolid(true, false);\r
-       }\r
-       \r
-       @SuppressWarnings("unchecked")\r
-       public Collection<vtkProp3D> getActors() {\r
-               if (solidObject == null)\r
-                       return Collections.EMPTY_LIST;\r
-               return solidObject.getActors();\r
-       }\r
-       \r
-       public void stopVisualize() {\r
-               if (solidObject != null) {\r
-                       if (Thread.currentThread() == AWTThread.getThreadAccess().getThread())\r
-                               solidObject.delete();\r
-                       else\r
-                               solidObject.dispose();\r
-                       solidObject = null;\r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public void cleanup() {\r
-               stopVisualize();\r
-               super.cleanup();\r
-       }\r
-       \r
-       \r
-       @Override\r
-       public void remove() {\r
-               //FIXME: creating boolean shapes (removing nodes from parent and attaching under boolean shape would destroy the existing hierarchy, if default implementation is used.\r
-               super.remove();\r
-       }\r
-\r
-       @Override\r
-       public Object getAdapter(Class adapter) {\r
-               return null;\r
-       }\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.csg.scenegraph2;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.vecmath.AxisAngle4d;
+import javax.vecmath.Quat4d;
+import javax.vecmath.Vector3d;
+
+import org.jcae.opencascade.jni.TopoDS_Shape;
+import org.simantics.g3d.csg.ontology.CSG;
+import org.simantics.g3d.math.MathTools;
+import org.simantics.g3d.ontology.G3D;
+import org.simantics.g3d.property.annotations.GetPropertyValue;
+import org.simantics.g3d.property.annotations.PropertyContributor;
+import org.simantics.g3d.property.annotations.SetPropertyValue;
+import org.simantics.g3d.scenegraph.IG3DNode;
+import org.simantics.g3d.scenegraph.base.ParentNode;
+import org.simantics.g3d.tools.NodeTools;
+import org.simantics.g3d.vtk.common.VtkView;
+import org.simantics.layer0.Layer0;
+import org.simantics.objmap.graph.annotations.RelatedElementsAdd;
+import org.simantics.objmap.graph.annotations.RelatedElementsGet;
+import org.simantics.objmap.graph.annotations.RelatedElementsRem;
+import org.simantics.objmap.graph.annotations.RelatedGetValue;
+import org.simantics.objmap.graph.annotations.RelatedSetValue;
+import org.simantics.opencascade.OccTriangulator;
+import org.simantics.opencascade.vtk.vtkSolidObject;
+import org.simantics.utils.threads.AWTThread;
+
+import vtk.vtkProp3D;
+
+@PropertyContributor
+public abstract class CSGparentNode extends ParentNode<ICSGnode> implements ICSGnode {
+
+       private String name;
+       
+
+       @RelatedGetValue(Layer0.URIs.HasName)
+       @GetPropertyValue(value = Layer0.URIs.HasName, tabId = "Default", name = "Name")
+       public String getName() {
+               return name;
+       }
+       
+       @RelatedSetValue(Layer0.URIs.HasName)
+       @SetPropertyValue(Layer0.URIs.HasName)
+       public void setName(String name) {
+               if (name == null)
+                       return;
+               this.name = name;
+               firePropertyChanged(Layer0.URIs.HasName);
+       }
+       
+       @Override
+       public String toString() {
+               return getName();
+       }
+       
+       private Vector3d position = new Vector3d();
+       private Quat4d orientation = MathTools.getIdentityQuat();
+       
+       @Override
+       @GetPropertyValue(value = G3D.URIs.hasOrientation, tabId = "Transform", name = "Orientation")
+       public Quat4d getOrientation() {
+               return orientation;
+       }
+       
+       @RelatedGetValue(G3D.URIs.hasOrientation)
+       public double[] getOrientationArr() {
+               double arr[] = new double[4];
+               orientation.get(arr);
+               return arr;
+               
+       }
+       
+       @Override
+       @GetPropertyValue(value = G3D.URIs.hasPosition, tabId = "Transform", name = "Position")
+       public Vector3d getPosition() {
+               return position;
+       }
+       
+       @RelatedGetValue(G3D.URIs.hasPosition)
+       public double[] getPositionArr() {
+               double arr[] = new double[3];
+               position.get(arr);
+               return arr;
+       }
+       
+       @RelatedElementsAdd(CSG.URIs.hasPrimaryShape)
+       public void addPrimaryChild(ICSGnode node) {
+               addNode("primary",node);
+       }
+       
+       @RelatedElementsGet(CSG.URIs.hasPrimaryShape)
+       public Collection<ICSGnode> getPrimaryChild() {
+               return getNodes("primary");
+       }
+       
+       @RelatedElementsRem(CSG.URIs.hasPrimaryShape)
+       public void remPrimaryChild(ICSGnode node) {
+               removeNode("primary", node);
+       }
+       
+       @RelatedElementsAdd(CSG.URIs.hasSecondaryShape)
+       public void addSecondaryChild(ICSGnode node) {
+               addNode("secondary",node);
+       }
+       
+       @RelatedElementsGet(CSG.URIs.hasSecondaryShape)
+       public Collection<ICSGnode> getSecondaryChild() {
+               return getNodes("secondary");
+       }
+       
+       @RelatedElementsRem(CSG.URIs.hasSecondaryShape)
+       public void remSecondaryChild(ICSGnode node) {
+               removeNode("secondary", node);
+       }
+       
+
+       @RelatedElementsAdd(CSG.URIs.hasChildShape)
+       public void addChild(ICSGnode node) {
+               addNode("child",node);
+       }
+       
+       @RelatedElementsGet(CSG.URIs.hasChildShape)
+       public Collection<ICSGnode> getChild() {
+               return getNodes("child");
+       }
+       
+       @RelatedElementsRem(CSG.URIs.hasChildShape)
+       public void remChild(ICSGnode node) {
+               removeNode("child", node);
+       }
+       
+       
+       
+       protected TopoDS_Shape getPrimary() {
+               for (ICSGnode node : getNodes("primary"))
+                       return node.getGeometry();
+               return null;
+       }
+       
+       protected TopoDS_Shape getSecondary() {
+               for (ICSGnode node : getNodes("secondary"))
+                       return node.getGeometry();
+               return null;
+       }
+       
+       @Override
+       public TopoDS_Shape getGeometry() {
+               TopoDS_Shape shape = getBaseGeometry();
+               if (shape == null)
+                       return null;
+               Quat4d q = getOrientation();
+               AxisAngle4d r = new AxisAngle4d();
+               r.set(q);
+               TopoDS_Shape tshape = OccTriangulator.makeRotation(shape, new double[] { 0.0, 0.0, 0.0, r.x, r.y, r.z }, r.angle);
+               shape.delete();
+               shape = tshape;
+               Vector3d p = getPosition();
+               tshape = OccTriangulator.makeTranslation(shape, p.x, p.y, p.z);
+               shape.delete();
+               return tshape;
+                       
+       }
+       
+
+       
+       @Override
+       @SetPropertyValue(G3D.URIs.hasOrientation)
+       public void setOrientation(Quat4d orientation) {
+               assert(orientation != null);
+               this.orientation = orientation;
+               
+               firePropertyChanged(G3D.URIs.hasOrientation);
+       }
+       
+       @Override
+       @SetPropertyValue(G3D.URIs.hasPosition)
+       public void setPosition(Vector3d position) {
+               assert(position != null);
+               this.position = position;
+               
+               firePropertyChanged(G3D.URIs.hasPosition);
+       }
+       
+       @RelatedSetValue(G3D.URIs.hasOrientation)
+       public void setOrientation(double[] arr) {
+               if (arr == null)
+                       return;
+               setOrientation(new Quat4d(arr));
+       }
+       
+       @RelatedSetValue(G3D.URIs.hasPosition)
+       public void setPosition(double[] arr) {
+               if (arr == null)
+                       return;
+               setPosition(new Vector3d(arr));
+       }
+       
+       @Override
+       @GetPropertyValue(value = G3D.URIs.hasWorldPosition, tabId = "Transform", name = "World Position")
+       public Vector3d getWorldPosition() {
+               IG3DNode parent = (IG3DNode) getParent();
+               if (parent == null)
+                       return position;
+               return NodeTools.getWorldPosition(parent, new Vector3d(position));
+       }
+
+       public Vector3d getWorldPosition(Vector3d localPosition) {
+               return NodeTools.getWorldPosition(this, localPosition);
+       }
+
+       
+       @Override
+       @GetPropertyValue(value = G3D.URIs.hasWorldOrientation, tabId = "Transform", name = "World Orientation")
+       public Quat4d getWorldOrientation() {
+               return getWorldOrientation(new Quat4d(orientation));
+       }
+       
+       public Quat4d getWorldOrientation(Quat4d localOrientation) {
+               IG3DNode parent = (IG3DNode)getParent();
+               if (parent == null)
+                       return localOrientation;
+               return NodeTools.getWorldOrientation(parent, localOrientation);
+       }
+       
+       @Override
+       public Vector3d getLocalPosition(Vector3d worldPosition) {
+               IG3DNode parent = (IG3DNode)getParent();
+               if (parent == null)
+                       return worldPosition;
+               return NodeTools.getLocalPosition(parent,new Vector3d(worldPosition));
+       }
+       
+       @Override
+       public Quat4d getLocalOrientation(Quat4d worldOrientation) {
+               IG3DNode parent = (IG3DNode)getParent();
+               if (parent == null)
+                       return worldOrientation;
+               return NodeTools.getLocalOrientation(parent, new Quat4d(worldOrientation));
+       }
+       
+       @Override
+       @SetPropertyValue(G3D.URIs.hasWorldPosition)
+       public void setWorldPosition(Vector3d position) {
+               Vector3d localPos = getLocalPosition(position);
+               setPosition(localPos);
+       }
+       
+       @Override
+       @SetPropertyValue(G3D.URIs.hasWorldOrientation)
+       public void setWorldOrientation(Quat4d orientation) {
+               Quat4d localOr = getLocalOrientation(orientation);
+               setOrientation(localOr);
+       }
+
+
+       private vtkSolidObject solidObject;
+       
+       
+       public void visualize(VtkView panel) {
+               if (solidObject != null) {
+                       solidObject.delete();
+                       solidObject = null;
+               }
+               TopoDS_Shape shape = getGeometry();
+               if (shape == null)
+                       return;
+               solidObject = new vtkSolidObject(panel, shape);
+               solidObject.visualizeSolid(true, false);
+       }
+       
+       @SuppressWarnings("unchecked")
+       public Collection<vtkProp3D> getActors() {
+               if (solidObject == null)
+                       return Collections.EMPTY_LIST;
+               return solidObject.getActors();
+       }
+       
+       public void stopVisualize() {
+               if (solidObject != null) {
+                       if (Thread.currentThread() == AWTThread.getThreadAccess().getThread())
+                               solidObject.delete();
+                       else
+                               solidObject.dispose();
+                       solidObject = null;
+               }
+       }
+       
+       @Override
+       public void cleanup() {
+               stopVisualize();
+               super.cleanup();
+       }
+       
+       
+       @Override
+       public void remove() {
+               //FIXME: creating boolean shapes (removing nodes from parent and attaching under boolean shape would destroy the existing hierarchy, if default implementation is used.
+               super.remove();
+       }
+
+       @Override
+       public Object getAdapter(Class adapter) {
+               return null;
+       }
+}
index 2f6ef6b7d60ec52e10be006e30ff33820ebb80b2..3f0568cd00fc3881b602269de4ee2ff957173310 100644 (file)
@@ -1,39 +1,39 @@
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.csg.scenegraph2;\r
-\r
-import java.util.Collection;\r
-\r
-import org.jcae.opencascade.jni.TopoDS_Shape;\r
-import org.simantics.g3d.scenegraph.IG3DNode;\r
-\r
-import vtk.vtkPanel;\r
-import vtk.vtkProp3D;\r
-\r
-public interface ICSGnode extends IG3DNode {\r
-       \r
-       \r
-       public String getName();\r
-       public void setName(String name);\r
-       \r
-       public TopoDS_Shape getBaseGeometry();\r
-       \r
-       public TopoDS_Shape getGeometry();\r
-       \r
-       \r
-       public void visualize(vtkPanel panel);\r
-       public void stopVisualize();\r
-       \r
-       public Collection<vtkProp3D> getActors();\r
-       \r
-       public void deattach();\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.csg.scenegraph2;
+
+import java.util.Collection;
+
+import org.jcae.opencascade.jni.TopoDS_Shape;
+import org.simantics.g3d.scenegraph.IG3DNode;
+import org.simantics.g3d.vtk.common.VtkView;
+
+import vtk.vtkProp3D;
+
+public interface ICSGnode extends IG3DNode {
+       
+       
+       public String getName();
+       public void setName(String name);
+       
+       public TopoDS_Shape getBaseGeometry();
+       
+       public TopoDS_Shape getGeometry();
+       
+       
+       public void visualize(VtkView panel);
+       public void stopVisualize();
+       
+       public Collection<vtkProp3D> getActors();
+       
+       public void deattach();
+}
index a375776054e4473caa65c51290faeb6faf76095d..3a9a0aaed986a890893a6896a347ced60b03c9da 100644 (file)
@@ -17,13 +17,17 @@ Require-Bundle: org.eclipse.core.runtime,
  org.simantics.db.common;bundle-version="1.1.0",
  org.simantics.g3d.ontology;bundle-version="1.0.0",
  vtk;bundle-version="5.10.0",
- org.simantics.utils.ui;bundle-version="1.1.0"
+ org.simantics.utils.ui;bundle-version="1.1.0",
+ vtk.rendering;bundle-version="8.2.0",
+ org.simantics.utils.thread.swt;bundle-version="1.1.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Export-Package: org.simantics.g3d.vtk.action,
+ org.simantics.g3d.vtk.awt,
  org.simantics.g3d.vtk.common,
  org.simantics.g3d.vtk.gizmo,
  org.simantics.g3d.vtk.handlers,
  org.simantics.g3d.vtk.property,
  org.simantics.g3d.vtk.shape,
+ org.simantics.g3d.vtk.swt,
  org.simantics.g3d.vtk.utils
index f95c875f3aa21c1374a9e759ed2f23c956c764bb..01327c519cc577fdbb533992a13585c1bd959144 100644 (file)
@@ -1,99 +1,9 @@
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.vtk.action;\r
-\r
-import java.awt.event.KeyEvent;\r
-import java.awt.event.KeyListener;\r
-import java.awt.event.MouseEvent;\r
-import java.awt.event.MouseListener;\r
-import java.awt.event.MouseMotionListener;\r
-\r
-import org.eclipse.jface.action.Action;\r
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;\r
-\r
-public abstract class vtkAction extends Action implements KeyListener, MouseListener, MouseMotionListener {\r
-\r
-       protected InteractiveVtkPanel panel;\r
-       \r
-       public vtkAction(InteractiveVtkPanel panel) {\r
-               this.panel = panel;\r
-       }\r
-       \r
-       @Override\r
-       public void run() {\r
-               panel.setActiveAction(this);\r
-       }\r
-       \r
-       \r
-       public void attach() {\r
-\r
-               panel.addKeyListener(this);\r
-               panel.addMouseListener(this);\r
-               panel.addMouseMotionListener(this);\r
-\r
-       }\r
-       \r
-       public void deattach() {\r
-               panel.removeKeyListener(this);\r
-               panel.removeMouseListener(this);\r
-               panel.removeMouseMotionListener(this);\r
-       }\r
-       \r
-       @Override\r
-       public void keyPressed(KeyEvent e) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void keyReleased(KeyEvent e) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void keyTyped(KeyEvent e) {\r
-               \r
-       }\r
-       \r
-       public void mouseClicked(java.awt.event.MouseEvent e) {\r
-               \r
-       };\r
-       \r
-       @Override\r
-       public void mouseDragged(MouseEvent e) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void mouseEntered(MouseEvent e) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void mouseExited(MouseEvent e) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void mouseMoved(MouseEvent e) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void mousePressed(MouseEvent e) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void mouseReleased(MouseEvent e) {\r
-       \r
-       }\r
-}\r
+package org.simantics.g3d.vtk.action;
+
+import org.eclipse.jface.action.Action;
+
+public abstract class vtkAction extends Action{
+
+       public abstract void attach();
+       public abstract void deattach();
+}
similarity index 93%
rename from org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/InteractiveVtkPanel.java
rename to org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/InteractiveVtkPanel.java
index e6129b5d537d6879a30391019d854666f565cdca..df91a5d4c7960d1735e311aadcaa7754b5b57583 100644 (file)
@@ -9,7 +9,7 @@
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
  *******************************************************************************/
-package org.simantics.g3d.vtk.common;
+package org.simantics.g3d.vtk.awt;
 
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
@@ -18,6 +18,9 @@ import java.util.List;
 
 import org.simantics.g3d.scenegraph.RenderListener;
 import org.simantics.g3d.vtk.action.vtkAction;
+import org.simantics.g3d.vtk.common.VtkView;
+import org.simantics.utils.threads.AWTThread;
+import org.simantics.utils.threads.IThreadWorkQueue;
 
 import vtk.vtkAbstractPicker;
 import vtk.vtkAreaPicker;
@@ -33,9 +36,10 @@ import vtk.vtkProp;
 import vtk.vtkProp3DCollection;
 import vtk.vtkPropCollection;
 import vtk.vtkPropPicker;
+import vtk.vtkRenderer;
 import vtk.vtkScenePicker;
 
-public class InteractiveVtkPanel extends vtkPanel {
+public class InteractiveVtkPanel extends vtkPanel implements VtkView {
        
        protected vtkGenericRenderWindowInteractor iren;
     
@@ -59,6 +63,16 @@ public class InteractiveVtkPanel extends vtkPanel {
         addDeletable(iren);
        }
        
+       @Override
+       public IThreadWorkQueue getThreadQueue() {
+               return AWTThread.getThreadAccess();
+       }
+       
+       @Override
+       public vtkRenderer getRenderer() {
+               return GetRenderer();
+       }
+       
        @Override
        public void mouseClicked(MouseEvent e) {
 
@@ -322,21 +336,21 @@ public class InteractiveVtkPanel extends vtkPanel {
        }
        
        
-       private vtkAction defaultAction;
-       private vtkAction currentAction;
+       private vtkAwtAction defaultAction;
+       private vtkAwtAction currentAction;
        
        public void setActiveAction(vtkAction action) {
                if (action.equals(currentAction))
                        return;
                if (currentAction != null)
                        currentAction.deattach();
-               currentAction = action;
+               currentAction = (vtkAwtAction)action;
                if (action != null)
                        action.attach();
        }
        
        public void setDefaultAction(vtkAction defaultAction) {
-               this.defaultAction = defaultAction;
+               this.defaultAction = (vtkAwtAction)defaultAction;
        }
        
        public void useDefaultAction() {
@@ -412,4 +426,12 @@ public class InteractiveVtkPanel extends vtkPanel {
                
                super.Delete();
        }
+       
+       @Override
+       public void refresh() {
+               repaint();
+       }
+       
+       
+       
 }
similarity index 95%
rename from org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/RotateAction.java
rename to org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/RotateAction.java
index d47456fdbca390145b381b3ab07209e2989cb688..f7ffc5530e2b1dc77a2ea275177070b1b93081b7 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.vtk.action;\r
-\r
-import java.awt.Cursor;\r
-import java.awt.event.KeyEvent;\r
-import java.awt.event.MouseEvent;\r
-\r
-import javax.vecmath.AxisAngle4d;\r
-import javax.vecmath.Point3d;\r
-import javax.vecmath.Quat4d;\r
-import javax.vecmath.Vector3d;\r
-\r
-import org.simantics.g3d.math.EulerTools;\r
-import org.simantics.g3d.math.MathTools;\r
-import org.simantics.g3d.math.Ray;\r
-import org.simantics.g3d.math.EulerTools.Order;\r
-import org.simantics.g3d.preferences.PreferenceConstants;\r
-import org.simantics.g3d.scenegraph.IG3DNode;\r
-import org.simantics.g3d.scenegraph.structural.IStructuralNode;\r
-import org.simantics.g3d.vtk.Activator;\r
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;\r
-import org.simantics.g3d.vtk.common.VTKNodeMap;\r
-import org.simantics.g3d.vtk.gizmo.RotateAxisGizmo;\r
-import org.simantics.g3d.vtk.utils.vtkUtil;\r
-import org.simantics.utils.threads.AWTThread;\r
-import org.simantics.utils.threads.ThreadUtils;\r
-\r
-import vtk.vtkProp;\r
-/**\r
- * FIXME: complete rewrite.\r
- * \r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public class RotateAction extends vtkAction{\r
-       \r
-       public static final int X = 0;\r
-    public static final int Y = 1;\r
-    public static final int Z = 2;\r
-    public static final int P = 3;\r
-\r
-       private VTKNodeMap nodeMap;\r
-       //private TranslateGizmo  gizmo = new TranslateGizmo();\r
-       private RotateAxisGizmo gizmo = new RotateAxisGizmo();\r
-       private IG3DNode node;\r
-       \r
-       \r
-       \r
-       private Cursor activeCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);\r
-       private Cursor dragCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);\r
-       \r
-       \r
-       int stepMethod = 1;\r
-       Order order = Order.YXZ;\r
-       \r
-    private int steps; \r
-    private double angles[];\r
-       \r
-       int index = P;\r
-       boolean valid = false;\r
-       private boolean worldCoord = true;\r
-       //private AxisAngle4d aa = null;\r
-       private Quat4d parentWorldOrientation = null;\r
-       \r
-       //AxisAngle4d rotation = new AxisAngle4d();\r
-       Quat4d worldOrientation = new Quat4d();\r
-       \r
-       public void setNode(IG3DNode node) {\r
-               this.node = node;\r
-               if ((node instanceof IStructuralNode) && ((IStructuralNode)node).isPartOfInstantiatedModel() && !((IStructuralNode)node).isInstantiatedModelRoot()) {\r
-                       setEnabled(false);\r
-               } else {\r
-                       setEnabled(true);\r
-               }\r
-               \r
-               String set = org.simantics.g3d.Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.ORIENTATION_PRESENTATION);\r
-               if (set.equals("aa")) {\r
-                       stepMethod = 0;\r
-               } else if (set.equals("euler")){\r
-                       stepMethod = 1;\r
-                       String eulerOrder = org.simantics.g3d.Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.EULER_ANGLE_ORDER);\r
-                       try {\r
-                               order = Order.valueOf(eulerOrder);\r
-                       } catch (Exception e) {\r
-                               order = Order.YXZ;\r
-                       }\r
-               } else {\r
-                       stepMethod = 2;\r
-               }\r
-       }\r
-       \r
-       public IG3DNode getNode() {\r
-               return node;\r
-       }\r
-       \r
-       public RotateAction(InteractiveVtkPanel panel, VTKNodeMap nodeMap) {\r
-               super(panel);\r
-               setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_rotate_clockwise.png"));\r
-               setText("Rotate");\r
-               this.nodeMap = nodeMap;\r
-               \r
-               \r
-               steps = 36;\r
-        angles = new double[steps+1];\r
-        for (int i = 0; i < angles.length; i++) {\r
-            angles[i] = - Math.PI + (Math.PI * i * 2.0 / steps);\r
-        }\r
-       }\r
-       \r
-       public void attach() {\r
-               if (node == null)\r
-                       return;\r
-               \r
-               super.attach();\r
-               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {\r
-                       public void run() {\r
-                               attachUI();\r
-                               update();\r
-                       }\r
-               });\r
-               \r
-               \r
-               \r
-       }\r
-       \r
-       public void deattach() {\r
-               \r
-               node = null;\r
-               nodeMap.commit();\r
-               deattachUI();\r
-               super.deattach();\r
-               panel.repaint();\r
-       }\r
-       \r
-       private void attachUI() {\r
-               panel.setCursor(activeCursor);\r
-               gizmo.attach(panel.GetRenderer());\r
-       }\r
-       \r
-       private void deattachUI() {\r
-               panel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));\r
-               gizmo.deattach();\r
-       }\r
-       \r
-       @Override\r
-       public void keyPressed(KeyEvent e) {\r
-               if (e.getKeyCode() == KeyEvent.VK_ESCAPE)\r
-                       panel.useDefaultAction();\r
-               if (valid)\r
-                       return;\r
-               if (e.getKeyCode() == KeyEvent.VK_X) {\r
-                       if (index != X)\r
-                               index = X;\r
-                       else\r
-                               index = P;\r
-               }\r
-               if (e.getKeyCode() == KeyEvent.VK_Y) {\r
-                       if (index != Y)\r
-                               index = Y;\r
-                       else\r
-                               index = P;\r
-               }\r
-               if (e.getKeyCode() == KeyEvent.VK_Z) {\r
-                       if (index != Z)\r
-                               index = Z;\r
-                       else\r
-                               index = P;\r
-               }\r
-               if (e.getKeyCode() == KeyEvent.VK_G) {\r
-                       worldCoord = !worldCoord;\r
-               }\r
-               gizmo.setType(index);\r
-               panel.repaint();\r
-       }\r
-       \r
-       @Override\r
-       public void keyReleased(KeyEvent e) {\r
-               \r
-       }\r
-       \r
-       \r
-       \r
-       @Override\r
-       public void mouseClicked(MouseEvent e) {\r
-               if (e.getClickCount() > 1) {\r
-                       if (isOverNode(e)) {\r
-                               return;\r
-                       }\r
-                       panel.useDefaultAction();\r
-                       //if(!gizmo.isPartOf(actor))\r
-                       //      panel.useDefaultAction();\r
-                       \r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public void mouseEntered(MouseEvent e) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void mouseExited(MouseEvent e) {\r
-               \r
-       }\r
-       \r
-       \r
-\r
-       \r
-       \r
-       public void setWorldCoord(boolean b) {\r
-               if (worldCoord == b)\r
-                       return;\r
-               worldCoord = b;\r
-               update();\r
-                                       \r
-       }\r
-       \r
-       \r
-       private void update() {\r
-               Vector3d nodePos = node.getWorldPosition();\r
-               System.out.println(nodePos);\r
-               gizmo.setPosition(nodePos);\r
-               if (worldCoord) {\r
-                       gizmo.setRotation(new AxisAngle4d());\r
-                       parentWorldOrientation = null;\r
-               } else {\r
-                       AxisAngle4d aa = new AxisAngle4d();\r
-                       parentWorldOrientation = ((IG3DNode)node.getParent()).getWorldOrientation();\r
-                       aa.set(parentWorldOrientation);\r
-                       gizmo.setRotation(aa);\r
-               }\r
-\r
-               Point3d camPos = new Point3d(panel.GetRenderer().GetActiveCamera().GetPosition());\r
-               Vector3d p = new Vector3d(nodePos);\r
-               p.sub(camPos);\r
-               \r
-               if (parentWorldOrientation != null) {\r
-                       Quat4d qi = new Quat4d(parentWorldOrientation);\r
-                       qi.inverse();\r
-                       MathTools.rotate(parentWorldOrientation, p, p);\r
-               }\r
-               if (panel.GetRenderer().GetActiveCamera().GetParallelProjection() == 0) {\r
-                       double distance = p.length();\r
-                       p.negate();\r
-            double fov = panel.GetRenderer().GetActiveCamera().GetViewAngle();\r
-            float s = (float) (Math.sin(fov) * distance * 0.1); \r
-\r
-            Vector3d scale = new Vector3d(1., 1., 1.);\r
-            \r
-//            if (p.x > 0.f)\r
-//                scale.x = -1.;\r
-//            if (p.y > 0.f)\r
-//                scale.y = -1.;\r
-//            if (p.z > 0.f)\r
-//                scale.z = -1.;\r
-            scale.scale(s);\r
-            gizmo.setScale(scale);\r
-                       \r
-               } else {\r
-                       Vector3d scale = new Vector3d(1.f, 1.f, 1.f);\r
-            double s = panel.GetRenderer().GetActiveCamera().GetParallelScale() / 5.;\r
-//            if (p.x > 0.f)\r
-//                scale.x = -1.;\r
-//            if (p.y > 0.f)\r
-//                scale.y = -1.;\r
-//            if (p.z > 0.f)\r
-//                scale.z = -1.;\r
-            scale.scale(s);\r
-            gizmo.setScale(scale);\r
-               }\r
-               \r
-               panel.Render();\r
-       }\r
-       \r
-       private boolean isOverNode(MouseEvent e) {\r
-               vtkProp picked[] = panel.pick(e.getX(), e.getY());\r
-               if (picked !=null) {\r
-                       for (int i = 0; i < picked.length; i++) {\r
-                               if (node.equals(nodeMap.getNode(picked[i])))\r
-                                       return true;\r
-                       }\r
-               }\r
-               return false;\r
-       }\r
-       \r
-\r
-       \r
-       @Override\r
-       public void mousePressed(MouseEvent e) {\r
-               if (e.getButton() == MouseEvent.BUTTON1) {\r
-       \r
-       \r
-                       if (isOverNode(e)) {\r
-                               valid = true;\r
-                               if ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0) {\r
-                                       useStep = true;\r
-                   } else {\r
-                       useStep = false;\r
-                   }\r
-                               worldOrientation = node.getWorldOrientation();\r
-                               doChanges(true, e.getX(), e.getY());\r
-                               \r
-                               panel.setCursor(dragCursor);\r
-                       } else {\r
-                               valid = false;\r
-                               panel.getDefaultAction().mousePressed(e);\r
-                               panel.setCursor(activeCursor);\r
-                       }\r
-               } else {\r
-                       panel.getDefaultAction().mousePressed(e);\r
-               }\r
-       }\r
-       \r
-       \r
-       \r
-       @Override\r
-       public void mouseReleased(MouseEvent e) {\r
-               if (e.getButton() == MouseEvent.BUTTON1) {\r
-                       valid = false;\r
-                       worldOrientation = null;\r
-                       panel.setCursor(activeCursor);\r
-               } else {\r
-                       panel.getDefaultAction().mouseReleased(e);\r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public void mouseDragged(MouseEvent e) {\r
-               if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) > 0 && valid) { \r
-                       if ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0) {\r
-                               useStep = true;\r
-            } else {\r
-                useStep = false;\r
-            }\r
-                       doChanges(false, e.getX(), e.getY());\r
-                       \r
-                       //nodeMap.modified(node);\r
-                       update();\r
-               } else {\r
-                       panel.getDefaultAction().mouseDragged(e);\r
-                       update();\r
-               }\r
-       }\r
-       \r
-        Vector3d axis = null;\r
-       \r
-       @Override\r
-       public void keyTyped(KeyEvent e) {\r
-                if (e.getKeyCode() == KeyEvent.VK_LEFT) {\r
-               inputType = InputType.KEY;\r
-               axis = new Vector3d(0.0,1.0,0.0);\r
-            } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {\r
-                       inputType = InputType.KEY;\r
-                       axis = new Vector3d(0.0,-1.0,0.0);\r
-            } else if (e.getKeyCode() ==KeyEvent.VK_UP) {\r
-                       inputType = InputType.KEY;\r
-                       axis = new Vector3d(1.0,0.0,0.0);\r
-            } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {\r
-                       inputType = InputType.KEY;\r
-                       axis = new Vector3d(-1.0,0.0,0.0);\r
-            } \r
-       }\r
-       \r
-    public void doChanges(boolean pressed, int x, int y) {\r
-       Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(),x, y);\r
-       Vector3d p = node.getWorldPosition();\r
-        \r
-       if (pressed) {\r
-            Vector3d axis = getRotationAxis();\r
-            if (axis != null) {\r
-               if (!worldCoord) {\r
-                       MathTools.rotate(parentWorldOrientation, axis, axis);\r
-               }\r
-\r
-               \r
-                double s[] = new double[2];\r
-                Vector3d i2 = new Vector3d();\r
-               \r
-                boolean intersect = MathTools.intersectStraightPlane(ray.pos, ray.dir, p, axis, i2, s);\r
-                double dot = Math.abs(ray.dir.dot(axis));\r
-                if (intersect &&  dot > 0.4)\r
-                       inputType = InputType.INTERSECT;\r
-                else\r
-                       inputType = InputType.NONINTERSECT;\r
-                       \r
-                \r
-                if (inputType == InputType.INTERSECT) {\r
-                    // picking ray and plane defined by gizmo's center point and\r
-                    // rotation axis can intersect\r
-                    // vector from center point to intersection point\r
-                    i2.sub(p);\r
-                    // creating vectors i and j that are lying on the plane and\r
-                    // are perpendicular\r
-                    // vectors are used to calculate polar coordinate for\r
-                    // intersection point\r
-                    j.set(i2);\r
-                    i.cross(j, axis);\r
-                    System.out.println("I,J " + i + " " + j);\r
-                    double angleI = i2.angle(i);\r
-                    double angleJ = i2.angle(j);\r
-                    prevAngle = Math.atan2(Math.cos(angleJ), Math.cos(angleI));\r
-                } else {\r
-                    // picking ray and plane defined by gizmo's center point and\r
-                    // rotation axis are parallel,\r
-                    // so we'll use cross product of rotation axis and picking\r
-                    // ray to detect amount of rotation\r
-                    i.cross(ray.dir, axis);\r
-                    MathTools.intersectStraightStraight(ray.pos, ray.dir, p, i, new Vector3d(), new Vector3d(), s);\r
-                    prevS = s[1];\r
-                }\r
-            }\r
-           \r
-            \r
-        }\r
-\r
-        if (inputType != InputType.KEY)\r
-               axis = getRotationAxis();\r
-        if (axis == null) {\r
-            return;   \r
-        }\r
-        Vector3d taxis = null;\r
-        if (!worldCoord) {\r
-               taxis = new Vector3d(axis);\r
-               MathTools.rotate(parentWorldOrientation, axis, axis);\r
-       }\r
-        System.out.println(inputType);\r
-        if (inputType == InputType.INTERSECT) {\r
-\r
-            double s[] = new double[2];\r
-            Vector3d i2 = new Vector3d();\r
-            MathTools.intersectStraightPlane(ray.pos, ray.dir, p, axis, i2, s);\r
-            i2.sub(p);\r
-            double angleI = i2.angle(i);\r
-            double angleJ = i2.angle(j);\r
-            double angle = Math.atan2(Math.cos(angleJ), Math.cos(angleI));\r
-            System.out.println("Angle " + angle + " i " + angleI + " j " + angleJ + " prev " + prevAngle);\r
-            if(!worldCoord)\r
-               axis = taxis;\r
-            if (useStep) {\r
-\r
-               //setOrientation(MathTools.getQuat(rotation));\r
-               AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);\r
-               Quat4d qrot = new Quat4d();\r
-               MathTools.getQuat(rot, qrot);\r
-               //prevAngle = angle;\r
-               qrot.mulInverse(worldOrientation);\r
-               \r
-          \r
-               if (stepMethod == 0) {\r
-                       rot.set(qrot);\r
-                       rot.angle = roundAngle(rot.angle);\r
-                       //qrot.set(rot);\r
-                       MathTools.getQuat(rot,qrot);\r
-                       setOrientation(qrot);\r
-               } else if (stepMethod == 1){\r
-                         \r
-                       //Vector3d euler = MathTools.getEuler(qrot);\r
-                       Vector3d euler = EulerTools.getEulerFromQuat(order, qrot);\r
-                       euler.x = roundAngle(euler.x);\r
-                       euler.y = roundAngle(euler.y);\r
-                       euler.z = roundAngle(euler.z);\r
-                       //Quat4d q = MathTools.getQuat(euler);\r
-                       Quat4d q = EulerTools.getQuatFromEuler(order, euler);\r
-                       setOrientation(q);\r
-                       System.out.println(" (" + MathTools.radToDeg(euler.x) + " " + MathTools.radToDeg(euler.y) + " " + MathTools.radToDeg(euler.z) +  ") " + qrot + " "+ q);\r
-               } else {\r
-                       setOrientation(qrot);\r
-               }\r
-               \r
-            } else {\r
-                if (worldCoord) {\r
-                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,angle-prevAngle));\r
-                       AxisAngle4d aa = MathTools.getAxisAngle(node.getWorldOrientation());\r
-                       AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);\r
-                       MathTools.multiplyOrientation(aa, rot);\r
-                       setWorldOrientation(MathTools.getQuat(rot));\r
-                } else {\r
-                       AxisAngle4d aa = MathTools.getAxisAngle(node.getOrientation());\r
-                       AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);\r
-                       MathTools.multiplyOrientation(aa, rot);\r
-                       setOrientation(MathTools.getQuat(rot));\r
-                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,angle-prevAngle));\r
-                }\r
-                prevAngle = angle;\r
-            }\r
-            \r
-        } else if (inputType == InputType.NONINTERSECT){\r
-\r
-            double s[] = new double[2];\r
-            MathTools.intersectStraightStraight(ray.pos, ray.dir, p, i, new Vector3d(), new Vector3d(), s);\r
-            if(!worldCoord)\r
-               axis = taxis;\r
-            if (useStep) {\r
-               //setOrientation(MathTools.getQuat(rotation));\r
-               AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);\r
-                \r
-               Quat4d qrot = new Quat4d();\r
-               //qrot.set(rot);\r
-               MathTools.getQuat(rot, qrot);\r
-               //prevAngle = angle;\r
-               qrot.mulInverse(worldOrientation);\r
-               \r
-          \r
-               if (stepMethod == 0) {\r
-                       rot.set(qrot);\r
-                       rot.angle = roundAngle(rot.angle);\r
-                       //qrot.set(rot);\r
-                       MathTools.getQuat(rot,qrot);\r
-                       setOrientation(qrot);\r
-               } else if (stepMethod == 1){\r
-                         \r
-                       //Vector3d euler = MathTools.getEuler(qrot);\r
-                       Vector3d euler = EulerTools.getEulerFromQuat(order, qrot);\r
-                       euler.x = roundAngle(euler.x);\r
-                       euler.y = roundAngle(euler.y);\r
-                       euler.z = roundAngle(euler.z);\r
-                       //Quat4d q = MathTools.getQuat(euler);\r
-                       Quat4d q = EulerTools.getQuatFromEuler(order, euler);\r
-                       setOrientation(q);\r
-                       System.out.println(" (" + MathTools.radToDeg(euler.x) + " " + MathTools.radToDeg(euler.y) + " " + MathTools.radToDeg(euler.z) +  ") " + qrot + " "+ q);\r
-               } else {\r
-                       setOrientation(qrot);\r
-               }\r
-                prevS = s[1];\r
-               \r
-//                    G3DTools.setOrientation(mo.getG3DNode(graph).getLocalOrientation(), rotations.get(mo));\r
-//                    G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,s[1] - prevS));\r
-//                    AxisAngle4d aa = G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation());\r
-//                    rotations.put(mo, aa);\r
-//                    Vector3d euler = MathTools.getEuler(aa);\r
-//                    euler.x = roundAngle(euler.x);\r
-//                    euler.y = roundAngle(euler.y);\r
-//                    euler.z = roundAngle(euler.z);\r
-//                    aa = MathTools.getFromEuler2(euler);\r
-//                    prevS = s[1];\r
-//                    G3DTools.setOrientation(mo.getG3DNode(graph).getLocalOrientation(), aa);\r
-//                    Vector3d e = MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()));\r
-//                    e.scale(180.0/Math.PI);\r
-//                    text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + e + " ";\r
-               \r
-               \r
-            } else {\r
-                       if (worldCoord) {\r
-                               AxisAngle4d aa =  MathTools.getAxisAngle(node.getWorldOrientation());\r
-                       AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);\r
-                       MathTools.multiplyOrientation(aa, rot);\r
-                       setWorldOrientation(MathTools.getQuat(rot));\r
-                               //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,s[1] - prevS));\r
-                       } else {\r
-                               AxisAngle4d aa =  MathTools.getAxisAngle(node.getOrientation());\r
-                       AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);\r
-                       MathTools.multiplyOrientation(aa, rot);\r
-                       setOrientation(MathTools.getQuat(rot));\r
-                               //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,s[1] - prevS));\r
-                       }\r
-                       //text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation())) + " ";\r
-                prevS = s[1];\r
-                \r
-            }\r
-           \r
-        } else {\r
-               if (worldCoord) {\r
-                       AxisAngle4d aa = MathTools.getAxisAngle(node.getWorldOrientation());\r
-               AxisAngle4d rot = new AxisAngle4d(axis,Math.PI * 0.5);\r
-               MathTools.multiplyOrientation(aa, rot);\r
-               setWorldOrientation(MathTools.getQuat(rot));\r
-                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,Math.PI * 0.5));\r
-               } else {\r
-                       AxisAngle4d aa = MathTools.getAxisAngle(node.getOrientation());\r
-               AxisAngle4d rot = new AxisAngle4d(axis,Math.PI * 0.5);\r
-               MathTools.multiplyOrientation(aa, rot);\r
-               setOrientation(MathTools.getQuat(rot));\r
-                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,Math.PI * 0.5));\r
-               }\r
-             //   text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation())) + " ";\r
-            \r
-        }\r
-        //setInfoText(text);\r
\r
-    }\r
-    \r
-    protected void setOrientation(Quat4d q) {\r
-       node.setOrientation(q);\r
-    }\r
-    \r
-    protected void setWorldOrientation(Quat4d q) {\r
-       node.setWorldOrientation(q);\r
-    }\r
-       \r
-       @Override\r
-       public void mouseMoved(MouseEvent e) {\r
-               panel.getDefaultAction().mouseMoved(e);\r
-       }\r
-       \r
-       private Vector3d getRotationAxis() {\r
-               switch (index) {\r
-               case X:\r
-                       return new Vector3d(1.0, 0.0, 0.0);\r
-               case Y:\r
-                       return new Vector3d(0.0, 1.0, 0.0);\r
-               case Z:\r
-                       return new Vector3d(0.0, 0.0, 1.0);\r
-               case P:\r
-                       Vector3d axis = new Vector3d(panel.GetRenderer().GetActiveCamera()\r
-                                       .GetDirectionOfProjection());\r
-                       axis.normalize();\r
-                       return axis;\r
-               default:\r
-                       return null;\r
-               }\r
-       }\r
-       \r
-        private double prevS = 0.0;\r
-           \r
-    private Vector3d i = new Vector3d();\r
-    private Vector3d j = new Vector3d();\r
-    private double prevAngle = 0;\r
-\r
-    enum InputType{INTERSECT,NONINTERSECT,KEY,NONE};\r
-    InputType inputType;\r
-    private boolean useStep = false;\r
-    \r
-    \r
-    \r
-    private double roundAngle(double angle) {\r
-        while (angle < - Math.PI)\r
-            angle += Math.PI*2.0;\r
-        while (angle > Math.PI)\r
-            angle -= Math.PI*2.0;\r
-        \r
-        \r
-        int index = 0;\r
-        while (angle > angles[index])\r
-            index++;\r
-        if (index == 0) {\r
-            angle = angles[0];\r
-        } else {\r
-            double d = angle - angles[index - 1];\r
-            double d2 = angles[index] - angle;\r
-            if (d < d2)\r
-                angle = angles[index - 1];\r
-            else\r
-                angle = angles[index];\r
-        }\r
-        return angle;\r
-    }\r
-       \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.awt;
+
+import java.awt.Cursor;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+
+import javax.vecmath.AxisAngle4d;
+import javax.vecmath.Point3d;
+import javax.vecmath.Quat4d;
+import javax.vecmath.Vector3d;
+
+import org.simantics.g3d.math.EulerTools;
+import org.simantics.g3d.math.EulerTools.Order;
+import org.simantics.g3d.math.MathTools;
+import org.simantics.g3d.math.Ray;
+import org.simantics.g3d.preferences.PreferenceConstants;
+import org.simantics.g3d.scenegraph.IG3DNode;
+import org.simantics.g3d.scenegraph.structural.IStructuralNode;
+import org.simantics.g3d.vtk.Activator;
+import org.simantics.g3d.vtk.common.VTKNodeMap;
+import org.simantics.g3d.vtk.gizmo.RotateAxisGizmo;
+import org.simantics.g3d.vtk.utils.vtkUtil;
+import org.simantics.utils.threads.AWTThread;
+import org.simantics.utils.threads.ThreadUtils;
+
+import vtk.vtkProp;
+/**
+ * FIXME: complete rewrite.
+ * 
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
+ *
+ */
+public class RotateAction extends vtkAwtAction{
+       
+       public static final int X = 0;
+    public static final int Y = 1;
+    public static final int Z = 2;
+    public static final int P = 3;
+
+       private VTKNodeMap nodeMap;
+       //private TranslateGizmo  gizmo = new TranslateGizmo();
+       private RotateAxisGizmo gizmo = new RotateAxisGizmo();
+       private IG3DNode node;
+       
+       
+       
+       private Cursor activeCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
+       private Cursor dragCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
+       
+       
+       int stepMethod = 1;
+       Order order = Order.YXZ;
+       
+    private int steps; 
+    private double angles[];
+       
+       int index = P;
+       boolean valid = false;
+       private boolean worldCoord = true;
+       //private AxisAngle4d aa = null;
+       private Quat4d parentWorldOrientation = null;
+       
+       //AxisAngle4d rotation = new AxisAngle4d();
+       Quat4d worldOrientation = new Quat4d();
+       
+       public void setNode(IG3DNode node) {
+               this.node = node;
+               if ((node instanceof IStructuralNode) && ((IStructuralNode)node).isPartOfInstantiatedModel() && !((IStructuralNode)node).isInstantiatedModelRoot()) {
+                       setEnabled(false);
+               } else {
+                       setEnabled(true);
+               }
+               
+               String set = org.simantics.g3d.Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.ORIENTATION_PRESENTATION);
+               if (set.equals("aa")) {
+                       stepMethod = 0;
+               } else if (set.equals("euler")){
+                       stepMethod = 1;
+                       String eulerOrder = org.simantics.g3d.Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.EULER_ANGLE_ORDER);
+                       try {
+                               order = Order.valueOf(eulerOrder);
+                       } catch (Exception e) {
+                               order = Order.YXZ;
+                       }
+               } else {
+                       stepMethod = 2;
+               }
+       }
+       
+       public IG3DNode getNode() {
+               return node;
+       }
+       
+       public RotateAction(InteractiveVtkPanel panel, VTKNodeMap nodeMap) {
+               super(panel);
+               setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_rotate_clockwise.png"));
+               setText("Rotate");
+               this.nodeMap = nodeMap;
+               
+               
+               steps = 36;
+        angles = new double[steps+1];
+        for (int i = 0; i < angles.length; i++) {
+            angles[i] = - Math.PI + (Math.PI * i * 2.0 / steps);
+        }
+       }
+       
+       public void attach() {
+               if (node == null)
+                       return;
+               
+               super.attach();
+               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+                       public void run() {
+                               attachUI();
+                               update();
+                       }
+               });
+               
+               
+               
+       }
+       
+       public void deattach() {
+               
+               node = null;
+               nodeMap.commit();
+               deattachUI();
+               super.deattach();
+               panel.repaint();
+       }
+       
+       private void attachUI() {
+               panel.setCursor(activeCursor);
+               gizmo.attach(panel);
+       }
+       
+       private void deattachUI() {
+               panel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+               gizmo.deattach();
+       }
+       
+       @Override
+       public void keyPressed(KeyEvent e) {
+               if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
+                       panel.useDefaultAction();
+               if (valid)
+                       return;
+               if (e.getKeyCode() == KeyEvent.VK_X) {
+                       if (index != X)
+                               index = X;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_Y) {
+                       if (index != Y)
+                               index = Y;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_Z) {
+                       if (index != Z)
+                               index = Z;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_G) {
+                       worldCoord = !worldCoord;
+               }
+               gizmo.setType(index);
+               panel.repaint();
+       }
+       
+       @Override
+       public void keyReleased(KeyEvent e) {
+               
+       }
+       
+       
+       
+       @Override
+       public void mouseClicked(MouseEvent e) {
+               if (e.getClickCount() > 1) {
+                       if (isOverNode(e)) {
+                               return;
+                       }
+                       panel.useDefaultAction();
+                       //if(!gizmo.isPartOf(actor))
+                       //      panel.useDefaultAction();
+                       
+               }
+       }
+       
+       @Override
+       public void mouseEntered(MouseEvent e) {
+               
+       }
+       
+       @Override
+       public void mouseExited(MouseEvent e) {
+               
+       }
+       
+       
+
+       
+       
+       public void setWorldCoord(boolean b) {
+               if (worldCoord == b)
+                       return;
+               worldCoord = b;
+               update();
+                                       
+       }
+       
+       
+       private void update() {
+               Vector3d nodePos = node.getWorldPosition();
+               System.out.println(nodePos);
+               gizmo.setPosition(nodePos);
+               if (worldCoord) {
+                       gizmo.setRotation(new AxisAngle4d());
+                       parentWorldOrientation = null;
+               } else {
+                       AxisAngle4d aa = new AxisAngle4d();
+                       parentWorldOrientation = ((IG3DNode)node.getParent()).getWorldOrientation();
+                       aa.set(parentWorldOrientation);
+                       gizmo.setRotation(aa);
+               }
+
+               Point3d camPos = new Point3d(panel.GetRenderer().GetActiveCamera().GetPosition());
+               Vector3d p = new Vector3d(nodePos);
+               p.sub(camPos);
+               
+               if (parentWorldOrientation != null) {
+                       Quat4d qi = new Quat4d(parentWorldOrientation);
+                       qi.inverse();
+                       MathTools.rotate(parentWorldOrientation, p, p);
+               }
+               if (panel.GetRenderer().GetActiveCamera().GetParallelProjection() == 0) {
+                       double distance = p.length();
+                       p.negate();
+            double fov = panel.GetRenderer().GetActiveCamera().GetViewAngle();
+            float s = (float) (Math.sin(fov) * distance * 0.1); 
+
+            Vector3d scale = new Vector3d(1., 1., 1.);
+            
+//            if (p.x > 0.f)
+//                scale.x = -1.;
+//            if (p.y > 0.f)
+//                scale.y = -1.;
+//            if (p.z > 0.f)
+//                scale.z = -1.;
+            scale.scale(s);
+            gizmo.setScale(scale);
+                       
+               } else {
+                       Vector3d scale = new Vector3d(1.f, 1.f, 1.f);
+            double s = panel.GetRenderer().GetActiveCamera().GetParallelScale() / 5.;
+//            if (p.x > 0.f)
+//                scale.x = -1.;
+//            if (p.y > 0.f)
+//                scale.y = -1.;
+//            if (p.z > 0.f)
+//                scale.z = -1.;
+            scale.scale(s);
+            gizmo.setScale(scale);
+               }
+               
+               panel.Render();
+       }
+       
+       private boolean isOverNode(MouseEvent e) {
+               vtkProp picked[] = panel.pick(e.getX(), e.getY());
+               if (picked !=null) {
+                       for (int i = 0; i < picked.length; i++) {
+                               if (node.equals(nodeMap.getNode(picked[i])))
+                                       return true;
+                       }
+               }
+               return false;
+       }
+       
+
+       
+       @Override
+       public void mousePressed(MouseEvent e) {
+               if (e.getButton() == MouseEvent.BUTTON1) {
+       
+       
+                       if (isOverNode(e)) {
+                               valid = true;
+                               if ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0) {
+                                       useStep = true;
+                   } else {
+                       useStep = false;
+                   }
+                               worldOrientation = node.getWorldOrientation();
+                               doChanges(true, e.getX(), e.getY());
+                               
+                               panel.setCursor(dragCursor);
+                       } else {
+                               valid = false;
+                               getDefaultAction().mousePressed(e);
+                               panel.setCursor(activeCursor);
+                       }
+               } else {
+                       getDefaultAction().mousePressed(e);
+               }
+       }
+       
+       
+       
+       @Override
+       public void mouseReleased(MouseEvent e) {
+               if (e.getButton() == MouseEvent.BUTTON1) {
+                       valid = false;
+                       worldOrientation = null;
+                       panel.setCursor(activeCursor);
+               } else {
+                       getDefaultAction().mouseReleased(e);
+               }
+       }
+       
+       @Override
+       public void mouseDragged(MouseEvent e) {
+               if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) > 0 && valid) { 
+                       if ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0) {
+                               useStep = true;
+            } else {
+                useStep = false;
+            }
+                       doChanges(false, e.getX(), e.getY());
+                       
+                       //nodeMap.modified(node);
+                       update();
+               } else {
+                       getDefaultAction().mouseDragged(e);
+                       update();
+               }
+       }
+       
+        Vector3d axis = null;
+       
+       @Override
+       public void keyTyped(KeyEvent e) {
+                if (e.getKeyCode() == KeyEvent.VK_LEFT) {
+               inputType = InputType.KEY;
+               axis = new Vector3d(0.0,1.0,0.0);
+            } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
+                       inputType = InputType.KEY;
+                       axis = new Vector3d(0.0,-1.0,0.0);
+            } else if (e.getKeyCode() ==KeyEvent.VK_UP) {
+                       inputType = InputType.KEY;
+                       axis = new Vector3d(1.0,0.0,0.0);
+            } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
+                       inputType = InputType.KEY;
+                       axis = new Vector3d(-1.0,0.0,0.0);
+            } 
+       }
+       
+    public void doChanges(boolean pressed, int x, int y) {
+       Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(),x, y);
+       Vector3d p = node.getWorldPosition();
+        
+       if (pressed) {
+            Vector3d axis = getRotationAxis();
+            if (axis != null) {
+               if (!worldCoord) {
+                       MathTools.rotate(parentWorldOrientation, axis, axis);
+               }
+
+               
+                double s[] = new double[2];
+                Vector3d i2 = new Vector3d();
+               
+                boolean intersect = MathTools.intersectStraightPlane(ray.pos, ray.dir, p, axis, i2, s);
+                double dot = Math.abs(ray.dir.dot(axis));
+                if (intersect &&  dot > 0.4)
+                       inputType = InputType.INTERSECT;
+                else
+                       inputType = InputType.NONINTERSECT;
+                       
+                
+                if (inputType == InputType.INTERSECT) {
+                    // picking ray and plane defined by gizmo's center point and
+                    // rotation axis can intersect
+                    // vector from center point to intersection point
+                    i2.sub(p);
+                    // creating vectors i and j that are lying on the plane and
+                    // are perpendicular
+                    // vectors are used to calculate polar coordinate for
+                    // intersection point
+                    j.set(i2);
+                    i.cross(j, axis);
+                    System.out.println("I,J " + i + " " + j);
+                    double angleI = i2.angle(i);
+                    double angleJ = i2.angle(j);
+                    prevAngle = Math.atan2(Math.cos(angleJ), Math.cos(angleI));
+                } else {
+                    // picking ray and plane defined by gizmo's center point and
+                    // rotation axis are parallel,
+                    // so we'll use cross product of rotation axis and picking
+                    // ray to detect amount of rotation
+                    i.cross(ray.dir, axis);
+                    MathTools.intersectStraightStraight(ray.pos, ray.dir, p, i, new Vector3d(), new Vector3d(), s);
+                    prevS = s[1];
+                }
+            }
+           
+            
+        }
+
+        if (inputType != InputType.KEY)
+               axis = getRotationAxis();
+        if (axis == null) {
+            return;   
+        }
+        Vector3d taxis = null;
+        if (!worldCoord) {
+               taxis = new Vector3d(axis);
+               MathTools.rotate(parentWorldOrientation, axis, axis);
+       }
+        System.out.println(inputType);
+        if (inputType == InputType.INTERSECT) {
+
+            double s[] = new double[2];
+            Vector3d i2 = new Vector3d();
+            MathTools.intersectStraightPlane(ray.pos, ray.dir, p, axis, i2, s);
+            i2.sub(p);
+            double angleI = i2.angle(i);
+            double angleJ = i2.angle(j);
+            double angle = Math.atan2(Math.cos(angleJ), Math.cos(angleI));
+            System.out.println("Angle " + angle + " i " + angleI + " j " + angleJ + " prev " + prevAngle);
+            if(!worldCoord)
+               axis = taxis;
+            if (useStep) {
+
+               //setOrientation(MathTools.getQuat(rotation));
+               AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);
+               Quat4d qrot = new Quat4d();
+               MathTools.getQuat(rot, qrot);
+               //prevAngle = angle;
+               qrot.mulInverse(worldOrientation);
+               
+          
+               if (stepMethod == 0) {
+                       rot.set(qrot);
+                       rot.angle = roundAngle(rot.angle);
+                       //qrot.set(rot);
+                       MathTools.getQuat(rot,qrot);
+                       setOrientation(qrot);
+               } else if (stepMethod == 1){
+                         
+                       //Vector3d euler = MathTools.getEuler(qrot);
+                       Vector3d euler = EulerTools.getEulerFromQuat(order, qrot);
+                       euler.x = roundAngle(euler.x);
+                       euler.y = roundAngle(euler.y);
+                       euler.z = roundAngle(euler.z);
+                       //Quat4d q = MathTools.getQuat(euler);
+                       Quat4d q = EulerTools.getQuatFromEuler(order, euler);
+                       setOrientation(q);
+                       System.out.println(" (" + MathTools.radToDeg(euler.x) + " " + MathTools.radToDeg(euler.y) + " " + MathTools.radToDeg(euler.z) +  ") " + qrot + " "+ q);
+               } else {
+                       setOrientation(qrot);
+               }
+               
+            } else {
+                if (worldCoord) {
+                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,angle-prevAngle));
+                       AxisAngle4d aa = MathTools.getAxisAngle(node.getWorldOrientation());
+                       AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);
+                       MathTools.multiplyOrientation(aa, rot);
+                       setWorldOrientation(MathTools.getQuat(rot));
+                } else {
+                       AxisAngle4d aa = MathTools.getAxisAngle(node.getOrientation());
+                       AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);
+                       MathTools.multiplyOrientation(aa, rot);
+                       setOrientation(MathTools.getQuat(rot));
+                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,angle-prevAngle));
+                }
+                prevAngle = angle;
+            }
+            
+        } else if (inputType == InputType.NONINTERSECT){
+
+            double s[] = new double[2];
+            MathTools.intersectStraightStraight(ray.pos, ray.dir, p, i, new Vector3d(), new Vector3d(), s);
+            if(!worldCoord)
+               axis = taxis;
+            if (useStep) {
+               //setOrientation(MathTools.getQuat(rotation));
+               AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);
+                
+               Quat4d qrot = new Quat4d();
+               //qrot.set(rot);
+               MathTools.getQuat(rot, qrot);
+               //prevAngle = angle;
+               qrot.mulInverse(worldOrientation);
+               
+          
+               if (stepMethod == 0) {
+                       rot.set(qrot);
+                       rot.angle = roundAngle(rot.angle);
+                       //qrot.set(rot);
+                       MathTools.getQuat(rot,qrot);
+                       setOrientation(qrot);
+               } else if (stepMethod == 1){
+                         
+                       //Vector3d euler = MathTools.getEuler(qrot);
+                       Vector3d euler = EulerTools.getEulerFromQuat(order, qrot);
+                       euler.x = roundAngle(euler.x);
+                       euler.y = roundAngle(euler.y);
+                       euler.z = roundAngle(euler.z);
+                       //Quat4d q = MathTools.getQuat(euler);
+                       Quat4d q = EulerTools.getQuatFromEuler(order, euler);
+                       setOrientation(q);
+                       System.out.println(" (" + MathTools.radToDeg(euler.x) + " " + MathTools.radToDeg(euler.y) + " " + MathTools.radToDeg(euler.z) +  ") " + qrot + " "+ q);
+               } else {
+                       setOrientation(qrot);
+               }
+                prevS = s[1];
+               
+//                    G3DTools.setOrientation(mo.getG3DNode(graph).getLocalOrientation(), rotations.get(mo));
+//                    G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,s[1] - prevS));
+//                    AxisAngle4d aa = G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation());
+//                    rotations.put(mo, aa);
+//                    Vector3d euler = MathTools.getEuler(aa);
+//                    euler.x = roundAngle(euler.x);
+//                    euler.y = roundAngle(euler.y);
+//                    euler.z = roundAngle(euler.z);
+//                    aa = MathTools.getFromEuler2(euler);
+//                    prevS = s[1];
+//                    G3DTools.setOrientation(mo.getG3DNode(graph).getLocalOrientation(), aa);
+//                    Vector3d e = MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()));
+//                    e.scale(180.0/Math.PI);
+//                    text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + e + " ";
+               
+               
+            } else {
+                       if (worldCoord) {
+                               AxisAngle4d aa =  MathTools.getAxisAngle(node.getWorldOrientation());
+                       AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);
+                       MathTools.multiplyOrientation(aa, rot);
+                       setWorldOrientation(MathTools.getQuat(rot));
+                               //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,s[1] - prevS));
+                       } else {
+                               AxisAngle4d aa =  MathTools.getAxisAngle(node.getOrientation());
+                       AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);
+                       MathTools.multiplyOrientation(aa, rot);
+                       setOrientation(MathTools.getQuat(rot));
+                               //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,s[1] - prevS));
+                       }
+                       //text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation())) + " ";
+                prevS = s[1];
+                
+            }
+           
+        } else {
+               if (worldCoord) {
+                       AxisAngle4d aa = MathTools.getAxisAngle(node.getWorldOrientation());
+               AxisAngle4d rot = new AxisAngle4d(axis,Math.PI * 0.5);
+               MathTools.multiplyOrientation(aa, rot);
+               setWorldOrientation(MathTools.getQuat(rot));
+                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,Math.PI * 0.5));
+               } else {
+                       AxisAngle4d aa = MathTools.getAxisAngle(node.getOrientation());
+               AxisAngle4d rot = new AxisAngle4d(axis,Math.PI * 0.5);
+               MathTools.multiplyOrientation(aa, rot);
+               setOrientation(MathTools.getQuat(rot));
+                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,Math.PI * 0.5));
+               }
+             //   text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation())) + " ";
+            
+        }
+        //setInfoText(text);
+    }
+    
+    protected void setOrientation(Quat4d q) {
+       node.setOrientation(q);
+    }
+    
+    protected void setWorldOrientation(Quat4d q) {
+       node.setWorldOrientation(q);
+    }
+       
+       @Override
+       public void mouseMoved(MouseEvent e) {
+               getDefaultAction().mouseMoved(e);
+       }
+       
+       private Vector3d getRotationAxis() {
+               switch (index) {
+               case X:
+                       return new Vector3d(1.0, 0.0, 0.0);
+               case Y:
+                       return new Vector3d(0.0, 1.0, 0.0);
+               case Z:
+                       return new Vector3d(0.0, 0.0, 1.0);
+               case P:
+                       Vector3d axis = new Vector3d(panel.GetRenderer().GetActiveCamera()
+                                       .GetDirectionOfProjection());
+                       axis.normalize();
+                       return axis;
+               default:
+                       return null;
+               }
+       }
+       
+        private double prevS = 0.0;
+           
+    private Vector3d i = new Vector3d();
+    private Vector3d j = new Vector3d();
+    private double prevAngle = 0;
+
+    enum InputType{INTERSECT,NONINTERSECT,KEY,NONE};
+    InputType inputType;
+    private boolean useStep = false;
+    
+    
+    
+    private double roundAngle(double angle) {
+        while (angle < - Math.PI)
+            angle += Math.PI*2.0;
+        while (angle > Math.PI)
+            angle -= Math.PI*2.0;
+        
+        
+        int index = 0;
+        while (angle > angles[index])
+            index++;
+        if (index == 0) {
+            angle = angles[0];
+        } else {
+            double d = angle - angles[index - 1];
+            double d2 = angles[index] - angle;
+            if (d < d2)
+                angle = angles[index - 1];
+            else
+                angle = angles[index];
+        }
+        return angle;
+    }
+       
+}
similarity index 96%
rename from org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/TranslateAction.java
rename to org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/TranslateAction.java
index 7000edaea2efd091b21bc6530ff16838c12e6b34..d7d81331b7c757151f52b8532c3b4bd5aaf771f4 100644 (file)
@@ -9,7 +9,7 @@
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
  *******************************************************************************/
-package org.simantics.g3d.vtk.action;
+package org.simantics.g3d.vtk.awt;
 
 import java.awt.Cursor;
 import java.awt.event.KeyEvent;
@@ -26,7 +26,6 @@ import org.simantics.g3d.math.Ray;
 import org.simantics.g3d.scenegraph.IG3DNode;
 import org.simantics.g3d.scenegraph.structural.IStructuralNode;
 import org.simantics.g3d.vtk.Activator;
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
 import org.simantics.g3d.vtk.common.VTKNodeMap;
 import org.simantics.g3d.vtk.gizmo.TranslateAxisGizmo;
 import org.simantics.g3d.vtk.utils.vtkUtil;
@@ -35,7 +34,7 @@ import org.simantics.utils.threads.ThreadUtils;
 
 import vtk.vtkProp;
 
-public class TranslateAction extends vtkAction{
+public class TranslateAction extends vtkAwtAction{
        
        public static final int X = 0;
     public static final int Y = 1;
@@ -102,7 +101,7 @@ public class TranslateAction extends vtkAction{
        
        private void attachUI() {
                panel.setCursor(activeCursor);
-               gizmo.attach(panel.GetRenderer());
+               gizmo.attach(panel);
        }
        
        private void deattachUI() {
@@ -279,11 +278,11 @@ public class TranslateAction extends vtkAction{
                                panel.setCursor(dragCursor);
                        } else {
                                valid = false;
-                               panel.getDefaultAction().mousePressed(e);
+                               getDefaultAction().mousePressed(e);
                                panel.setCursor(activeCursor);
                        }
                } else {
-                       panel.getDefaultAction().mousePressed(e);
+                       getDefaultAction().mousePressed(e);
                }
                //index = gizmo.getTranslateAxis(actor);
                //if (index == -1) {
@@ -305,7 +304,7 @@ public class TranslateAction extends vtkAction{
                        prevTranslate = null;
                        panel.setCursor(activeCursor);
                } else {
-                       panel.getDefaultAction().mouseReleased(e);
+                       getDefaultAction().mouseReleased(e);
                }
        }
        
@@ -334,7 +333,7 @@ public class TranslateAction extends vtkAction{
                        //nodeMap.modified(node);
                        update();
                } else {
-                       panel.getDefaultAction().mouseDragged(e);
+                       getDefaultAction().mouseDragged(e);
                        update();
                }
        }
@@ -379,7 +378,7 @@ public class TranslateAction extends vtkAction{
        
        @Override
        public void mouseMoved(MouseEvent e) {
-               panel.getDefaultAction().mouseMoved(e);
+               getDefaultAction().mouseMoved(e);
        }
        
        protected Vector3d getTranslate(double x, double y) {
diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkAwtAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkAwtAction.java
new file mode 100644 (file)
index 0000000..2a2ea3e
--- /dev/null
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.awt;
+
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+
+import org.simantics.g3d.vtk.action.vtkAction;
+
+public abstract class vtkAwtAction extends vtkAction implements KeyListener, MouseListener, MouseMotionListener {
+
+       protected InteractiveVtkPanel panel;
+       
+       public vtkAwtAction(InteractiveVtkPanel panel) {
+               this.panel = panel;
+       }
+       
+       @Override
+       public void run() {
+               panel.setActiveAction(this);
+       }
+       
+       
+       public void attach() {
+
+               panel.addKeyListener(this);
+               panel.addMouseListener(this);
+               panel.addMouseMotionListener(this);
+
+       }
+       
+       public void deattach() {
+               panel.removeKeyListener(this);
+               panel.removeMouseListener(this);
+               panel.removeMouseMotionListener(this);
+       }
+       
+       protected vtkAwtAction getDefaultAction() {
+               return (vtkAwtAction)panel.getDefaultAction();
+       }
+       
+       @Override
+       public void keyPressed(KeyEvent e) {
+               
+       }
+       
+       @Override
+       public void keyReleased(KeyEvent e) {
+               
+       }
+       
+       @Override
+       public void keyTyped(KeyEvent e) {
+               
+       }
+       
+       public void mouseClicked(java.awt.event.MouseEvent e) {
+               
+       };
+       
+       @Override
+       public void mouseDragged(MouseEvent e) {
+               
+       }
+       
+       @Override
+       public void mouseEntered(MouseEvent e) {
+               
+       }
+       
+       @Override
+       public void mouseExited(MouseEvent e) {
+               
+       }
+       
+       @Override
+       public void mouseMoved(MouseEvent e) {
+               
+       }
+       
+       @Override
+       public void mousePressed(MouseEvent e) {
+               
+       }
+       
+       @Override
+       public void mouseReleased(MouseEvent e) {
+       
+       }
+}
similarity index 98%
rename from org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/vtkCameraAndSelectorAction.java
rename to org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkCameraAndSelectorAction.java
index b4a387bc5390a7a27014626f7c0671f3b4c80254..f1e6f32443bf7d1079c1f00b4b5004a0dc415533 100644 (file)
@@ -9,7 +9,7 @@
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
  *******************************************************************************/
-package org.simantics.g3d.vtk.action;
+package org.simantics.g3d.vtk.awt;
 
 import java.awt.event.InputEvent;
 import java.awt.event.MouseEvent;
@@ -24,14 +24,13 @@ import org.eclipse.jface.viewers.SelectionChangedEvent;
 import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.swt.widgets.Display;
 import org.simantics.g3d.tools.AdaptationUtils;
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
 
 import vtk.vtkCamera;
 import vtk.vtkProp;
 import vtk.vtkRenderWindow;
 import vtk.vtkRenderer;
 
-public class vtkCameraAndSelectorAction extends vtkAction implements ISelectionProvider {
+public class vtkCameraAndSelectorAction extends vtkAwtAction implements ISelectionProvider {
        
        protected vtkRenderer ren;
        protected int lastX;
index 35d3105fb451f1debc7afca7476e5d1449099007..646fbe41cdef8300e24e71ea84eba13510995e35 100644 (file)
@@ -21,15 +21,12 @@ import java.util.Set;
 import java.util.Stack;
 
 import org.simantics.db.ReadGraph;
-import org.simantics.db.Resource;
 import org.simantics.db.Session;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.g3d.ontology.G3D;
-import org.simantics.g3d.scenegraph.G3DNode;
-import org.simantics.g3d.scenegraph.IG3DNode;
 import org.simantics.g3d.scenegraph.RenderListener;
 import org.simantics.g3d.scenegraph.base.INode;
 import org.simantics.g3d.scenegraph.base.NodeListener;
@@ -50,19 +47,19 @@ public abstract class AbstractVTKNodeMap<E extends INode> implements VTKNodeMap<
        
        protected Session session;
        protected IMapping<Object,E> mapping;
-       protected InteractiveVtkPanel panel;
+       protected VtkView view;
        
        protected MapList<E, vtkProp> nodeToActor = new MapList<E, vtkProp>();
        protected Map<vtkProp,E> actorToNode = new HashMap<vtkProp, E>();
 
        protected ParentNode<E> rootNode;
        
-       public AbstractVTKNodeMap(Session session, IMapping<Object,E> mapping, InteractiveVtkPanel panel, ParentNode<E> rootNode) {
+       public AbstractVTKNodeMap(Session session, IMapping<Object,E> mapping, VtkView view, ParentNode<E> rootNode) {
                this.session = session;
                this.mapping = mapping;
-               this.panel = panel;
+               this.view = view;
                this.rootNode = rootNode;
-               panel.addListener(this);
+               view.addListener(this);
                mapping.addMappingListener(this);
                rootNode.addListener(this);
        }
@@ -73,7 +70,7 @@ public abstract class AbstractVTKNodeMap<E extends INode> implements VTKNodeMap<
        protected abstract void updateActor(E node,Set<String> ids);
        
        public void repaint() {
-               panel.repaint();
+               view.refresh();
        }
        
        public void populate() {
@@ -128,14 +125,16 @@ public abstract class AbstractVTKNodeMap<E extends INode> implements VTKNodeMap<
        @Override
        public void updateRenderObjectsFor(INode node) {
                List<vtkProp> toDelete = new ArrayList<vtkProp>();
+               view.lock();
                for (vtkProp prop : nodeToActor.getValues((E)node)) {
                        if (prop.GetVTKId() != 0) {
-                               panel.GetRenderer().RemoveActor(prop);
+                               view.getRenderer().RemoveActor(prop);
                                //prop.Delete();
                                toDelete.add(prop);
                        }
                        actorToNode.remove(prop);
                }
+               view.unlock();
                nodeToActor.remove((E)node);
                Collection<vtkProp> coll = getActors((E)node);
                if (coll == null)
@@ -165,7 +164,7 @@ public abstract class AbstractVTKNodeMap<E extends INode> implements VTKNodeMap<
                        added.add(new Pair<E, String>(node, id));
                        rangeModified = true;
                }
-               panel.repaint();
+               view.refresh();
        }
        
        @SuppressWarnings("unchecked")
@@ -181,7 +180,7 @@ public abstract class AbstractVTKNodeMap<E extends INode> implements VTKNodeMap<
                        removed.add(new Pair<E, String>(node, id));
                        rangeModified = true;
                }
-               panel.repaint();
+               view.refresh();
        }
        
        @SuppressWarnings("unchecked")
@@ -198,7 +197,7 @@ public abstract class AbstractVTKNodeMap<E extends INode> implements VTKNodeMap<
                        updated.add(node, id);
                        rangeModified = true;
                }
-               panel.repaint();
+               view.refresh();
        }
        
        private boolean graphUpdates = false;
@@ -461,7 +460,7 @@ public abstract class AbstractVTKNodeMap<E extends INode> implements VTKNodeMap<
        @Override
        public void delete() {
                changeTracking = false;
-               panel.removeListener(this);
+               view.removeListener(this);
                mapping.removeMappingListener(this);
 
                List<E> nodes = new ArrayList<E>(nodeToActor.getKeySize());
index f80af054dd466c8921d3e9c38cd8dda54879ac73..7acb3f547adc3ced76f6e0e1932e69fcefbae73b 100644 (file)
@@ -1,55 +1,53 @@
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.vtk.common;\r
-\r
-import org.eclipse.jface.viewers.ISelection;\r
-import org.simantics.g3d.scenegraph.IG3DNode;\r
-import org.simantics.g3d.scenegraph.NodeHighlighter;\r
-import org.simantics.g3d.scenegraph.NodeHighlighter.HighlightEventType;\r
-\r
-import vtk.vtkPanel;\r
-\r
-public class HoverHighlighter extends SelectionHighlighter {\r
-\r
-\r
-       public HoverHighlighter(vtkPanel panel, VTKNodeMap nodeMap) {\r
-               super(panel, nodeMap);\r
-               \r
-       }\r
-       \r
-       protected void highlight(ISelection s) {\r
-               highlight(s, HighlightEventType.Hover, HighlightEventType.ClearHover);\r
-       }\r
-       \r
-       protected void hilight(IG3DNode node, HighlightEventType type) {\r
-               if (node instanceof NodeHighlighter) {\r
-                       ((NodeHighlighter)node).highlight(type);\r
-                       return;\r
-               }\r
-               if (type == HighlightEventType.Hover) {\r
-                       setSelectedColor(node);\r
-               } else if (type == HighlightEventType.ClearHover) {\r
-                       setDefaultColor(node);\r
-               }\r
-       }\r
-\r
-       protected void setDefaultColor(IG3DNode node) {\r
-               double color[] = new double[]{0,0,0};\r
-               setColor(node, true, color);\r
-       }\r
-       \r
-       protected void setSelectedColor(IG3DNode node) {\r
-               double color[] = new double[]{1,0,1};\r
-               setColor(node, true, color);\r
-       }\r
-       \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.common;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.simantics.g3d.scenegraph.IG3DNode;
+import org.simantics.g3d.scenegraph.NodeHighlighter;
+import org.simantics.g3d.scenegraph.NodeHighlighter.HighlightEventType;
+
+public class HoverHighlighter extends SelectionHighlighter {
+
+
+       public HoverHighlighter(VtkView panel, VTKNodeMap nodeMap) {
+               super(panel, nodeMap);
+               
+       }
+       
+       protected void highlight(ISelection s) {
+               highlight(s, HighlightEventType.Hover, HighlightEventType.ClearHover);
+       }
+       
+       protected void hilight(IG3DNode node, HighlightEventType type) {
+               if (node instanceof NodeHighlighter) {
+                       ((NodeHighlighter)node).highlight(type);
+                       return;
+               }
+               if (type == HighlightEventType.Hover) {
+                       setSelectedColor(node);
+               } else if (type == HighlightEventType.ClearHover) {
+                       setDefaultColor(node);
+               }
+       }
+
+       protected void setDefaultColor(IG3DNode node) {
+               double color[] = new double[]{0,0,0};
+               setColor(node, true, color);
+       }
+       
+       protected void setSelectedColor(IG3DNode node) {
+               double color[] = new double[]{1,0,1};
+               setColor(node, true, color);
+       }
+       
+}
index 95ba7aee2ef852e827a1070aa3c9dda48c15405f..dec7421152fd683ed4da8fccfc1f8b2b1b45d0f0 100644 (file)
@@ -32,7 +32,6 @@ import vtk.vtkAlgorithm;
 import vtk.vtkAlgorithmOutput;
 import vtk.vtkFeatureEdges;
 import vtk.vtkMapper;
-import vtk.vtkPanel;
 import vtk.vtkProp;
 import vtk.vtkProperty;
 
@@ -40,7 +39,7 @@ public class SelectionHighlighter<E extends IG3DNode> implements ISelectionChang
 
        
        
-       vtkPanel panel;
+       VtkView panel;
        VTKNodeMap<E> nodeMap;
        
        List<IG3DNode> selectedNodes = new ArrayList<IG3DNode>();
@@ -48,7 +47,7 @@ public class SelectionHighlighter<E extends IG3DNode> implements ISelectionChang
        
        HighlightObjectType type = HighlightObjectType.Node;
        
-       public SelectionHighlighter(vtkPanel panel, VTKNodeMap<E> nodeMap) {
+       public SelectionHighlighter(VtkView panel, VTKNodeMap<E> nodeMap) {
                this.panel = panel;
                this.nodeMap = nodeMap;
        }
@@ -57,7 +56,7 @@ public class SelectionHighlighter<E extends IG3DNode> implements ISelectionChang
        public void selectionChanged(SelectionChangedEvent event) {
                final ISelection s = event.getSelection();
                
-               if (Thread.currentThread().equals(AWTThread.getThreadAccess().getThread()))
+               if (Thread.currentThread().equals(panel.getThreadQueue().getThread()))
                        highlight(s);
                else {
                        ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
@@ -65,8 +64,8 @@ public class SelectionHighlighter<E extends IG3DNode> implements ISelectionChang
                                public void run() {
                                        highlight(s);
                                        //System.out.println(this.getClass().getName() + " highlight ");
-                                       panel.Render();
-                                       //panel.repaint();
+                                       //panel.Render();
+                                       panel.refresh();
                                }
                        });
                }
@@ -144,7 +143,7 @@ public class SelectionHighlighter<E extends IG3DNode> implements ISelectionChang
                        selectedActors.addAll(currentSelectedActors);
                }
                if (changed) {
-                       panel.repaint();
+                       panel.refresh();
                }
        }
        
diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/VtkView.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/VtkView.java
new file mode 100644 (file)
index 0000000..5bbd9c9
--- /dev/null
@@ -0,0 +1,32 @@
+package org.simantics.g3d.vtk.common;
+
+import org.simantics.g3d.scenegraph.RenderListener;
+import org.simantics.g3d.vtk.action.vtkAction;
+import org.simantics.utils.threads.IThreadWorkQueue;
+
+import vtk.vtkObjectBase;
+import vtk.vtkRenderWindowInteractor;
+import vtk.vtkRenderer;
+
+public interface VtkView {
+       
+       public void addListener(RenderListener l);
+       public void removeListener(RenderListener l);
+       public void refresh();
+       public vtkRenderer getRenderer();
+       public vtkRenderWindowInteractor getRenderWindowInteractor();
+       
+       public void setActiveAction(vtkAction action);
+       public void setDefaultAction(vtkAction defaultAction);
+       public void useDefaultAction();
+       public vtkAction getDefaultAction();
+       
+       public IThreadWorkQueue getThreadQueue();
+       
+       public void lock();
+       public void unlock();
+       
+       public void addDeletable(vtkObjectBase o);
+       public void removeDeletable (vtkObjectBase o);
+
+}
index c547f513960395aeca7809dc7e579fe843f839bb..94ea902c4f441bbb7819220d72c8e1867ba53364 100644 (file)
@@ -1,80 +1,80 @@
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.vtk.gizmo;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.List;\r
-\r
-import javax.vecmath.Point3d;\r
-\r
-import org.simantics.g3d.vtk.action.RotateAction;\r
-import org.simantics.g3d.vtk.shape.vtkShape;\r
-\r
-import vtk.vtkActor;\r
-import vtk.vtkProp;\r
-\r
-public class RotateAxisGizmo extends vtkGizmo{\r
-       \r
-       private List<vtkProp> parts = new ArrayList<vtkProp>();\r
-       int type = -1;\r
-\r
-       \r
-       @Override\r
-       public Collection<vtkProp> getGizmo() {\r
-               for (vtkProp p : parts)\r
-                       p.Delete();\r
-               parts.clear();\r
-               double l = 100;\r
-               double w = 3;\r
-               switch (type) {\r
-               case RotateAction.X:{\r
-                       vtkActor lineActorX = vtkShape.createLineActor(new Point3d(-l,0,0), new Point3d(l,0,0));\r
-                       lineActorX.GetProperty().SetColor(1, 0, 0);\r
-                       lineActorX.GetProperty().SetLineWidth(w);\r
-                       lineActorX.GetProperty().Delete();\r
-                       parts.add(lineActorX);\r
-                       break;\r
-               }\r
-               case RotateAction.Y: {\r
-                       vtkActor lineActorY = vtkShape.createLineActor(new Point3d(0,-l,0), new Point3d(0,l,0));\r
-                       lineActorY.GetProperty().SetColor(0, 1, 0);\r
-                       lineActorY.GetProperty().SetLineWidth(w);\r
-                       lineActorY.GetProperty().Delete();\r
-                       parts.add(lineActorY);\r
-                       break;\r
-               }\r
-               case RotateAction.Z: {\r
-                       vtkActor lineActorZ = vtkShape.createLineActor(new Point3d(0,0,-l), new Point3d(0,0,l));\r
-                       lineActorZ.GetProperty().SetColor(0, 0, 1);\r
-                       lineActorZ.GetProperty().SetLineWidth(w);\r
-                       lineActorZ.GetProperty().Delete();\r
-                       parts.add(lineActorZ);\r
-                       break;\r
-               }\r
-               default: {\r
-                       \r
-               }\r
-               }\r
-               return parts;\r
-       }\r
-       \r
-       public void setType(int type) {\r
-               if (this.type == type)\r
-                       return;\r
-               this.type = type;\r
-               deattachActors();\r
-               attachActors();\r
-       }\r
-       \r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.gizmo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.vecmath.Point3d;
+
+import org.simantics.g3d.vtk.awt.RotateAction;
+import org.simantics.g3d.vtk.shape.vtkShape;
+
+import vtk.vtkActor;
+import vtk.vtkProp;
+
+public class RotateAxisGizmo extends vtkGizmo{
+       
+       private List<vtkProp> parts = new ArrayList<vtkProp>();
+       int type = -1;
+
+       
+       @Override
+       public Collection<vtkProp> getGizmo() {
+               for (vtkProp p : parts)
+                       p.Delete();
+               parts.clear();
+               double l = 100;
+               double w = 3;
+               switch (type) {
+               case RotateAction.X:{
+                       vtkActor lineActorX = vtkShape.createLineActor(new Point3d(-l,0,0), new Point3d(l,0,0));
+                       lineActorX.GetProperty().SetColor(1, 0, 0);
+                       lineActorX.GetProperty().SetLineWidth(w);
+                       lineActorX.GetProperty().Delete();
+                       parts.add(lineActorX);
+                       break;
+               }
+               case RotateAction.Y: {
+                       vtkActor lineActorY = vtkShape.createLineActor(new Point3d(0,-l,0), new Point3d(0,l,0));
+                       lineActorY.GetProperty().SetColor(0, 1, 0);
+                       lineActorY.GetProperty().SetLineWidth(w);
+                       lineActorY.GetProperty().Delete();
+                       parts.add(lineActorY);
+                       break;
+               }
+               case RotateAction.Z: {
+                       vtkActor lineActorZ = vtkShape.createLineActor(new Point3d(0,0,-l), new Point3d(0,0,l));
+                       lineActorZ.GetProperty().SetColor(0, 0, 1);
+                       lineActorZ.GetProperty().SetLineWidth(w);
+                       lineActorZ.GetProperty().Delete();
+                       parts.add(lineActorZ);
+                       break;
+               }
+               default: {
+                       
+               }
+               }
+               return parts;
+       }
+       
+       public void setType(int type) {
+               if (this.type == type)
+                       return;
+               this.type = type;
+               deattachActors();
+               attachActors();
+       }
+       
+
+}
index 0bd70cf279e3000913f98c1e50b7ea071dc459b3..64b32d3ed9ced8c4291f73abff093927d43b83fb 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.vtk.gizmo;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.List;\r
-\r
-import javax.vecmath.Point3d;\r
-\r
-import org.simantics.g3d.vtk.action.TranslateAction;\r
-import org.simantics.g3d.vtk.shape.vtkShape;\r
-\r
-import vtk.vtkActor;\r
-import vtk.vtkProp;\r
-\r
-public class TranslateAxisGizmo extends vtkGizmo{\r
-       \r
-       private List<vtkProp> parts = new ArrayList<vtkProp>();\r
-       int type = -1;\r
-\r
-       \r
-       @Override\r
-       public Collection<vtkProp> getGizmo() {\r
-               for (vtkProp p : parts)\r
-                       p.Delete();\r
-               parts.clear();\r
-               double l = 100;\r
-               double w = 3;\r
-               switch (type) {\r
-               case TranslateAction.X:{\r
-                       vtkActor lineActorX = vtkShape.createLineActor(new Point3d(-l,0,0), new Point3d(l,0,0));\r
-                       lineActorX.GetProperty().SetColor(1, 0, 0);\r
-                       lineActorX.GetProperty().SetLineWidth(w);\r
-                       lineActorX.GetProperty().Delete();\r
-                       parts.add(lineActorX);\r
-                       break;\r
-               }\r
-               case TranslateAction.Y: {\r
-                       vtkActor lineActorY = vtkShape.createLineActor(new Point3d(0,-l,0), new Point3d(0,l,0));\r
-                       lineActorY.GetProperty().SetColor(0, 1, 0);\r
-                       lineActorY.GetProperty().SetLineWidth(w);\r
-                       lineActorY.GetProperty().Delete();\r
-                       parts.add(lineActorY);\r
-                       break;\r
-               }\r
-               case TranslateAction.Z: {\r
-                       vtkActor lineActorZ = vtkShape.createLineActor(new Point3d(0,0,-l), new Point3d(0,0,l));\r
-                       lineActorZ.GetProperty().SetColor(0, 0, 1);\r
-                       lineActorZ.GetProperty().SetLineWidth(w);\r
-                       lineActorZ.GetProperty().Delete();\r
-                       parts.add(lineActorZ);\r
-                       break;\r
-               }\r
-               case TranslateAction.XY: {\r
-                       vtkActor lineActorX = vtkShape.createLineActor(new Point3d(-l,0,0), new Point3d(l,0,0));\r
-                       lineActorX.GetProperty().SetColor(1, 0, 0);\r
-                       lineActorX.GetProperty().SetLineWidth(w);\r
-                       lineActorX.GetProperty().Delete();\r
-                       parts.add(lineActorX);\r
-                       vtkActor lineActorY = vtkShape.createLineActor(new Point3d(0,-l,0), new Point3d(0,l,0));\r
-                       lineActorY.GetProperty().SetColor(0, 1, 0);\r
-                       lineActorY.GetProperty().SetLineWidth(w);\r
-                       lineActorY.GetProperty().Delete();\r
-                       parts.add(lineActorY);\r
-                       break;\r
-               }\r
-               case TranslateAction.XZ: {\r
-                       vtkActor lineActorX = vtkShape.createLineActor(new Point3d(-l,0,0), new Point3d(l,0,0));\r
-                       lineActorX.GetProperty().SetColor(1, 0, 0);\r
-                       lineActorX.GetProperty().Delete();\r
-                       parts.add(lineActorX);\r
-                       vtkActor lineActorZ = vtkShape.createLineActor(new Point3d(0,0,-l), new Point3d(0,0,l));\r
-                       lineActorZ.GetProperty().SetColor(0, 0, 1);\r
-                       lineActorZ.GetProperty().Delete();\r
-                       parts.add(lineActorZ);\r
-                       break;\r
-               }\r
-               case TranslateAction.YZ: {\r
-                       vtkActor lineActorY = vtkShape.createLineActor(new Point3d(0,-l,0), new Point3d(0,l,0));\r
-                       lineActorY.GetProperty().SetColor(0, 1, 0);\r
-                       lineActorY.GetProperty().SetLineWidth(w);\r
-                       lineActorY.GetProperty().Delete();\r
-                       parts.add(lineActorY);\r
-                       vtkActor lineActorZ = vtkShape.createLineActor(new Point3d(0,0,-l), new Point3d(0,0,l));\r
-                       lineActorZ.GetProperty().SetColor(0, 0, 1);\r
-                       lineActorZ.GetProperty().SetLineWidth(w);\r
-                       lineActorZ.GetProperty().Delete();\r
-                       parts.add(lineActorZ);\r
-                       break;\r
-               }\r
-               default: {\r
-                       \r
-               }\r
-               }\r
-               return parts;\r
-       }\r
-       \r
-       public void setType(int type) {\r
-               if (this.type == type)\r
-                       return;\r
-               this.type = type;\r
-               if (getRenderer() != null) {\r
-                       deattachActors();\r
-                       attachActors();\r
-               }\r
-       }\r
-       \r
-       \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.gizmo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.vecmath.Point3d;
+
+import org.simantics.g3d.vtk.awt.TranslateAction;
+import org.simantics.g3d.vtk.shape.vtkShape;
+
+import vtk.vtkActor;
+import vtk.vtkProp;
+
+public class TranslateAxisGizmo extends vtkGizmo{
+       
+       private List<vtkProp> parts = new ArrayList<vtkProp>();
+       int type = -1;
+
+       
+       @Override
+       public Collection<vtkProp> getGizmo() {
+               for (vtkProp p : parts)
+                       p.Delete();
+               parts.clear();
+               double l = 100;
+               double w = 3;
+               switch (type) {
+               case TranslateAction.X:{
+                       vtkActor lineActorX = vtkShape.createLineActor(new Point3d(-l,0,0), new Point3d(l,0,0));
+                       lineActorX.GetProperty().SetColor(1, 0, 0);
+                       lineActorX.GetProperty().SetLineWidth(w);
+                       lineActorX.GetProperty().Delete();
+                       parts.add(lineActorX);
+                       break;
+               }
+               case TranslateAction.Y: {
+                       vtkActor lineActorY = vtkShape.createLineActor(new Point3d(0,-l,0), new Point3d(0,l,0));
+                       lineActorY.GetProperty().SetColor(0, 1, 0);
+                       lineActorY.GetProperty().SetLineWidth(w);
+                       lineActorY.GetProperty().Delete();
+                       parts.add(lineActorY);
+                       break;
+               }
+               case TranslateAction.Z: {
+                       vtkActor lineActorZ = vtkShape.createLineActor(new Point3d(0,0,-l), new Point3d(0,0,l));
+                       lineActorZ.GetProperty().SetColor(0, 0, 1);
+                       lineActorZ.GetProperty().SetLineWidth(w);
+                       lineActorZ.GetProperty().Delete();
+                       parts.add(lineActorZ);
+                       break;
+               }
+               case TranslateAction.XY: {
+                       vtkActor lineActorX = vtkShape.createLineActor(new Point3d(-l,0,0), new Point3d(l,0,0));
+                       lineActorX.GetProperty().SetColor(1, 0, 0);
+                       lineActorX.GetProperty().SetLineWidth(w);
+                       lineActorX.GetProperty().Delete();
+                       parts.add(lineActorX);
+                       vtkActor lineActorY = vtkShape.createLineActor(new Point3d(0,-l,0), new Point3d(0,l,0));
+                       lineActorY.GetProperty().SetColor(0, 1, 0);
+                       lineActorY.GetProperty().SetLineWidth(w);
+                       lineActorY.GetProperty().Delete();
+                       parts.add(lineActorY);
+                       break;
+               }
+               case TranslateAction.XZ: {
+                       vtkActor lineActorX = vtkShape.createLineActor(new Point3d(-l,0,0), new Point3d(l,0,0));
+                       lineActorX.GetProperty().SetColor(1, 0, 0);
+                       lineActorX.GetProperty().Delete();
+                       parts.add(lineActorX);
+                       vtkActor lineActorZ = vtkShape.createLineActor(new Point3d(0,0,-l), new Point3d(0,0,l));
+                       lineActorZ.GetProperty().SetColor(0, 0, 1);
+                       lineActorZ.GetProperty().Delete();
+                       parts.add(lineActorZ);
+                       break;
+               }
+               case TranslateAction.YZ: {
+                       vtkActor lineActorY = vtkShape.createLineActor(new Point3d(0,-l,0), new Point3d(0,l,0));
+                       lineActorY.GetProperty().SetColor(0, 1, 0);
+                       lineActorY.GetProperty().SetLineWidth(w);
+                       lineActorY.GetProperty().Delete();
+                       parts.add(lineActorY);
+                       vtkActor lineActorZ = vtkShape.createLineActor(new Point3d(0,0,-l), new Point3d(0,0,l));
+                       lineActorZ.GetProperty().SetColor(0, 0, 1);
+                       lineActorZ.GetProperty().SetLineWidth(w);
+                       lineActorZ.GetProperty().Delete();
+                       parts.add(lineActorZ);
+                       break;
+               }
+               default: {
+                       
+               }
+               }
+               return parts;
+       }
+       
+       public void setType(int type) {
+               if (this.type == type)
+                       return;
+               this.type = type;
+               if (getView() != null) {
+                       deattachActors();
+                       attachActors();
+               }
+       }
+       
+       
+}
index 0fc6dbb26b5fec9b94d398820ae0566bfa7b5834..dacbc00808e029b2a4b4b9328bf03abf6ee8caec 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.vtk.gizmo;\r
-\r
-import java.util.Collection;\r
-\r
-import javax.vecmath.AxisAngle4d;\r
-import javax.vecmath.Tuple3d;\r
-import javax.vecmath.Vector3d;\r
-\r
-import org.simantics.g3d.gizmo.Gizmo;\r
-import org.simantics.g3d.math.MathTools;\r
-\r
-import vtk.vtkProp;\r
-import vtk.vtkProp3D;\r
-import vtk.vtkRenderer;\r
-\r
-public abstract class vtkGizmo implements Gizmo<vtkProp> {\r
-\r
-       private vtkRenderer ren1;\r
-       private Collection<vtkProp> gizmo;\r
-       \r
-       private Tuple3d position;\r
-       private AxisAngle4d orientation;\r
-       private Tuple3d scale;\r
-       \r
-       @Override\r
-       public void attach(Object renderingPart) {\r
-               if (ren1 != null)\r
-                       throw new RuntimeException("Gizmo is attached");\r
-               ren1 = (vtkRenderer)renderingPart;\r
-               attachActors();\r
-       }\r
-       \r
-       @Override\r
-       public void deattach() {\r
-               if (ren1 == null)\r
-                       throw new RuntimeException("Gizmo is not attached");\r
-               deattachActors();\r
-               ren1 = null;\r
-       }\r
-       \r
-       public boolean isAttached() {\r
-               return (ren1 != null);\r
-       }\r
-       \r
-       protected void attachActors() {\r
-               gizmo = getGizmo();\r
-               for (vtkProp p : gizmo) {\r
-                       ren1.AddActor(p);\r
-               }\r
-               if (position != null)\r
-                       setPosition(position);\r
-               if (orientation != null)\r
-                       setRotation(orientation);\r
-               if (scale != null)\r
-                       setScale(scale);\r
-       }\r
-       \r
-       protected void deattachActors() {\r
-               for (vtkProp p : gizmo) {\r
-                       ren1.RemoveActor(p);\r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public boolean isPartOf(vtkProp pickedObject) {\r
-               for (vtkProp prop : gizmo) {\r
-                       if (prop.equals(pickedObject))\r
-                               return true;\r
-               }\r
-               return false;\r
-       }\r
-       \r
-        public void setPosition(Tuple3d position) {\r
-                this.position = position;\r
-                for (vtkProp p : gizmo) {\r
-                        ((vtkProp3D)p).SetPosition(position.x, position.y, position.z);\r
-                }\r
-        }\r
-        \r
-        public void setRotation(AxisAngle4d q) {\r
-                this.orientation = q;\r
-                for (vtkProp p : gizmo) {\r
-                        ((vtkProp3D)p).SetOrientation(0,0,0);\r
-                        ((vtkProp3D)p).RotateWXYZ(MathTools.radToDeg(q.angle), q.x, q.y, q.z);\r
-                }\r
-        }\r
-       \r
-        \r
-        public void setScale(Tuple3d s) {\r
-                this.scale = s;\r
-                for (vtkProp p : gizmo) {\r
-                        ((vtkProp3D)p).SetScale(s.x, s.y, s.z);\r
-                }\r
-        }\r
-        \r
-        public void setScale(double s) {\r
-                this.scale = new Vector3d(s,s,s);\r
-                for (vtkProp p : gizmo) {\r
-                        ((vtkProp3D)p).SetScale(s, s, s);\r
-                }\r
-        }\r
-       \r
-       public abstract Collection<vtkProp> getGizmo();\r
-       \r
-//     public double[] add(double[] color1, double[] color2) {\r
-//             double[] result = new double[]{color1[0]+color2[0],color1[1],+color2[1],color1[2]+color2[2]};\r
-//             return result;\r
-//     }\r
-//     \r
-//     public double[] add(double[] color1, double[] color2, double[] color3) {\r
-//             double[] result = new double[]{color1[0]+color2[0]+color3[0],color1[1],+color2[1]+color3[1],color1[2]+color2[2]+color3[2]};\r
-//             return result;\r
-//     }\r
-       \r
-       public double[] add(double[]... color) {\r
-               double result[] = new double[]{0,0,0};\r
-               for (double c[] : color) {\r
-                       for (int i = 0; i < 3; i++)\r
-                               result[i] += c[i];\r
-               }\r
-               \r
-               return result;\r
-       }\r
-       \r
-       \r
-       public vtkRenderer getRenderer() {\r
-               return ren1;\r
-       }\r
-       \r
-       \r
-       \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.gizmo;
+
+import java.util.Collection;
+
+import javax.vecmath.AxisAngle4d;
+import javax.vecmath.Tuple3d;
+import javax.vecmath.Vector3d;
+
+import org.simantics.g3d.gizmo.Gizmo;
+import org.simantics.g3d.math.MathTools;
+import org.simantics.g3d.vtk.common.VtkView;
+
+import vtk.vtkProp;
+import vtk.vtkProp3D;
+import vtk.vtkRenderer;
+
+public abstract class vtkGizmo implements Gizmo<vtkProp, VtkView> {
+
+       private VtkView view;
+       private Collection<vtkProp> gizmo;
+       
+       private Tuple3d position;
+       private AxisAngle4d orientation;
+       private Tuple3d scale;
+       
+       @Override
+       public void attach(VtkView renderingPart) {
+               if (view != null)
+                       throw new RuntimeException("Gizmo is attached");
+               view = renderingPart;
+               
+               attachActors();
+       }
+       
+       @Override
+       public void deattach() {
+               if (view == null)
+                       throw new RuntimeException("Gizmo is not attached");
+               deattachActors();
+               view = null;
+       }
+       
+       public boolean isAttached() {
+               return (view != null);
+       }
+       
+       protected void attachActors() {
+               view.lock();
+               gizmo = getGizmo();
+               vtkRenderer ren1 = view.getRenderer();
+               for (vtkProp p : gizmo) {
+                       ren1.AddActor(p);
+               }
+               if (position != null)
+                       setPosition(position);
+               if (orientation != null)
+                       setRotation(orientation);
+               if (scale != null)
+                       setScale(scale);
+               view.unlock();
+       }
+       
+       protected void deattachActors() {
+               view.lock();
+               vtkRenderer ren1 = view.getRenderer();
+               for (vtkProp p : gizmo) {
+                       ren1.RemoveActor(p);
+               }
+               view.unlock();
+       }
+       
+       @Override
+       public boolean isPartOf(vtkProp pickedObject) {
+               for (vtkProp prop : gizmo) {
+                       if (prop.equals(pickedObject))
+                               return true;
+               }
+               return false;
+       }
+       
+        public void setPosition(Tuple3d position) {
+                this.position = position;
+                for (vtkProp p : gizmo) {
+                        ((vtkProp3D)p).SetPosition(position.x, position.y, position.z);
+                }
+        }
+        
+        public void setRotation(AxisAngle4d q) {
+                this.orientation = q;
+                for (vtkProp p : gizmo) {
+                        ((vtkProp3D)p).SetOrientation(0,0,0);
+                        ((vtkProp3D)p).RotateWXYZ(MathTools.radToDeg(q.angle), q.x, q.y, q.z);
+                }
+        }
+       
+        
+        public void setScale(Tuple3d s) {
+                this.scale = s;
+                for (vtkProp p : gizmo) {
+                        ((vtkProp3D)p).SetScale(s.x, s.y, s.z);
+                }
+        }
+        
+        public void setScale(double s) {
+                this.scale = new Vector3d(s,s,s);
+                for (vtkProp p : gizmo) {
+                        ((vtkProp3D)p).SetScale(s, s, s);
+                }
+        }
+       
+       public abstract Collection<vtkProp> getGizmo();
+       
+//     public double[] add(double[] color1, double[] color2) {
+//             double[] result = new double[]{color1[0]+color2[0],color1[1],+color2[1],color1[2]+color2[2]};
+//             return result;
+//     }
+//     
+//     public double[] add(double[] color1, double[] color2, double[] color3) {
+//             double[] result = new double[]{color1[0]+color2[0]+color3[0],color1[1],+color2[1]+color3[1],color1[2]+color2[2]+color3[2]};
+//             return result;
+//     }
+       
+       public double[] add(double[]... color) {
+               double result[] = new double[]{0,0,0};
+               for (double c[] : color) {
+                       for (int i = 0; i < 3; i++)
+                               result[i] += c[i];
+               }
+               
+               return result;
+       }
+       
+       
+       public VtkView getView() {
+               return view;
+       }
+       
+       
+       
+}
index 218668ec74b5d935c0f48d2c5b59440112649af3..c3e0e54a98f29abd910b5e81739952086e6f1a3e 100644 (file)
@@ -1,77 +1,76 @@
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.vtk.handlers;\r
-\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-import javax.vecmath.Vector3d;\r
-\r
-import org.eclipse.core.commands.AbstractHandler;\r
-import org.eclipse.core.commands.ExecutionEvent;\r
-import org.eclipse.core.commands.ExecutionException;\r
-import org.eclipse.ui.IWorkbenchPart;\r
-import org.eclipse.ui.handlers.HandlerUtil;\r
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;\r
-import org.simantics.utils.threads.AWTThread;\r
-import org.simantics.utils.threads.ThreadUtils;\r
-\r
-public class CameraPositionHandler extends AbstractHandler {\r
-\r
-       \r
-       private Map<InteractiveVtkPanel,Vector3d> cameraPos = new HashMap<InteractiveVtkPanel, Vector3d>();\r
-       \r
-       @Override\r
-       public Object execute(ExecutionEvent event) throws ExecutionException {\r
-            \r
-            final IWorkbenchPart ap = HandlerUtil.getActiveEditor(event);\r
-            final InteractiveVtkPanel panel = (InteractiveVtkPanel)ap.getAdapter(InteractiveVtkPanel.class);\r
-            \r
-            String param = event.getParameter("org.simantics.g3d.viewDirection");\r
-            String vals[] = param.split(",");\r
-            final Vector3d direction = new Vector3d(Double.parseDouble(vals[0]),Double.parseDouble(vals[1]),Double.parseDouble(vals[2]));\r
-\r
-            \r
-            ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {\r
-                       \r
-                       @Override\r
-                       public void run() {\r
-\r
-                               Vector3d focal = new Vector3d(panel.GetRenderer().GetActiveCamera().GetFocalPoint());\r
-                               Vector3d pos = new Vector3d(panel.GetRenderer().GetActiveCamera().GetPosition());\r
-                               cameraPos.put(panel, pos);\r
-                               Vector3d dir = new Vector3d(pos);\r
-                               dir.sub(focal);\r
-                               double distance = dir.length();\r
-                               \r
-                               dir.set(direction);\r
-                               dir.scale(distance);\r
-                               dir.add(focal);\r
-                               panel.GetRenderer().GetActiveCamera().SetPosition(dir.x, dir.y, dir.z);\r
-                               if (Math.abs(direction.dot(new Vector3d(0,1,0))) < 0.95)\r
-                                       panel.GetRenderer().GetActiveCamera().SetViewUp(0, 1, 0);\r
-                               else\r
-                                       panel.GetRenderer().GetActiveCamera().SetViewUp(1, 0, 0);\r
-                               \r
-                               panel.GetRenderer().ResetCameraClippingRange();\r
-                               \r
-                               panel.UpdateLight();\r
-                               panel.repaint();\r
-                       }\r
-                });\r
-           \r
-            return null;\r
-            \r
-       }\r
-       \r
-       \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.handlers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.vecmath.Vector3d;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.simantics.g3d.vtk.common.VtkView;
+import org.simantics.utils.threads.ThreadUtils;
+
+public class CameraPositionHandler extends AbstractHandler {
+
+       
+       private Map<VtkView,Vector3d> cameraPos = new HashMap<VtkView, Vector3d>();
+       
+       @Override
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+            
+            final IWorkbenchPart ap = HandlerUtil.getActiveEditor(event);
+            final VtkView panel = (VtkView)ap.getAdapter(VtkView.class);
+            
+            String param = event.getParameter("org.simantics.g3d.viewDirection");
+            String vals[] = param.split(",");
+            final Vector3d direction = new Vector3d(Double.parseDouble(vals[0]),Double.parseDouble(vals[1]),Double.parseDouble(vals[2]));
+
+            
+            ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
+                       
+                       @Override
+                       public void run() {
+
+                               Vector3d focal = new Vector3d(panel.getRenderer().GetActiveCamera().GetFocalPoint());
+                               Vector3d pos = new Vector3d(panel.getRenderer().GetActiveCamera().GetPosition());
+                               cameraPos.put(panel, pos);
+                               Vector3d dir = new Vector3d(pos);
+                               dir.sub(focal);
+                               double distance = dir.length();
+                               
+                               dir.set(direction);
+                               dir.scale(distance);
+                               dir.add(focal);
+                               panel.getRenderer().GetActiveCamera().SetPosition(dir.x, dir.y, dir.z);
+                               if (Math.abs(direction.dot(new Vector3d(0,1,0))) < 0.95)
+                                       panel.getRenderer().GetActiveCamera().SetViewUp(0, 1, 0);
+                               else
+                                       panel.getRenderer().GetActiveCamera().SetViewUp(1, 0, 0);
+                               
+                               panel.getRenderer().ResetCameraClippingRange();
+                               
+                               //panel.UpdateLight();
+                               panel.refresh();
+                       }
+                });
+           
+            return null;
+            
+       }
+       
+       
+}
index aad92f987a20271e8790e59eb4ae6403b401a8ea..855a0d145286696194ac03b0511878b7b7d8ab04 100644 (file)
@@ -1,82 +1,82 @@
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.vtk.handlers;\r
-\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-import javax.vecmath.Vector3d;\r
-\r
-import org.eclipse.core.commands.AbstractHandler;\r
-import org.eclipse.core.commands.Command;\r
-import org.eclipse.core.commands.ExecutionEvent;\r
-import org.eclipse.core.commands.ExecutionException;\r
-import org.eclipse.ui.IWorkbenchPart;\r
-import org.eclipse.ui.handlers.HandlerUtil;\r
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;\r
-import org.simantics.utils.threads.AWTThread;\r
-import org.simantics.utils.threads.ThreadUtils;\r
-\r
-public class ParallelPerspectiveHandler extends AbstractHandler {\r
-\r
-       \r
-       private Map<InteractiveVtkPanel,Vector3d> cameraPos = new HashMap<InteractiveVtkPanel, Vector3d>();\r
-       \r
-       @Override\r
-       public Object execute(ExecutionEvent event) throws ExecutionException {\r
-                Command command = event.getCommand();\r
-            boolean oldValue = HandlerUtil.toggleCommandState(command);\r
-            final boolean activate = !oldValue;\r
-            \r
-            final IWorkbenchPart ap = HandlerUtil.getActiveEditor(event);\r
-            final InteractiveVtkPanel panel = (InteractiveVtkPanel)ap.getAdapter(InteractiveVtkPanel.class);\r
-            \r
-            ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {\r
-                       \r
-                       @Override\r
-                       public void run() {\r
-                               if (activate){\r
-                                       Vector3d focal = new Vector3d(panel.GetRenderer().GetActiveCamera().GetFocalPoint());\r
-                                       Vector3d pos = new Vector3d(panel.GetRenderer().GetActiveCamera().GetPosition());\r
-                                       cameraPos.put(panel, pos);\r
-                                       Vector3d dir = new Vector3d(pos);\r
-                                       dir.sub(focal);\r
-                                       dir.normalize();\r
-                                       dir.scale(100);\r
-                                       dir.add(focal);\r
-                                       panel.GetRenderer().GetActiveCamera().SetPosition(dir.x, dir.y, dir.z);\r
-                                       \r
-                                       \r
-                                       panel.GetRenderer().GetActiveCamera().SetParallelProjection(1);\r
-                                       panel.GetRenderer().ResetCameraClippingRange();\r
-                               } else {\r
-                                       panel.GetRenderer().GetActiveCamera().SetParallelProjection(0);\r
-                                       Vector3d pos = cameraPos.get(panel);\r
-                                       if (pos != null) {\r
-                                               panel.GetRenderer().GetActiveCamera().SetPosition(pos.x, pos.y, pos.z);\r
-                                       }\r
-                                       panel.GetRenderer().ResetCameraClippingRange();\r
-                                       \r
-                               }\r
-                               panel.UpdateLight();\r
-                               panel.repaint();\r
-\r
-                       }\r
-                });\r
-           \r
-            return null;\r
-            \r
-       }\r
-       \r
-       \r
-       \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.handlers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.vecmath.Vector3d;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.simantics.g3d.vtk.common.VtkView;
+import org.simantics.utils.threads.AWTThread;
+import org.simantics.utils.threads.ThreadUtils;
+
+public class ParallelPerspectiveHandler extends AbstractHandler {
+
+       
+       private Map<VtkView,Vector3d> cameraPos = new HashMap<VtkView, Vector3d>();
+       
+       @Override
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+                Command command = event.getCommand();
+            boolean oldValue = HandlerUtil.toggleCommandState(command);
+            final boolean activate = !oldValue;
+            
+            final IWorkbenchPart ap = HandlerUtil.getActiveEditor(event);
+            final VtkView panel = (VtkView)ap.getAdapter(VtkView.class);
+            
+            ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+                       
+                       @Override
+                       public void run() {
+                               if (activate){
+                                       Vector3d focal = new Vector3d(panel.getRenderer().GetActiveCamera().GetFocalPoint());
+                                       Vector3d pos = new Vector3d(panel.getRenderer().GetActiveCamera().GetPosition());
+                                       cameraPos.put(panel, pos);
+                                       Vector3d dir = new Vector3d(pos);
+                                       dir.sub(focal);
+                                       dir.normalize();
+                                       dir.scale(100);
+                                       dir.add(focal);
+                                       panel.getRenderer().GetActiveCamera().SetPosition(dir.x, dir.y, dir.z);
+                                       
+                                       
+                                       panel.getRenderer().GetActiveCamera().SetParallelProjection(1);
+                                       panel.getRenderer().ResetCameraClippingRange();
+                               } else {
+                                       panel.getRenderer().GetActiveCamera().SetParallelProjection(0);
+                                       Vector3d pos = cameraPos.get(panel);
+                                       if (pos != null) {
+                                               panel.getRenderer().GetActiveCamera().SetPosition(pos.x, pos.y, pos.z);
+                                       }
+                                       panel.getRenderer().ResetCameraClippingRange();
+                                       
+                               }
+//                             panel.UpdateLight();
+                               panel.refresh();
+
+                       }
+                });
+           
+            return null;
+            
+       }
+       
+       
+       
+}
index 10176616a37149569fc045a81686428774473818..7686aaa19c6059da5d47d8070dc1bbcdb1670050 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.vtk.property;\r
-\r
-import org.eclipse.jface.viewers.ISelection;\r
-import org.eclipse.jface.viewers.ISelectionProvider;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.layout.FillLayout;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.Text;\r
-import org.eclipse.ui.IWorkbenchSite;\r
-import org.simantics.db.management.ISessionContext;\r
-import org.simantics.selectionview.IPropertyTab;\r
-import org.simantics.selectionview.PropertyTabContributor;\r
-import org.simantics.utils.threads.AWTThread;\r
-import org.simantics.utils.threads.ThreadUtils;\r
-\r
-import vtk.vtkActor;\r
-import vtk.vtkAlgorithm;\r
-import vtk.vtkAlgorithmOutput;\r
-import vtk.vtkMapper;\r
-import vtk.vtkProp;\r
-\r
-public class VTKPropertyTabContributor implements PropertyTabContributor{\r
-       \r
-       public org.simantics.selectionview.IPropertyTab create(Composite parent, IWorkbenchSite site, ISessionContext context, Object input) {\r
-               IPropertyTab tab = new VTKPropertyTab((vtkProp)input);\r
-               tab.createControl(parent, context);\r
-               return tab;\r
-       };\r
-       \r
-       \r
-       public class VTKPropertyTab implements IPropertyTab {\r
-               private Composite composite;\r
-               private Text text;\r
-               private vtkProp prop;\r
-               \r
-               public VTKPropertyTab(vtkProp prop) {\r
-                       this.prop = prop;\r
-               }\r
-               \r
-               @Override\r
-               public void createControl(Composite parent, ISessionContext context) {\r
-                       \r
-                       composite = new Composite(parent, SWT.NONE);\r
-                       composite.setLayout(new FillLayout());\r
-                       text = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY);\r
-                       ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {\r
-                               \r
-                               @Override\r
-                               public void run() {\r
-                                       String string = "";\r
-                                       if (prop instanceof vtkActor) {\r
-                                               vtkActor act = (vtkActor)prop;\r
-                                               vtkMapper mapper = act.GetMapper();\r
-                                               vtkAlgorithmOutput out = mapper.GetInputConnection(0, 0);\r
-                                               vtkAlgorithm producer = out.GetProducer();\r
-                                               string += producer.GetClassName() +"\n";\r
-                                               out.Delete();\r
-                                               mapper.Delete();\r
-                                               producer.Delete();\r
-                                       }\r
-                                       string += prop.Print();\r
-                                       final String s = string;\r
-                                       Display.getDefault().asyncExec(new Runnable() {\r
-                                               @Override\r
-                                               public void run() {\r
-                                                       if (!text.isDisposed())\r
-                                                               text.setText(s);\r
-                                               }\r
-                                       });\r
-                               }\r
-                       });;\r
-                       \r
-                       \r
-               }\r
-               \r
-               @Override\r
-               public void requestFocus() {\r
-                       composite.setFocus();\r
-               }\r
-               \r
-               @Override\r
-               public void dispose() {\r
-                       composite.dispose();\r
-               }\r
-               \r
-               @Override\r
-               public boolean isDisposed() {\r
-                       return composite.isDisposed();\r
-               }\r
-               \r
-               @Override\r
-               public Control getControl() {\r
-                       return composite;\r
-               }\r
-               \r
-               @Override\r
-               public void setInput(ISessionContext context, ISelection selection,\r
-                               boolean force) {\r
-                       \r
-               }\r
-               \r
-               @Override\r
-               public ISelectionProvider getSelectionProvider() {\r
-                       return null;\r
-               }\r
-       }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.property;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchSite;
+import org.simantics.db.management.ISessionContext;
+import org.simantics.selectionview.IPropertyTab;
+import org.simantics.selectionview.PropertyTabContributor;
+import org.simantics.utils.threads.IThreadWorkQueue;
+import org.simantics.utils.threads.ThreadUtils;
+
+import vtk.vtkActor;
+import vtk.vtkAlgorithm;
+import vtk.vtkAlgorithmOutput;
+import vtk.vtkMapper;
+import vtk.vtkProp;
+
+public class VTKPropertyTabContributor implements PropertyTabContributor{
+       
+       private IThreadWorkQueue tq;
+       public VTKPropertyTabContributor(IThreadWorkQueue tq) {
+               this.tq = tq;
+       }
+       
+       public org.simantics.selectionview.IPropertyTab create(Composite parent, IWorkbenchSite site, ISessionContext context, Object input) {
+               IPropertyTab tab = new VTKPropertyTab((vtkProp)input);
+               tab.createControl(parent, context);
+               return tab;
+       };
+       
+       
+       public class VTKPropertyTab implements IPropertyTab {
+               private Composite composite;
+               private Text text;
+               private vtkProp prop;
+               
+               public VTKPropertyTab(vtkProp prop) {
+                       this.prop = prop;
+               }
+               
+               @Override
+               public void createControl(Composite parent, ISessionContext context) {
+                       
+                       composite = new Composite(parent, SWT.NONE);
+                       composite.setLayout(new FillLayout());
+                       text = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY);
+                       ThreadUtils.asyncExec(tq, new Runnable() {
+                               
+                               @Override
+                               public void run() {
+                                       String string = "";
+                                       if (prop instanceof vtkActor) {
+                                               vtkActor act = (vtkActor)prop;
+                                               vtkMapper mapper = act.GetMapper();
+                                               vtkAlgorithmOutput out = mapper.GetInputConnection(0, 0);
+                                               vtkAlgorithm producer = out.GetProducer();
+                                               string += producer.GetClassName() +"\n";
+                                               out.Delete();
+                                               mapper.Delete();
+                                               producer.Delete();
+                                       }
+                                       string += prop.Print();
+                                       final String s = string;
+                                       Display.getDefault().asyncExec(new Runnable() {
+                                               @Override
+                                               public void run() {
+                                                       if (!text.isDisposed())
+                                                               text.setText(s);
+                                               }
+                                       });
+                               }
+                       });;
+                       
+                       
+               }
+               
+               @Override
+               public void requestFocus() {
+                       composite.setFocus();
+               }
+               
+               @Override
+               public void dispose() {
+                       composite.dispose();
+               }
+               
+               @Override
+               public boolean isDisposed() {
+                       return composite.isDisposed();
+               }
+               
+               @Override
+               public Control getControl() {
+                       return composite;
+               }
+               
+               @Override
+               public void setInput(ISessionContext context, ISelection selection,
+                               boolean force) {
+                       
+               }
+               
+               @Override
+               public ISelectionProvider getSelectionProvider() {
+                       return null;
+               }
+       }
+
+}
index 0e60a270f24ce699a243ed3c16c00dbe8250630e..466d0864bef56c871d93cb708450fb8b836aabfc 100644 (file)
@@ -1,62 +1,63 @@
 package org.simantics.g3d.vtk.shape;
 
 import org.simantics.g3d.shape.Mesh;
-import org.simantics.utils.threads.AWTThread;
+import org.simantics.g3d.vtk.common.VtkView;
 import org.simantics.utils.threads.ThreadUtils;
 
-import vtk.vtkPanel;
 import vtk.vtkRenderer;
 
 public class vtkMeshObject {
        
-       private vtkPanel panel;
+       private VtkView panel;
        private Mesh mesh;
        
        private MeshActor meshActor;
        
-       public vtkMeshObject(vtkPanel panel, Mesh mesh) {
+       public vtkMeshObject(VtkView panel, Mesh mesh) {
                this.mesh = mesh;
                this.panel = panel;
        }
        
        public void visualizeMesh() {
-               clearActorsAWT();
+               clearActorsVTK();
                meshActor = new MeshActor();
                meshActor.setMesh(mesh);
                //System.out.println("Set mesh " + mesh.getVertices().size() + " " + mesh.getIndices().size() + " " + this);
-               showActorsAWT();
+               showActorsVTK();
        }
        
        public MeshActor getActor() {
-               assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread());
+               assert (Thread.currentThread() == panel.getThreadQueue().getThread());
                return meshActor;
        }
        
-       public void showActorsAWT() {
+       public void showActorsVTK() {
                //System.out.println("showActorsAWT " + this + " " + meshActor != null);
-               assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread());
-               vtkRenderer ren = panel.GetRenderer();
+               assert (Thread.currentThread() == panel.getThreadQueue().getThread());
+               panel.lock();
+               vtkRenderer ren = panel.getRenderer();
                if (meshActor != null)
                        ren.AddActor(meshActor);
+               panel.unlock();
        }
        
        public void showActors() {
-               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+               ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
                        
                        @Override
                        public void run() {
-                               showActorsAWT();
+                               showActorsVTK();
                        }
                });
        }
        
-       public void clearActorsAWT() {
-               assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread());
+       public void clearActorsVTK() {
+               assert (Thread.currentThread() == panel.getThreadQueue().getThread());
                
                if (meshActor == null)
                        return;
                //System.out.println("clearActorsAwt " + this);
-               vtkRenderer ren = panel.GetRenderer();
+               vtkRenderer ren = panel.getRenderer();
                if (ren == null)
                        return;
                panel.lock();
@@ -68,13 +69,13 @@ public class vtkMeshObject {
                meshActor = null;
        }
        
-       private void clearActorsAWT(MeshActor meshActor) {
-               assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread());
+       private void clearActorsVTK(MeshActor meshActor) {
+               assert (Thread.currentThread() == panel.getThreadQueue().getThread());
                
                if (meshActor == null)
                        return;
                //System.out.println("clearActorsAwt2 " + this);
-               vtkRenderer ren = panel.GetRenderer();
+               vtkRenderer ren = panel.getRenderer();
                if (ren == null)
                        return;
                panel.lock();
@@ -89,11 +90,11 @@ public class vtkMeshObject {
        public void clearActors() {
                if (meshActor == null)
                        return;
-               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+               ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
                        
                        @Override
                        public void run() {
-                               clearActorsAWT(meshActor);
+                               clearActorsVTK(meshActor);
                        }
                });
        }
@@ -105,7 +106,7 @@ public class vtkMeshObject {
        
        public void delete() {
                mesh = null;
-               clearActorsAWT();
+               clearActorsVTK();
        }
 
 }
diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/ContextMenuListener.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/ContextMenuListener.java
new file mode 100644 (file)
index 0000000..c7ed54a
--- /dev/null
@@ -0,0 +1,49 @@
+package org.simantics.g3d.vtk.swt;
+
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Menu;
+
+public class ContextMenuListener implements MouseListener{
+       
+       InteractiveVtkComposite panel;
+       Menu contextMenu;
+       
+       public ContextMenuListener(InteractiveVtkComposite panel, Menu contextMenu) {
+               this.panel = panel;
+               this.contextMenu = contextMenu;
+               this.panel.getComponent().addMouseListener(this);
+       }
+       
+       int x = 0;
+       int y = 0;
+       int d = 4;
+       int time = 0;
+       
+       @Override
+       public void mouseUp(MouseEvent e) {
+               if (e.button == 3) {
+                       if (Math.abs(x-e.x) < d && Math.abs(y-e.y) < d && (e.time - time) < 500) {
+                               Point point = panel.getComponent().getParent().toDisplay(new Point(e.x, e.y));
+                               contextMenu.setLocation(point.x, point.y);
+                               contextMenu.setVisible(true);
+                       }
+               }
+       }
+       
+       @Override
+       public void mouseDown(MouseEvent e) {
+               if (e.button == 3) {
+                       x = e.x;
+                       y = e.y;
+                       time = e.time;
+               }
+       }
+       
+       @Override
+       public void mouseDoubleClick(MouseEvent e) {
+                       
+       }
+
+}
diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/InteractiveVtkComposite.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/InteractiveVtkComposite.java
new file mode 100644 (file)
index 0000000..b20bcac
--- /dev/null
@@ -0,0 +1,425 @@
+package org.simantics.g3d.vtk.swt;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.vecmath.Vector3d;
+
+import org.eclipse.swt.widgets.Composite;
+import org.simantics.g3d.math.Ray;
+import org.simantics.g3d.scenegraph.RenderListener;
+import org.simantics.g3d.vtk.action.vtkAction;
+import org.simantics.g3d.vtk.common.VtkView;
+import org.simantics.g3d.vtk.utils.vtkUtil;
+import org.simantics.utils.threads.IThreadWorkQueue;
+import org.simantics.utils.threads.SWTThread;
+import org.simantics.utils.threads.ThreadUtils;
+
+import vtk.vtkAbstractPicker;
+import vtk.vtkActor2D;
+import vtk.vtkActor2DCollection;
+import vtk.vtkAreaPicker;
+import vtk.vtkAssemblyNode;
+import vtk.vtkAssemblyPath;
+import vtk.vtkCellPicker;
+import vtk.vtkCoordinate;
+import vtk.vtkObjectBase;
+import vtk.vtkPointPicker;
+import vtk.vtkProp;
+import vtk.vtkProp3DCollection;
+import vtk.vtkPropCollection;
+import vtk.vtkPropPicker;
+import vtk.vtkRenderWindow;
+import vtk.vtkRenderer;
+import vtk.vtkScenePicker;
+import vtk.rendering.swt.vtkSwtComponent;
+
+public class InteractiveVtkComposite extends vtkSwtComponent implements VtkView{
+       
+       Composite parentComposite;
+       public InteractiveVtkComposite(Composite parentComposite) {
+               super(parentComposite);
+               this.parentComposite = parentComposite;
+               
+               // TODO Auto-generated constructor stub
+       }
+       
+       private boolean updating = false;
+       private Object mutex = new Object();
+       
+       @Override
+       public void refresh() {
+//             if (Thread.currentThread() == getThreadQueue().getThread())
+//                     update();
+//             else {
+                       synchronized (mutex) {
+                               if (!updating) {
+                                       updating = true;
+                                       ThreadUtils.asyncExec(getThreadQueue(), new Runnable() {
+                                               
+                                               @Override
+                                               public void run() {
+                                                       if (parentComposite.isDisposed())
+                                                               return;
+                                                       synchronized (mutex) {
+                                                               updating = false;
+                                                       }
+                                                       update();
+                                               }
+                                       });
+                                       
+                               }
+                       }
+//             }
+       }
+       
+       boolean update = false;
+       @Override
+       public void update() {
+               if (update)
+                       return;
+               update = true;
+               super.update();
+               update = false;
+       }
+       
+       @Override
+       public IThreadWorkQueue getThreadQueue() {
+               return SWTThread.getThreadAccess();
+       }
+       
+
+       boolean render = false;
+       @Override
+       public void Render() {
+               if (render)
+                       return;
+//             System.out.println(getClass().getSimpleName() +" render");
+               render = true;
+               firePreRender();
+               super.Render();
+               firePostRender();
+               render = false;
+       }
+
+       public void addListener(RenderListener l) {
+               listeners.add(l);
+       }
+       
+       public void removeListener(RenderListener l) {
+               listeners.remove(l);
+       }
+       
+       private List<RenderListener> listeners = new ArrayList<RenderListener>();
+       
+       List<RenderListener> list = new ArrayList<RenderListener>();
+       
+       private void firePreRender() {
+               if (listeners.size() > 0) {
+                       list.addAll(listeners);
+                       for (RenderListener l : list)
+                               l.preRender();
+                       list.clear();
+               }
+       }
+       
+       private void firePostRender() {
+               if (listeners.size() > 0) {
+                       list.addAll(listeners);
+                       for (RenderListener l : list)
+                               l.postRender();
+                       list.clear();
+               }
+       }
+
+       
+       private List<vtkObjectBase> deletable = new ArrayList<vtkObjectBase>();
+       
+       public void addDeletable(vtkObjectBase o) {
+               deletable.add(o);
+       }
+       
+       public void removeDeletable (vtkObjectBase o) {
+               deletable.remove(o);
+       }
+       
+       @Override
+       public void Delete() {
+               for (vtkObjectBase o : deletable) {
+                       if (o.GetVTKId() != 0) {
+                               o.Delete();
+                       }
+               }
+               deletable.clear();
+               
+               super.Delete();
+       }
+       
+       private vtkSwtAction defaultAction;
+       private vtkSwtAction currentAction;
+       
+       public void setActiveAction(vtkAction action) {
+               if (action.equals(currentAction))
+                       return;
+               if (currentAction != null)
+                       currentAction.deattach();
+               currentAction = (vtkSwtAction)action;
+               if (action != null)
+                       action.attach();
+       }
+       
+       public void setDefaultAction(vtkAction defaultAction) {
+               this.defaultAction = (vtkSwtAction)defaultAction;
+       }
+       
+       public void useDefaultAction() {
+               setActiveAction(defaultAction);
+       }
+       
+       public vtkAction getDefaultAction() {
+               return defaultAction;
+       }
+       
+       public void lock() {
+               getVTKLock().lock();
+               if (getComponent().getContext() != null && !getComponent().getContext().isCurrent()) {
+                       int ret = getComponent().getContext().makeCurrent();
+//                     System.out.println("Make current2 " + ret);
+               }
+       }
+       
+       public void unlock() {
+               getVTKLock().unlock();
+       }
+       
+       private vtkScenePicker scenePicker;
+       
+       int pickType = 4;
+       
+       public int getPickType() {
+               return pickType;
+       }
+       
+       public void setPickType(int pickType) {
+               this.pickType = pickType;
+       }
+       
+       public vtkProp[] pick(int x, int y) {
+               
+               
+               vtkRenderWindow rw = getRenderWindow();
+               vtkRenderer ren = getRenderer();
+               
+               int ax = x;
+               int ay = rw.GetSize()[1] - y;
+
+               if (pickType == 0) {
+                       throw new IllegalStateException("SWT Binding does not work with hw picking");
+//                     lock();
+//                     ren.BreakOnError();
+//                     ren.DrawOff();
+//                     vtkPropPicker picker = new vtkPropPicker();
+//                     picker.DebugOn();
+//                     //picker.PickProp(x, rw.GetSize()[1] - y, ren);
+//                     picker.Pick(x, rw.GetSize()[1] - y,0, ren);
+//                     ren.DrawOn();
+//                     unlock();
+//     
+//                     vtkAssemblyPath apath = picker.GetPath();
+//                     return processPick(picker, apath);
+//                     
+               } else if (pickType == 1) {
+                       throw new IllegalStateException("SWT Binding does not work with hw picking");
+//                     if (scenePicker == null) {
+//                             scenePicker = new vtkScenePicker();
+//                             scenePicker.SetRenderer(ren);
+//                             scenePicker.EnableVertexPickingOn();
+//                             
+//                     }
+//                     lock();
+//
+//                     vtkAssemblyPath apath = ren.PickProp(ax, ay);
+//                     
+//                     unlock();
+//                     
+//                     if (apath != null) {
+//                             apath.InitTraversal();
+//                             vtkAssemblyNode node = apath.GetLastNode();
+//                             vtkProp test = (vtkProp) node.GetViewProp();
+//                             apath.Delete();
+//                             node.Delete();
+//                             return new vtkProp[]{test};
+//     
+//                     }
+                       
+               } else if (pickType == 2) {
+                       vtkPointPicker picker = new vtkPointPicker();
+                       //picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
+                       picker.SetTolerance(0.00001);
+                       lock();
+                       picker.Pick(new double[]{ax, ay,0}, ren);
+                       unlock();
+                       
+                       vtkAssemblyPath apath = picker.GetPath();
+                       return processPick(picker, apath);
+               } else if (pickType == 3) {
+                       vtkAreaPicker picker = new vtkAreaPicker();
+                       lock();
+                       picker.Pick(new double[]{ax, ay,0}, ren);
+                       unlock();
+                       vtkAssemblyPath apath = picker.GetPath();
+                       return processPick(picker, apath);
+               } else if (pickType == 4) {
+                       vtkCellPicker picker = new vtkCellPicker();
+                       picker.SetTolerance(0.00001);
+                       lock();
+                       picker.Pick(new double[]{ax, ay,0}, ren);
+                       unlock();       
+                       vtkAssemblyPath apath = picker.GetPath();
+                       return processPick(picker, apath);
+               } else if (pickType == 5) {
+                       vtkActor2DCollection coll = ren.GetActors2D(); 
+                   coll.InitTraversal();
+                   vtkActor2D a;
+                   
+                   List<vtkActor2D> picked = new ArrayList<vtkActor2D>();
+                   while ((a = coll.GetNextItem()) != null) {
+                       double pos[] = a.GetPosition();
+                       // TODO : width and height do not seem to affect the perceived size of Actor2D.
+                       //        actual size should be fetched from mapper. 
+                       double w = a.GetWidth();
+                       double h = a.GetHeight();
+                       int minx = (int)(pos[0]-w*0.5);
+                       int miny = (int)(pos[1]-h*0.5);
+                       int maxx = (int)(pos[0]+w*0.5);
+                       int maxy = (int)(pos[1]+h*0.5);
+                       if (minx <= ax && maxx >= ax &&
+                               miny <= ay && maxy >= ay) {
+                               picked.add(a);
+                       }
+                   }
+                   return picked.toArray(new vtkProp[picked.size()]);
+               }
+
+               return null;
+       }
+       
+       public vtkProp[] pick2(int x, int y) {
+               vtkRenderWindow rw = getRenderWindow();
+               vtkRenderer ren = getRenderer();
+               
+//             vtkPicker picker = new vtkPicker();
+//             vtkAbstractPicker picker = new vtkAbstractPicker();
+//             picker.Pick(x, rw.GetSize()[1] - y, ren);
+//             // see page 60 of VTK user's guide
+//
+               if (pickType == 0) {
+       
+                       vtkPropPicker picker = new vtkPropPicker();
+                       lock();
+                       picker.PickProp(x, rw.GetSize()[1] - y, ren);
+       
+                       unlock();
+                       vtkPropCollection coll = picker.GetPickList();
+                       return processPick(picker, coll);
+                       
+               } else if (pickType == 1) {
+                       if (scenePicker == null) {
+                               scenePicker = new vtkScenePicker();
+                               scenePicker.SetRenderer(ren);
+                               scenePicker.EnableVertexPickingOn();
+                               scenePicker.DebugOn();
+                               
+                       }
+                       lock();
+
+                       
+                       vtkAssemblyPath apath = ren.PickProp(x, rw.GetSize()[1] - y);
+                       
+                       unlock();
+                       
+                       if (apath != null) {
+                               apath.InitTraversal();
+
+                               
+                               vtkAssemblyNode node = apath.GetLastNode();
+                               vtkProp test = (vtkProp) node.GetViewProp();
+                               apath.Delete();
+                               node.Delete();
+                               return new vtkProp[]{test};
+       
+                       }
+                       
+               } else if (pickType == 2) {
+                       vtkPointPicker picker = new vtkPointPicker();
+                       picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
+                       lock();
+                       picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
+                       unlock();
+                       vtkProp3DCollection coll = picker.GetProp3Ds();
+                       return processPick(picker, coll);
+               } else if (pickType == 3) {
+                       vtkAreaPicker picker = new vtkAreaPicker();
+                       lock();
+                       picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
+                       //picker.AreaPick(x-1, rw.GetSize()[1] - y-1,x+1,rw.GetSize()[1] - y+1, ren);
+                       unlock();
+                       vtkProp3DCollection coll = picker.GetProp3Ds();
+                       return processPick(picker, coll);
+               } else if (pickType == 4) {
+                       vtkCellPicker picker = new vtkCellPicker();
+                       picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
+                       lock();
+                       picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
+                       unlock();       
+                       vtkProp3DCollection coll = picker.GetProp3Ds();
+                       return processPick(picker, coll);
+               }
+
+               return null;
+       }
+       
+       private vtkProp[] processPick(vtkAbstractPicker picker, vtkAssemblyPath apath) {
+//             double[] pickPos = picker.GetPickPosition();
+               picker.Delete();
+               if (apath != null) {
+                       apath.InitTraversal();
+                       vtkProp result[] = new vtkProp[apath.GetNumberOfItems()];
+                       for (int i = apath.GetNumberOfItems()-1; i >= 0; i--) {
+                               vtkAssemblyNode node = apath.GetNextNode();
+                               vtkProp test = (vtkProp) node.GetViewProp();
+//                             System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());
+                               result[i] = test;
+                               node.Delete();
+                       }
+                       apath.Delete();
+                       return result;
+
+               }
+               return null;
+       }
+       
+       private vtkProp[] processPick(vtkAbstractPicker picker, vtkPropCollection coll) {
+//             double[] pickPos = picker.GetPickPosition();
+               picker.Delete();
+               if (coll != null) {
+                       coll.InitTraversal();
+                       vtkProp result[] = new vtkProp[coll.GetNumberOfItems()];
+                       for (int i = coll.GetNumberOfItems()-1; i >= 0; i--) {
+                               vtkProp test = coll.GetNextProp();
+                               
+//                             System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());
+                               result[i] = test;
+                               
+                       }
+                       coll.Delete();
+                       return result;
+
+               }
+               return null;
+       }
+       
+       
+       
+}
diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/RotateAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/RotateAction.java
new file mode 100644 (file)
index 0000000..1b2d791
--- /dev/null
@@ -0,0 +1,661 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.swt;
+
+
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+
+import javax.vecmath.AxisAngle4d;
+import javax.vecmath.Point3d;
+import javax.vecmath.Quat4d;
+import javax.vecmath.Vector3d;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.widgets.Display;
+import org.simantics.g3d.math.EulerTools;
+import org.simantics.g3d.math.EulerTools.Order;
+import org.simantics.g3d.math.MathTools;
+import org.simantics.g3d.math.Ray;
+import org.simantics.g3d.preferences.PreferenceConstants;
+import org.simantics.g3d.scenegraph.IG3DNode;
+import org.simantics.g3d.scenegraph.structural.IStructuralNode;
+import org.simantics.g3d.vtk.Activator;
+import org.simantics.g3d.vtk.common.VTKNodeMap;
+import org.simantics.g3d.vtk.gizmo.RotateAxisGizmo;
+import org.simantics.g3d.vtk.utils.vtkUtil;
+import org.simantics.utils.threads.AWTThread;
+import org.simantics.utils.threads.ThreadUtils;
+
+import vtk.vtkProp;
+/**
+ * FIXME: complete rewrite.
+ * 
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
+ *
+ */
+public class RotateAction extends vtkSwtAction{
+       
+       public static final int X = 0;
+    public static final int Y = 1;
+    public static final int Z = 2;
+    public static final int P = 3;
+
+       private VTKNodeMap nodeMap;
+       //private TranslateGizmo  gizmo = new TranslateGizmo();
+       private RotateAxisGizmo gizmo = new RotateAxisGizmo();
+       private IG3DNode node;
+       
+       
+       
+       private Cursor activeCursor;// = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
+       private Cursor dragCursor;// = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
+       
+       
+       int stepMethod = 1;
+       Order order = Order.YXZ;
+       
+    private int steps; 
+    private double angles[];
+       
+       int index = P;
+       boolean valid = false;
+       private boolean worldCoord = true;
+       //private AxisAngle4d aa = null;
+       private Quat4d parentWorldOrientation = null;
+       
+       //AxisAngle4d rotation = new AxisAngle4d();
+       Quat4d worldOrientation = new Quat4d();
+       
+       public void setNode(IG3DNode node) {
+               this.node = node;
+               if ((node instanceof IStructuralNode) && ((IStructuralNode)node).isPartOfInstantiatedModel() && !((IStructuralNode)node).isInstantiatedModelRoot()) {
+                       setEnabled(false);
+               } else {
+                       setEnabled(true);
+               }
+               
+               String set = org.simantics.g3d.Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.ORIENTATION_PRESENTATION);
+               if (set.equals("aa")) {
+                       stepMethod = 0;
+               } else if (set.equals("euler")){
+                       stepMethod = 1;
+                       String eulerOrder = org.simantics.g3d.Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.EULER_ANGLE_ORDER);
+                       try {
+                               order = Order.valueOf(eulerOrder);
+                       } catch (Exception e) {
+                               order = Order.YXZ;
+                       }
+               } else {
+                       stepMethod = 2;
+               }
+       }
+       
+       public IG3DNode getNode() {
+               return node;
+       }
+       
+       public RotateAction(InteractiveVtkComposite panel, VTKNodeMap nodeMap) {
+               super(panel);
+               setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_rotate_clockwise.png"));
+               setText("Rotate");
+               this.nodeMap = nodeMap;
+               
+               
+               steps = 36;
+        angles = new double[steps+1];
+        for (int i = 0; i < angles.length; i++) {
+            angles[i] = - Math.PI + (Math.PI * i * 2.0 / steps);
+        }
+        
+        activeCursor = Display.getCurrent().getSystemCursor(SWT.CURSOR_HAND);
+        dragCursor = Display.getCurrent().getSystemCursor(SWT.CURSOR_CROSS);
+       }
+       
+       public void attach() {
+               if (node == null)
+                       return;
+               
+               super.attach();
+               ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
+                       public void run() {
+                               attachUI();
+                               update();
+                       }
+               });
+               
+               
+               
+       }
+       
+       public void deattach() {
+               
+               node = null;
+               nodeMap.commit();
+               deattachUI();
+               super.deattach();
+               panel.refresh();
+       }
+       
+       private void attachUI() {
+               panel.getComponent().setCursor(activeCursor);
+               gizmo.attach(panel);
+       }
+       
+       private void deattachUI() {
+               panel.getComponent().setCursor(Display.getCurrent().getSystemCursor(SWT.CURSOR_ARROW));
+               gizmo.deattach();
+       }
+       
+       @Override
+       public boolean keyPressed(KeyEvent e) {
+               if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
+                       panel.useDefaultAction();
+               if (valid)
+                       return true;
+               if (e.getKeyCode() == KeyEvent.VK_X) {
+                       if (index != X)
+                               index = X;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_Y) {
+                       if (index != Y)
+                               index = Y;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_Z) {
+                       if (index != Z)
+                               index = Z;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_G) {
+                       worldCoord = !worldCoord;
+               }
+               gizmo.setType(index);
+               panel.refresh();
+               return true;
+       }
+       
+       @Override
+       public boolean keyReleased(KeyEvent e) {
+               return false;
+       }
+       
+       
+       
+       @Override
+       public boolean mouseClicked(MouseEvent e) {
+               if (e.getClickCount() > 1) {
+                       if (isOverNode(e)) {
+                               return true;
+                       }
+                       panel.useDefaultAction();
+                       //if(!gizmo.isPartOf(actor))
+                       //      panel.useDefaultAction();
+                       return true;
+               }
+               return false;
+       }
+       
+       
+       
+       
+
+       
+       
+       public void setWorldCoord(boolean b) {
+               if (worldCoord == b)
+                       return;
+               worldCoord = b;
+               update();
+                                       
+       }
+       
+       
+       private void update() {
+               Vector3d nodePos = node.getWorldPosition();
+               System.out.println(nodePos);
+               gizmo.setPosition(nodePos);
+               if (worldCoord) {
+                       gizmo.setRotation(new AxisAngle4d());
+                       parentWorldOrientation = null;
+               } else {
+                       AxisAngle4d aa = new AxisAngle4d();
+                       parentWorldOrientation = ((IG3DNode)node.getParent()).getWorldOrientation();
+                       aa.set(parentWorldOrientation);
+                       gizmo.setRotation(aa);
+               }
+
+               Point3d camPos = new Point3d(panel.getRenderer().GetActiveCamera().GetPosition());
+               Vector3d p = new Vector3d(nodePos);
+               p.sub(camPos);
+               
+               if (parentWorldOrientation != null) {
+                       Quat4d qi = new Quat4d(parentWorldOrientation);
+                       qi.inverse();
+                       MathTools.rotate(parentWorldOrientation, p, p);
+               }
+               if (panel.getRenderer().GetActiveCamera().GetParallelProjection() == 0) {
+                       double distance = p.length();
+                       p.negate();
+            double fov = panel.getRenderer().GetActiveCamera().GetViewAngle();
+            float s = (float) (Math.sin(fov) * distance * 0.1); 
+
+            Vector3d scale = new Vector3d(1., 1., 1.);
+            
+//            if (p.x > 0.f)
+//                scale.x = -1.;
+//            if (p.y > 0.f)
+//                scale.y = -1.;
+//            if (p.z > 0.f)
+//                scale.z = -1.;
+            scale.scale(s);
+            gizmo.setScale(scale);
+                       
+               } else {
+                       Vector3d scale = new Vector3d(1.f, 1.f, 1.f);
+            double s = panel.getRenderer().GetActiveCamera().GetParallelScale() / 5.;
+//            if (p.x > 0.f)
+//                scale.x = -1.;
+//            if (p.y > 0.f)
+//                scale.y = -1.;
+//            if (p.z > 0.f)
+//                scale.z = -1.;
+            scale.scale(s);
+            gizmo.setScale(scale);
+               }
+               
+               panel.refresh();
+       }
+       
+       private boolean isOverNode(MouseEvent e) {
+               vtkProp picked[] = panel.pick(e.getX(), e.getY());
+               if (picked !=null) {
+                       for (int i = 0; i < picked.length; i++) {
+                               if (node.equals(nodeMap.getNode(picked[i])))
+                                       return true;
+                       }
+               }
+               return false;
+       }
+       
+
+       
+       @Override
+       public boolean mousePressed(MouseEvent e) {
+               if (e.getButton() == MouseEvent.BUTTON1) {
+       
+       
+                       if (isOverNode(e)) {
+                               valid = true;
+                               if ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0) {
+                                       useStep = true;
+                   } else {
+                       useStep = false;
+                   }
+                               worldOrientation = node.getWorldOrientation();
+                               doChanges(true, e.getX(), e.getY());
+                               
+                               panel.getComponent().setCursor(dragCursor);
+                       } else {
+                               valid = false;
+                               getDefaultAction().mousePressed(e);
+                               panel.getComponent().setCursor(activeCursor);
+                       }
+               } else {
+                       getDefaultAction().mousePressed(e);
+               }
+               return true;
+       }
+       
+       
+       
+       @Override
+       public boolean mouseReleased(MouseEvent e) {
+               if (e.getButton() == MouseEvent.BUTTON1) {
+                       valid = false;
+                       worldOrientation = null;
+                       panel.getComponent().setCursor(activeCursor);
+               } else {
+                       getDefaultAction().mouseReleased(e);
+               }
+               return true;
+       }
+       
+       @Override
+       public boolean mouseDragged(MouseEvent e) {
+               if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) > 0 && valid) { 
+                       if ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0) {
+                               useStep = true;
+            } else {
+                useStep = false;
+            }
+                       doChanges(false, e.getX(), e.getY());
+                       
+                       //nodeMap.modified(node);
+                       update();
+               } else {
+                       getDefaultAction().mouseDragged(e);
+                       update();
+               }
+               return true;
+       }
+       
+        Vector3d axis = null;
+       
+       @Override
+       public boolean keyTyped(KeyEvent e) {
+                if (e.getKeyCode() == KeyEvent.VK_LEFT) {
+               inputType = InputType.KEY;
+               axis = new Vector3d(0.0,1.0,0.0);
+            } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
+                       inputType = InputType.KEY;
+                       axis = new Vector3d(0.0,-1.0,0.0);
+            } else if (e.getKeyCode() ==KeyEvent.VK_UP) {
+                       inputType = InputType.KEY;
+                       axis = new Vector3d(1.0,0.0,0.0);
+            } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
+                       inputType = InputType.KEY;
+                       axis = new Vector3d(-1.0,0.0,0.0);
+            } 
+                return true;
+       }
+       
+    public void doChanges(boolean pressed, int x, int y) {
+       Ray ray = vtkUtil.createMouseRay(panel.getRenderer(),x, y);
+       Vector3d p = node.getWorldPosition();
+        
+       if (pressed) {
+            Vector3d axis = getRotationAxis();
+            if (axis != null) {
+               if (!worldCoord) {
+                       MathTools.rotate(parentWorldOrientation, axis, axis);
+               }
+
+               
+                double s[] = new double[2];
+                Vector3d i2 = new Vector3d();
+               
+                boolean intersect = MathTools.intersectStraightPlane(ray.pos, ray.dir, p, axis, i2, s);
+                double dot = Math.abs(ray.dir.dot(axis));
+                if (intersect &&  dot > 0.4)
+                       inputType = InputType.INTERSECT;
+                else
+                       inputType = InputType.NONINTERSECT;
+                       
+                
+                if (inputType == InputType.INTERSECT) {
+                    // picking ray and plane defined by gizmo's center point and
+                    // rotation axis can intersect
+                    // vector from center point to intersection point
+                    i2.sub(p);
+                    // creating vectors i and j that are lying on the plane and
+                    // are perpendicular
+                    // vectors are used to calculate polar coordinate for
+                    // intersection point
+                    j.set(i2);
+                    i.cross(j, axis);
+                    System.out.println("I,J " + i + " " + j);
+                    double angleI = i2.angle(i);
+                    double angleJ = i2.angle(j);
+                    prevAngle = Math.atan2(Math.cos(angleJ), Math.cos(angleI));
+                } else {
+                    // picking ray and plane defined by gizmo's center point and
+                    // rotation axis are parallel,
+                    // so we'll use cross product of rotation axis and picking
+                    // ray to detect amount of rotation
+                    i.cross(ray.dir, axis);
+                    MathTools.intersectStraightStraight(ray.pos, ray.dir, p, i, new Vector3d(), new Vector3d(), s);
+                    prevS = s[1];
+                }
+            }
+           
+            
+        }
+
+        if (inputType != InputType.KEY)
+               axis = getRotationAxis();
+        if (axis == null) {
+            return;   
+        }
+        Vector3d taxis = null;
+        if (!worldCoord) {
+               taxis = new Vector3d(axis);
+               MathTools.rotate(parentWorldOrientation, axis, axis);
+       }
+        System.out.println(inputType);
+        if (inputType == InputType.INTERSECT) {
+
+            double s[] = new double[2];
+            Vector3d i2 = new Vector3d();
+            MathTools.intersectStraightPlane(ray.pos, ray.dir, p, axis, i2, s);
+            i2.sub(p);
+            double angleI = i2.angle(i);
+            double angleJ = i2.angle(j);
+            double angle = Math.atan2(Math.cos(angleJ), Math.cos(angleI));
+            System.out.println("Angle " + angle + " i " + angleI + " j " + angleJ + " prev " + prevAngle);
+            if(!worldCoord)
+               axis = taxis;
+            if (useStep) {
+
+               //setOrientation(MathTools.getQuat(rotation));
+               AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);
+               Quat4d qrot = new Quat4d();
+               MathTools.getQuat(rot, qrot);
+               //prevAngle = angle;
+               qrot.mulInverse(worldOrientation);
+               
+          
+               if (stepMethod == 0) {
+                       rot.set(qrot);
+                       rot.angle = roundAngle(rot.angle);
+                       //qrot.set(rot);
+                       MathTools.getQuat(rot,qrot);
+                       setOrientation(qrot);
+               } else if (stepMethod == 1){
+                         
+                       //Vector3d euler = MathTools.getEuler(qrot);
+                       Vector3d euler = EulerTools.getEulerFromQuat(order, qrot);
+                       euler.x = roundAngle(euler.x);
+                       euler.y = roundAngle(euler.y);
+                       euler.z = roundAngle(euler.z);
+                       //Quat4d q = MathTools.getQuat(euler);
+                       Quat4d q = EulerTools.getQuatFromEuler(order, euler);
+                       setOrientation(q);
+                       System.out.println(" (" + MathTools.radToDeg(euler.x) + " " + MathTools.radToDeg(euler.y) + " " + MathTools.radToDeg(euler.z) +  ") " + qrot + " "+ q);
+               } else {
+                       setOrientation(qrot);
+               }
+               
+            } else {
+                if (worldCoord) {
+                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,angle-prevAngle));
+                       AxisAngle4d aa = MathTools.getAxisAngle(node.getWorldOrientation());
+                       AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);
+                       MathTools.multiplyOrientation(aa, rot);
+                       setWorldOrientation(MathTools.getQuat(rot));
+                } else {
+                       AxisAngle4d aa = MathTools.getAxisAngle(node.getOrientation());
+                       AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);
+                       MathTools.multiplyOrientation(aa, rot);
+                       setOrientation(MathTools.getQuat(rot));
+                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,angle-prevAngle));
+                }
+                prevAngle = angle;
+            }
+            
+        } else if (inputType == InputType.NONINTERSECT){
+
+            double s[] = new double[2];
+            MathTools.intersectStraightStraight(ray.pos, ray.dir, p, i, new Vector3d(), new Vector3d(), s);
+            if(!worldCoord)
+               axis = taxis;
+            if (useStep) {
+               //setOrientation(MathTools.getQuat(rotation));
+               AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);
+                
+               Quat4d qrot = new Quat4d();
+               //qrot.set(rot);
+               MathTools.getQuat(rot, qrot);
+               //prevAngle = angle;
+               qrot.mulInverse(worldOrientation);
+               
+          
+               if (stepMethod == 0) {
+                       rot.set(qrot);
+                       rot.angle = roundAngle(rot.angle);
+                       //qrot.set(rot);
+                       MathTools.getQuat(rot,qrot);
+                       setOrientation(qrot);
+               } else if (stepMethod == 1){
+                         
+                       //Vector3d euler = MathTools.getEuler(qrot);
+                       Vector3d euler = EulerTools.getEulerFromQuat(order, qrot);
+                       euler.x = roundAngle(euler.x);
+                       euler.y = roundAngle(euler.y);
+                       euler.z = roundAngle(euler.z);
+                       //Quat4d q = MathTools.getQuat(euler);
+                       Quat4d q = EulerTools.getQuatFromEuler(order, euler);
+                       setOrientation(q);
+                       System.out.println(" (" + MathTools.radToDeg(euler.x) + " " + MathTools.radToDeg(euler.y) + " " + MathTools.radToDeg(euler.z) +  ") " + qrot + " "+ q);
+               } else {
+                       setOrientation(qrot);
+               }
+                prevS = s[1];
+               
+//                    G3DTools.setOrientation(mo.getG3DNode(graph).getLocalOrientation(), rotations.get(mo));
+//                    G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,s[1] - prevS));
+//                    AxisAngle4d aa = G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation());
+//                    rotations.put(mo, aa);
+//                    Vector3d euler = MathTools.getEuler(aa);
+//                    euler.x = roundAngle(euler.x);
+//                    euler.y = roundAngle(euler.y);
+//                    euler.z = roundAngle(euler.z);
+//                    aa = MathTools.getFromEuler2(euler);
+//                    prevS = s[1];
+//                    G3DTools.setOrientation(mo.getG3DNode(graph).getLocalOrientation(), aa);
+//                    Vector3d e = MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()));
+//                    e.scale(180.0/Math.PI);
+//                    text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + e + " ";
+               
+               
+            } else {
+                       if (worldCoord) {
+                               AxisAngle4d aa =  MathTools.getAxisAngle(node.getWorldOrientation());
+                       AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);
+                       MathTools.multiplyOrientation(aa, rot);
+                       setWorldOrientation(MathTools.getQuat(rot));
+                               //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,s[1] - prevS));
+                       } else {
+                               AxisAngle4d aa =  MathTools.getAxisAngle(node.getOrientation());
+                       AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);
+                       MathTools.multiplyOrientation(aa, rot);
+                       setOrientation(MathTools.getQuat(rot));
+                               //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,s[1] - prevS));
+                       }
+                       //text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation())) + " ";
+                prevS = s[1];
+                
+            }
+           
+        } else {
+               if (worldCoord) {
+                       AxisAngle4d aa = MathTools.getAxisAngle(node.getWorldOrientation());
+               AxisAngle4d rot = new AxisAngle4d(axis,Math.PI * 0.5);
+               MathTools.multiplyOrientation(aa, rot);
+               setWorldOrientation(MathTools.getQuat(rot));
+                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,Math.PI * 0.5));
+               } else {
+                       AxisAngle4d aa = MathTools.getAxisAngle(node.getOrientation());
+               AxisAngle4d rot = new AxisAngle4d(axis,Math.PI * 0.5);
+               MathTools.multiplyOrientation(aa, rot);
+               setOrientation(MathTools.getQuat(rot));
+                       //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,Math.PI * 0.5));
+               }
+             //   text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation())) + " ";
+            
+        }
+        //setInfoText(text);
+    }
+    
+    protected void setOrientation(Quat4d q) {
+       node.setOrientation(q);
+    }
+    
+    protected void setWorldOrientation(Quat4d q) {
+       node.setWorldOrientation(q);
+    }
+       
+       @Override
+       public boolean mouseMoved(MouseEvent e) {
+               return getDefaultAction().mouseMoved(e);
+       }
+       
+       private Vector3d getRotationAxis() {
+               switch (index) {
+               case X:
+                       return new Vector3d(1.0, 0.0, 0.0);
+               case Y:
+                       return new Vector3d(0.0, 1.0, 0.0);
+               case Z:
+                       return new Vector3d(0.0, 0.0, 1.0);
+               case P:
+                       Vector3d axis = new Vector3d(panel.getRenderer().GetActiveCamera()
+                                       .GetDirectionOfProjection());
+                       axis.normalize();
+                       return axis;
+               default:
+                       return null;
+               }
+       }
+       
+        private double prevS = 0.0;
+           
+    private Vector3d i = new Vector3d();
+    private Vector3d j = new Vector3d();
+    private double prevAngle = 0;
+
+    enum InputType{INTERSECT,NONINTERSECT,KEY,NONE};
+    InputType inputType;
+    private boolean useStep = false;
+    
+    
+    
+    private double roundAngle(double angle) {
+        while (angle < - Math.PI)
+            angle += Math.PI*2.0;
+        while (angle > Math.PI)
+            angle -= Math.PI*2.0;
+        
+        
+        int index = 0;
+        while (angle > angles[index])
+            index++;
+        if (index == 0) {
+            angle = angles[0];
+        } else {
+            double d = angle - angles[index - 1];
+            double d2 = angles[index] - angle;
+            if (d < d2)
+                angle = angles[index - 1];
+            else
+                angle = angles[index];
+        }
+        return angle;
+    }
+       
+}
diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/TranslateAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/TranslateAction.java
new file mode 100644 (file)
index 0000000..32274f0
--- /dev/null
@@ -0,0 +1,479 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.swt;
+
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.math.BigDecimal;
+
+import javax.vecmath.AxisAngle4d;
+import javax.vecmath.Point3d;
+import javax.vecmath.Quat4d;
+import javax.vecmath.Vector3d;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.widgets.Display;
+import org.simantics.g3d.math.MathTools;
+import org.simantics.g3d.math.Ray;
+import org.simantics.g3d.scenegraph.IG3DNode;
+import org.simantics.g3d.scenegraph.structural.IStructuralNode;
+import org.simantics.g3d.vtk.Activator;
+import org.simantics.g3d.vtk.common.VTKNodeMap;
+import org.simantics.g3d.vtk.gizmo.TranslateAxisGizmo;
+import org.simantics.g3d.vtk.utils.vtkUtil;
+import org.simantics.utils.threads.AWTThread;
+import org.simantics.utils.threads.ThreadUtils;
+
+import vtk.vtkProp;
+
+public class TranslateAction extends vtkSwtAction{
+       
+       public static final int X = 0;
+    public static final int Y = 1;
+    public static final int Z = 2;
+    public static final int XY = 3;
+    public static final int XZ = 4;
+    public static final int YZ = 5;
+    public static final int P = 6;
+
+       private VTKNodeMap nodeMap;
+       //private TranslateGizmo  gizmo = new TranslateGizmo();
+       private TranslateAxisGizmo gizmo = new TranslateAxisGizmo();
+       protected IG3DNode node;
+       
+       
+       
+       private Cursor activeCursor;// = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
+       private Cursor dragCursor;// = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
+       
+       public void setNode(IG3DNode node) {
+               this.node = node;
+               if ((node instanceof IStructuralNode) && ((IStructuralNode)node).isPartOfInstantiatedModel() && !((IStructuralNode)node).isInstantiatedModelRoot()) {
+                       setEnabled(false);
+               } else {
+                       setEnabled(true);
+               }
+       }
+       
+       public IG3DNode getNode() {
+               return node;
+       }
+       
+       public TranslateAction(InteractiveVtkComposite panel, VTKNodeMap nodeMap) {
+               super(panel);
+               setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_out.png"));
+               setText("Translate");
+               this.nodeMap = nodeMap;
+               
+               activeCursor = Display.getCurrent().getSystemCursor(SWT.CURSOR_HAND);
+        dragCursor = Display.getCurrent().getSystemCursor(SWT.CURSOR_SIZEALL);
+       }
+       
+       public void attach() {
+               if (node == null)
+                       return;
+               
+               super.attach();
+               ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
+                       public void run() {
+                               attachUI();
+                               update();
+                       }
+               });
+               
+               
+               
+       }
+       
+       public void deattach() {
+               
+               node = null;
+               nodeMap.commit();
+               deattachUI();
+               super.deattach();
+               panel.refresh();
+       }
+       
+       private void attachUI() {
+               panel.getComponent().setCursor(activeCursor);
+               gizmo.attach(panel);
+       }
+       
+       private void deattachUI() {
+               panel.getComponent().setCursor(Display.getCurrent().getSystemCursor(SWT.CURSOR_ARROW));
+               gizmo.deattach();
+       }
+       
+       @Override
+       public boolean keyPressed(KeyEvent e) {
+               if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
+                       panel.useDefaultAction();
+               if (valid)
+                       return true;
+               if (e.getKeyCode() == KeyEvent.VK_X) {
+                       if (index != X)
+                               index = X;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_Y) {
+                       if (index != Y)
+                               index = Y;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_Z) {
+                       if (index != Z)
+                               index = Z;
+                       else
+                               index = P;
+               }
+               if (e.getKeyCode() == KeyEvent.VK_G) {
+                       worldCoord = !worldCoord;
+               }
+               gizmo.setType(index);
+               
+               update();
+               //panel.repaint();
+               return true;
+       }
+       
+
+       
+       @Override
+       public boolean mouseClicked(MouseEvent e) {
+               if (e.getClickCount() > 1) {
+                       if (isOverNode(e)) {
+                               return true;
+                       } else {
+                               panel.useDefaultAction();
+                       }
+                       //if(!gizmo.isPartOf(actor))
+                       //      panel.useDefaultAction();
+                       return true;
+               }
+               return false;
+       }
+       
+       private boolean isOverNode(MouseEvent e) {
+               vtkProp picked[] = panel.pick(e.getX(), e.getY());
+               if (picked !=null) {
+                       for (int i = 0; i < picked.length; i++) {
+                               if (node.equals(nodeMap.getNode(picked[i])))
+                                       return true;
+                       }
+               }
+               return false;
+       }
+       
+       
+       int index = P;
+       protected boolean valid = false;
+       private boolean worldCoord = true;
+       private AxisAngle4d aa = null;
+       private Quat4d q = null;
+       
+       
+       public void setWorldCoord(boolean b) {
+               if (worldCoord == b)
+                       return;
+               worldCoord = b;
+               update();
+                                       
+       }
+       
+       
+       protected void update() {
+               if (node == null)
+                       return;
+               if (worldCoord) {
+                       gizmo.setRotation(new AxisAngle4d());
+                       aa = null;
+                       q = null;
+               } else {
+                       aa = new AxisAngle4d();
+                       aa.set(((IG3DNode)node.getParent()).getWorldOrientation());
+                       gizmo.setRotation(aa);
+                       q = new Quat4d();
+                       MathTools.getQuat(aa, q);
+               }
+               
+               Vector3d nodePos = node.getWorldPosition();
+               //System.out.println(nodePos);
+               gizmo.setPosition(nodePos);
+
+               
+               Point3d camPos = new Point3d(panel.getRenderer().GetActiveCamera().GetPosition());
+               Vector3d p = new Vector3d(nodePos);
+               p.sub(camPos);
+               
+               if (q != null) {
+                       Quat4d qi = new Quat4d(q);
+                       qi.inverse();
+                       MathTools.rotate(q, p, p);
+               }
+               if (panel.getRenderer().GetActiveCamera().GetParallelProjection() == 0) {
+                       double distance = p.length();
+                       p.negate();
+            double fov = panel.getRenderer().GetActiveCamera().GetViewAngle();
+            float s = (float) (Math.sin(fov) * distance * 0.1); 
+
+            Vector3d scale = new Vector3d(1., 1., 1.);
+            
+//            if (p.x > 0.f)
+//                scale.x = -1.;
+//            if (p.y > 0.f)
+//                scale.y = -1.;
+//            if (p.z > 0.f)
+//                scale.z = -1.;
+            scale.scale(s);
+            gizmo.setScale(scale);
+                       
+               } else {
+                       Vector3d scale = new Vector3d(1.f, 1.f, 1.f);
+            double s = panel.getRenderer().GetActiveCamera().GetParallelScale() / 5.;
+//            if (p.x > 0.f)
+//                scale.x = -1.;
+//            if (p.y > 0.f)
+//                scale.y = -1.;
+//            if (p.z > 0.f)
+//                scale.z = -1.;
+            scale.scale(s);
+            gizmo.setScale(scale);
+               }
+               
+               //panel.Render();
+               panel.refresh();
+       }
+       
+       protected Vector3d prevTranslate = null;
+       
+       @Override
+       public boolean mousePressed(MouseEvent e) {
+               if (e.getButton() == MouseEvent.BUTTON1) {
+
+                       if (isOverNode(e)) {
+                               prevTranslate = getTranslate(e.getX(), e.getY());
+                               valid = true;
+                               panel.getComponent().setCursor(dragCursor);
+                       } else {
+                               valid = false;
+                               getDefaultAction().mousePressed(e);
+                               panel.getComponent().setCursor(activeCursor);
+                       }
+               } else {
+                       getDefaultAction().mousePressed(e);
+               }
+               return true;
+               //index = gizmo.getTranslateAxis(actor);
+               //if (index == -1) {
+               //  valid = false;
+               //      panel.getDefaultAction().mousePressed(e);
+               //      return;
+               //}
+               //valid = true; 
+               //prevTranslate = getTranslate(e.getX(), e.getY());
+               //System.out.println("start translate " + prevTranslate);
+       }
+       
+       
+       
+       @Override
+       public boolean mouseReleased(MouseEvent e) {
+               if (e.getButton() == MouseEvent.BUTTON1) {
+                       valid = false;
+                       prevTranslate = null;
+                       panel.getComponent().setCursor(activeCursor);
+               } else {
+                       getDefaultAction().mouseReleased(e);
+               }
+               return true;
+       }
+       
+       @Override
+       public boolean mouseDragged(MouseEvent e) {
+               if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) > 0 && valid) { 
+                       
+                       Vector3d translate = getTranslate(e.getX(), e.getY(), prevTranslate);
+                       //System.out.println("translate " + translate);
+                       if (translate == null)
+                               return true;
+                       boolean step = ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0);
+                       if (worldCoord) {
+                               Vector3d pos = new Vector3d(node.getWorldPosition());
+                               pos.add(translate);
+                               pos = constaints(pos, step);
+                               setWorldPos(pos);
+                       } else {
+                               Vector3d pos = new Vector3d(node.getPosition());
+                               pos.add(translate);
+                               pos = constaints(pos, step);
+                               setPos(pos);
+                       }
+                       //mapping.rangeModified(node);
+                       
+                       //nodeMap.modified(node);
+                       update();
+               } else {
+                       getDefaultAction().mouseDragged(e);
+                       update();
+               }
+               return true;
+       }
+       
+       protected void setPos(Vector3d pos) {
+               node.setPosition(pos);
+       }
+       
+       protected void setWorldPos(Vector3d pos) {
+               node.setWorldPosition(pos);
+       }
+       
+        private double istep = 10.0;
+        private int decimals = 2;
+       
+       protected Vector3d constaints(Vector3d p, boolean step) {
+               if(!step)
+                       return p;
+               switch (index) {
+               case X:
+                        p.x = Math.round(istep * p.x) / istep;
+             BigDecimal bx = new BigDecimal(p.x);
+             bx.setScale(decimals, BigDecimal.ROUND_HALF_UP);
+             p.x = bx.doubleValue();
+                       break;
+               case Y:
+                        p.y = Math.round(istep * p.y) / istep;
+             BigDecimal by = new BigDecimal(p.y);
+             by.setScale(decimals, BigDecimal.ROUND_HALF_UP);
+             p.y = by.doubleValue();
+                       break;
+                       
+               case Z:
+                        p.z = Math.round(istep * p.z) / istep;
+             BigDecimal bz = new BigDecimal(p.z);
+             bz.setScale(decimals, BigDecimal.ROUND_HALF_UP);
+             p.z = bz.doubleValue();
+                       break;
+               }
+               return p;
+       }
+       
+       @Override
+       public boolean mouseMoved(MouseEvent e) {
+               getDefaultAction().mouseMoved(e);
+               return true;
+       }
+       
+       protected Vector3d getTranslate(double x, double y) {
+               return getTranslate(x, y, new Vector3d());
+       }
+       
+       protected Vector3d getTranslate(double x, double y, Vector3d offset) {
+               Vector3d translate = new Vector3d();
+               
+               Ray ray = vtkUtil.createMouseRay(panel.getRenderer(),x, y);
+               
+               Vector3d p = node.getWorldPosition();
+               Vector3d dir = null;
+               
+               switch (index) {
+               case P:
+                       Vector3d normal = new Vector3d(panel.getRenderer().GetActiveCamera().GetDirectionOfProjection());
+                       if (!worldCoord) {
+                               MathTools.rotate(q, normal, normal);
+                       }
+                       normal.normalize();
+                       double s[] = new double[1];
+            Vector3d r = new Vector3d();
+            if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
+                r.sub(p);
+                translate.x = r.x;
+                translate.y = r.y;
+                translate.z = r.z;
+            }
+            break;
+
+                case X :
+                   dir = new Vector3d(1.0,0.0,0.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, dir, dir);
+                   Vector3d i1 = new Vector3d();
+                   Vector3d i2 = new Vector3d();
+                   s = new double[2];
+                   MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);
+                   translate.x = s[0];
+                   
+                   break;
+               case Y :
+                   dir = new Vector3d(0.0,1.0,0.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, dir, dir);
+                   i1 = new Vector3d();
+                   i2 = new Vector3d();
+                   s = new double[2];
+                   MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);
+                   translate.y = s[0];
+                   break;
+               case Z :
+                   dir = new Vector3d(0.0,0.0,1.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, dir, dir);
+                   i1 = new Vector3d();
+                   i2 = new Vector3d();
+                   s = new double[2];
+                   MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);
+                   translate.z = s[0];
+                   break;
+               case XY :
+                   normal = new Vector3d(0.0,0.0,1.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, normal, normal);
+                   r = new Vector3d();
+                   if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
+                       r.sub(p);
+                       translate.x = r.x;
+                       translate.y = r.y;
+                   }
+                   break;
+               case XZ :
+                   normal = new Vector3d(0.0,1.0,0.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, normal, normal);
+                   r = new Vector3d();
+                   if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
+                       r.sub(p);
+                       translate.x = r.x;
+                       translate.z = r.z;
+                   }
+                   break;
+               case YZ :
+                   normal = new Vector3d(1.0,0.0,0.0);
+                   if(!worldCoord)
+                       MathTools.rotate(q, normal, normal);
+                   r = new Vector3d();
+                   if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
+                       r.sub(p);
+                       translate.y = r.y;
+                       translate.z = r.z;
+                   }
+                   break;
+               default :
+                   
+                   return null;
+               }
+               translate.sub(offset);
+               return translate;
+       }
+       
+}
diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java
new file mode 100644 (file)
index 0000000..5b3e3a1
--- /dev/null
@@ -0,0 +1,399 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.vtk.swt;
+
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.widgets.Display;
+import org.simantics.g3d.tools.AdaptationUtils;
+
+import vtk.vtkCamera;
+import vtk.vtkProp;
+import vtk.vtkRenderWindow;
+import vtk.vtkRenderer;
+
+public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelectionProvider {
+       
+       protected vtkRenderer ren;
+       protected int lastX;
+       protected int lastY;
+       protected vtkRenderWindow rw;
+       protected vtkCamera cam;
+       protected int InteractionMode = 1;
+       
+       protected double activeRate = 5.0;
+       protected double passiveRate = 0.01;
+       protected boolean doNotRotate = true; 
+       
+       public vtkCameraAndSelectorAction(InteractiveVtkComposite panel) {
+               super(panel);
+               this.ren = panel.getRenderer();
+               this.rw = panel.getRenderWindow();
+               this.cam = ren.GetActiveCamera();
+       }
+       
+       public void Lock() {
+               panel.lock();
+       }
+       
+       public void UnLock() {
+               panel.unlock();
+       }
+       
+       public void InteractionModeRotate()
+         {
+           this.InteractionMode = 1;
+         }
+         
+         public void InteractionModeTranslate()
+         {
+           this.InteractionMode = 2;
+         }
+         
+         public void InteractionModeZoom()
+         {
+           this.InteractionMode = 3;
+         }
+         
+       public void resetCameraClippingRange() {
+           Lock();
+           ren.ResetCameraClippingRange();
+           UnLock();
+         }
+
+         public void resetCamera() {
+           Lock();
+           ren.ResetCamera();
+           UnLock();
+         }
+         
+        public boolean mousePressed(MouseEvent e)
+         {
+             
+           if (ren.VisibleActorCount() == 0) return false;
+           rw.SetDesiredUpdateRate(activeRate);
+           lastX = e.getX();
+           lastY = e.getY();
+           if ((e.getModifiers()==InputEvent.BUTTON2_MASK) ||
+               (e.getModifiers()==(InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK)))
+             {
+               InteractionModeTranslate();
+             }
+           else if (e.getModifiers()==InputEvent.BUTTON3_MASK)
+             {
+               InteractionModeZoom();
+             }
+           else 
+             {
+               InteractionModeRotate();
+             }
+           return true;
+         }
+        
+        public boolean mouseReleased(MouseEvent e)
+         {
+           rw.SetDesiredUpdateRate(passiveRate);
+           return true;
+         }
+        
+
+        
+        public boolean mouseDragged(MouseEvent e)
+         {
+           if (ren.VisibleActorCount() == 0) return false;
+           int x = e.getX();
+           int y = e.getY();
+           // rotate
+           if (this.InteractionMode == 1)
+             {
+               cam.Azimuth(lastX - x);
+               cam.Elevation(y - lastY);
+               if (doNotRotate)
+                       cam.SetRoll(0);
+               cam.OrthogonalizeViewUp();
+               resetCameraClippingRange();
+               //panel.UpdateLight();
+             }
+           // translate
+           if (this.InteractionMode == 2)
+             {
+               double  FPoint[];
+               double  PPoint[];
+               double  APoint[] = new double[3];
+               double  RPoint[];
+               double focalDepth;
+               
+               // get the current focal point and position
+               FPoint = cam.GetFocalPoint();
+               PPoint = cam.GetPosition();
+               
+               // calculate the focal depth since we'll be using it a lot
+               ren.SetWorldPoint(FPoint[0],FPoint[1],FPoint[2],1.0);
+               ren.WorldToDisplay();
+               focalDepth = ren.GetDisplayPoint()[2];
+               
+               APoint[0] = rw.GetSize()[0]/2.0 + (x - lastX);
+               APoint[1] = rw.GetSize()[1]/2.0 - (y - lastY);
+               APoint[2] = focalDepth;
+               ren.SetDisplayPoint(APoint);
+               ren.DisplayToWorld();
+               RPoint = ren.GetWorldPoint();
+               if (RPoint[3] != 0.0)
+                 {
+                   RPoint[0] = RPoint[0]/RPoint[3];
+                   RPoint[1] = RPoint[1]/RPoint[3];
+                   RPoint[2] = RPoint[2]/RPoint[3];
+                 }
+               
+               /*
+                * Compute a translation vector, moving everything 1/2 
+                * the distance to the cursor. (Arbitrary scale factor)
+                */
+               cam.SetFocalPoint(
+                                 (FPoint[0]-RPoint[0])/2.0 + FPoint[0],
+                                 (FPoint[1]-RPoint[1])/2.0 + FPoint[1],
+                                 (FPoint[2]-RPoint[2])/2.0 + FPoint[2]);
+               cam.SetPosition(
+                               (FPoint[0]-RPoint[0])/2.0 + PPoint[0],
+                               (FPoint[1]-RPoint[1])/2.0 + PPoint[1],
+                               (FPoint[2]-RPoint[2])/2.0 + PPoint[2]);
+               resetCameraClippingRange();
+             }
+           // zoom
+           if (this.InteractionMode == 3)
+             {
+               double zoomFactor;
+               //double clippingRange[];
+               
+               zoomFactor = Math.pow(1.02,(y - lastY));
+               if (cam.GetParallelProjection() == 1)
+                 {
+                   cam.SetParallelScale(cam.GetParallelScale()/zoomFactor);
+                 }
+               else
+                 {
+                   cam.Dolly(zoomFactor);
+                   resetCameraClippingRange();
+                 }
+             }
+           lastX = x;
+           lastY = y;
+           panel.refresh();
+           return true;
+         }
+
+        
+               private List<vtkProp> selectActors = new ArrayList<vtkProp>();
+               private List<vtkProp> hoverActor = new ArrayList<vtkProp>();
+        
+               @Override
+               public boolean mouseClicked(MouseEvent e) {
+                       if (!panel.getComponent().isFocusControl())
+                               return false;
+                       if (e.getButton() != MouseEvent.BUTTON1)
+                               return false;
+                       vtkProp spick[] = panel.pick(e.getX(), e.getY());
+                       if (spick != null && spick.length > 0) {
+                               for (vtkProp selectActor : spick) {
+                                       if (!e.isControlDown()) {
+                                               selectActors.clear();
+                                               selectActors.add(selectActor);
+                                       } else {
+                                               if (selectActors.contains(selectActor))
+                                                       selectActors.remove(selectActor);
+                                               else
+                                                       selectActors.add(selectActor);
+                                       }
+                               }
+                               fireSelectionChanged();
+                       } else if (!e.isControlDown()) {
+                               selectActors.clear();
+                               fireSelectionChanged();
+                       }
+                       return true;
+//                     if (e.getClickCount() > 1)
+//                             updatePickRay(e.getX(), e.getY());
+                       
+               }
+               
+//             private void updatePickRay(double x , double y) {
+//                     Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(), x, y);
+//                     
+//                     
+//                     System.out.println(ray.pos + " " + ray.dir);
+//                     vtkPoints linePoints = new vtkPoints();
+//                     linePoints.InsertPoint(0,ray.pos.x, ray.pos.y, ray.pos.z);
+//                     linePoints.InsertPoint(1, ray.pos.x + ray.dir.x, ray.pos.y + ray.dir.y, ray.pos.z + ray.dir.z);
+//                     vtkLine aLine = new vtkLine();
+//                     aLine.GetPointIds().SetId(0, 0);
+//                     aLine.GetPointIds().SetId(1, 1);
+//                     vtkUnstructuredGrid aLineGrid = new vtkUnstructuredGrid();
+//                     aLineGrid.Allocate(1, 1);
+//                     aLineGrid.InsertNextCell(aLine.GetCellType(), aLine.GetPointIds());
+//                     aLineGrid.SetPoints(linePoints);
+//                     vtkDataSetMapper aLineMapper = new vtkDataSetMapper();
+//                     aLineMapper.SetInput(aLineGrid);
+//                     vtkActor aLineActor = new vtkActor();
+//                     aLineActor.SetMapper(aLineMapper);
+//                     aLineActor.GetProperty().SetDiffuseColor(.2, 1, 1);
+//                     
+//                 if (rayActor != null) {
+//                     panel.GetRenderer().RemoveActor(rayActor);
+//                     rayActor.Delete();
+//                 }
+//                 rayActor = aLineActor;
+//                 panel.GetRenderer().AddActor(rayActor);
+//                 
+//                 linePoints.Delete();
+//                 aLine.Delete();
+//                 aLineGrid.Delete();
+//                 aLineMapper.Delete();
+//                 panel.repaint();
+//             }
+//             
+//             private vtkActor rayActor;
+               
+               @Override
+               public boolean mouseMoved(MouseEvent e) {
+                       lastX = e.getX();
+                   lastY = e.getY();
+                   
+                   if (!panel.getComponent().isFocusControl())
+                               return false;
+                       List<vtkProp> prevHover = new ArrayList<vtkProp>();
+                       prevHover.addAll(hoverActor);
+                       hoverActor.clear();
+                       vtkProp pick[] =  panel.pick(e.getX(),e.getY());
+                       if (pick != null) {
+                               for (vtkProp p : pick)
+                                       hoverActor.add(p);
+                       }
+                               
+                       if (!prevHover.containsAll(hoverActor) || !hoverActor.containsAll(prevHover)) {
+                               fireHoverChanged();
+                       }
+                       return true;
+               }
+               
+               public List<vtkProp> getSelectActor() {
+                       return selectActors;
+               }
+               
+               public List<vtkProp> getHoverActor() {
+                       return hoverActor;
+               }
+               
+               private List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();
+                
+               @Override
+               public void addSelectionChangedListener(ISelectionChangedListener listener) {
+                       selectionListeners.add(listener);
+               }
+               
+               @Override
+               public ISelection getSelection() {
+                       return new StructuredSelection(selectActors);
+               }
+               
+               @Override
+               public void removeSelectionChangedListener(
+                               ISelectionChangedListener listener) {
+                       selectionListeners.remove(listener);
+               }
+               
+               @Override
+               public void setSelection(ISelection selection) {
+                       setSelection(selection, false);
+
+               }
+               
+               public void setSelection(ISelection selection, boolean fire) {
+                       Collection<vtkProp> selectedProps = AdaptationUtils.adaptToCollection(selection, vtkProp.class);
+                       
+                       selectActors.clear();
+                       selectActors.addAll(selectedProps);
+                       if (fire)
+                               fireSelectionChanged();
+               }
+               
+               private void fireSelectionChanged() {
+                       Display.getDefault().asyncExec(new Runnable() {
+                               @Override
+                               public void run() {
+                                       
+                                       SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, new StructuredSelection(selectActors));
+                                       for (ISelectionChangedListener l :selectionListeners) {
+                                               l.selectionChanged(evt);
+                                       }
+                                       
+                               }
+                       });
+               }
+               
+               
+               private List<ISelectionChangedListener> hoverListeners = new ArrayList<ISelectionChangedListener>();
+                
+       
+               public void addHoverChangedListener(ISelectionChangedListener listener) {
+                       hoverListeners.add(listener);
+               }
+               
+               
+               public ISelection getHoverSelection() {
+                       return new StructuredSelection(hoverActor);
+               }
+               
+               public void removeHoverChangedListener(
+                               ISelectionChangedListener listener) {
+                       hoverListeners.remove(listener);
+               }
+
+               private void fireHoverChanged() {
+                       Display.getDefault().asyncExec(new Runnable() {
+                               @Override
+                               public void run() {
+                                       StructuredSelection sel = null;
+                                       if (hoverActor == null)
+                                               sel = new StructuredSelection();
+                                       else
+                                               sel = new StructuredSelection(hoverActor);
+                                       SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, sel);
+                                       for (ISelectionChangedListener l :hoverListeners) {
+                                               l.selectionChanged(evt);
+                                       }
+                                       
+                               }
+                       });
+               }
+               
+               public void focus(double x, double y, double z) {
+                       Lock();
+                       cam.SetFocalPoint(x, y, z);
+                       if (doNotRotate)
+                       cam.SetRoll(0);
+               cam.OrthogonalizeViewUp();
+               resetCameraClippingRange();
+               //panel.UpdateLight();
+                       UnLock();
+               }
+               
+               
+}
diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkSwtAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkSwtAction.java
new file mode 100644 (file)
index 0000000..9d4332c
--- /dev/null
@@ -0,0 +1,105 @@
+package org.simantics.g3d.vtk.swt;
+
+import java.awt.event.MouseWheelEvent;
+
+import org.simantics.g3d.vtk.action.vtkAction;
+
+import vtk.rendering.vtkEventInterceptor;
+
+public class vtkSwtAction extends vtkAction implements vtkEventInterceptor{
+       
+       protected InteractiveVtkComposite panel;
+       
+       public vtkSwtAction(InteractiveVtkComposite panel) {
+               this.panel = panel;
+       }
+       
+       @Override
+       public void run() {
+               panel.setActiveAction(this);
+       }
+       
+       @Override
+       public void attach() {
+               panel.getInteractorForwarder().setEventInterceptor(this);
+       }
+       
+       @Override
+       public void deattach() {
+               if (panel.getInteractorForwarder().getEventInterceptor() == this)
+                       panel.getInteractorForwarder().setEventInterceptor(null);
+       }
+       
+       protected vtkSwtAction getDefaultAction() {
+               return (vtkSwtAction)panel.getDefaultAction();
+       }
+
+       @Override
+       public boolean keyPressed(java.awt.event.KeyEvent e) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean keyReleased(java.awt.event.KeyEvent e) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean keyTyped(java.awt.event.KeyEvent e) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean mouseDragged(java.awt.event.MouseEvent e) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean mouseMoved(java.awt.event.MouseEvent e) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean mouseClicked(java.awt.event.MouseEvent e) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean mouseEntered(java.awt.event.MouseEvent e) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean mouseExited(java.awt.event.MouseEvent e) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean mousePressed(java.awt.event.MouseEvent e) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean mouseReleased(java.awt.event.MouseEvent e) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       @Override
+       public boolean mouseWheelMoved(MouseWheelEvent e) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+       
+       
+
+}
index ed1a503a92b7ef6a1bbb5dcb0f07fcec511dbd43..13ffac0838534fc6cbdbefb9b9874b00fb23f787 100644 (file)
@@ -1,6 +1,6 @@
 package org.simantics.g3d.vtk.utils;
 
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
+import org.simantics.g3d.vtk.common.VtkView;
 
 import vtk.vtkAxesActor;
 import vtk.vtkOrientationMarkerWidget;
@@ -8,9 +8,9 @@ import vtk.vtkOrientationMarkerWidget;
 public class AxesDisplay {
        
        
-       private InteractiveVtkPanel panel;
+       private VtkView panel;
        
-       public AxesDisplay(InteractiveVtkPanel panel) {
+       public AxesDisplay(VtkView panel) {
                this.panel = panel;
        }
        
index f207dc56a5be4dcaa34d48cd67ce81374d667fe7..9b9b072758f45f56688853df9ccb34413456b055 100644 (file)
@@ -1,28 +1,28 @@
-/*******************************************************************************\r
- * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.g3d.gizmo;\r
-\r
-import javax.vecmath.AxisAngle4d;\r
-import javax.vecmath.Tuple3d;\r
-\r
-public interface Gizmo<T> {\r
-       \r
-       \r
-       public boolean isPartOf(T pickedObject);\r
-       \r
-       \r
-       public void attach(Object renderingPart);\r
-       public void deattach();\r
-       \r
-        public void setPosition(Tuple3d position);\r
-        public void setRotation(AxisAngle4d q);\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g3d.gizmo;
+
+import javax.vecmath.AxisAngle4d;
+import javax.vecmath.Tuple3d;
+
+public interface Gizmo<T,T2> {
+       
+       
+       public boolean isPartOf(T pickedObject);
+       
+       
+       public void attach(T2 renderingPart);
+       public void deattach();
+       
+        public void setPosition(Tuple3d position);
+        public void setRotation(AxisAngle4d q);
+}
index f5db540e81640a7082853e538e7aee28410219f8..c3d7376fd87af9af1fef64c6066b893d48671fdb 100644 (file)
@@ -673,6 +673,8 @@ public class AnnotatedPropertyTabContributorFactory implements PropertyTabContri
 //                             }
 //                     }
                        if (Thread.currentThread() == Display.getDefault().getThread()) {
+                               if (viewer.getTable().isDisposed())
+                                       return;
                                if (DEBUG)System.out.println("Viewer refresh " + id);
                                for (PropertyItem item : resolvedItems)
                                        if (!item.equals(selectedItem))
index f9a953f926b83644aa451e7cb3e8888679203bee..9297e52d95cbdcddb842f2a9ea4cd8c7e714a6ff 100644 (file)
@@ -11,7 +11,8 @@ Require-Bundle: org.eclipse.ui,
  org.simantics.opencascade;bundle-version="1.0.0",
  vtk;bundle-version="5.8.0",
  javax.vecmath;bundle-version="1.5.2",
- org.simantics.utils.datastructures;bundle-version="1.1.0"
+ org.simantics.utils.datastructures;bundle-version="1.1.0",
+ org.simantics.g3d.vtk;bundle-version="1.0.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Export-Package: org.simantics.opencascade.vtk
index f2501e95d7fe659965b9421608a30db44e9feee2..797c9ae23298d6fb796be43cd0058a3e3f6be069 100644 (file)
@@ -20,9 +20,9 @@ import org.jcae.opencascade.jni.TopAbs_ShapeEnum;
 import org.jcae.opencascade.jni.TopExp_Explorer;
 import org.jcae.opencascade.jni.TopoDS_Face;
 import org.jcae.opencascade.jni.TopoDS_Shape;
+import org.simantics.g3d.vtk.common.VtkView;
 import org.simantics.opencascade.OCCTTool;
 import org.simantics.utils.datastructures.Pair;
-import org.simantics.utils.threads.AWTThread;
 import org.simantics.utils.threads.ThreadUtils;
 
 import vtk.vtkActor;
@@ -31,7 +31,6 @@ import vtk.vtkCleanPolyData;
 import vtk.vtkDataSetMapper;
 import vtk.vtkFeatureEdges;
 import vtk.vtkGlyph3D;
-import vtk.vtkPanel;
 import vtk.vtkPolyData;
 import vtk.vtkPolyDataMapper;
 import vtk.vtkPolyDataNormals;
@@ -50,7 +49,7 @@ public class vtkSolidObject {
        public static boolean cleanPart = false;
        public static boolean mergePoints = false;
        
-       private vtkPanel panel;
+       private VtkView panel;
        private TopoDS_Shape shape;
        
        private List<vtkProp3D> actors = new ArrayList<vtkProp3D>(2);
@@ -61,7 +60,7 @@ public class vtkSolidObject {
        
        private boolean errors = false;
        
-       public vtkSolidObject(vtkPanel panel,TopoDS_Shape shape) {
+       public vtkSolidObject(VtkView panel,TopoDS_Shape shape) {
                this.shape = shape;
                this.panel = panel;
        }
@@ -75,7 +74,7 @@ public class vtkSolidObject {
        }
        
        public void visualizeSolid(boolean showFaces, boolean showEdges, boolean showVertices, boolean showSilhouette) {
-               clearActorsAWT();
+               clearActorsVTK();
                errors = false;
                Pair<vtkPolyData, Boolean> res = createSolidMesh(shape);
                if (res == null) {
@@ -96,19 +95,19 @@ public class vtkSolidObject {
                        }
                }
                if (showSilhouette) {
-                       silhouette = createSilhouette(panel.GetRenderer(), data);
+                       silhouette = createSilhouette(panel.getRenderer(), data);
                }
                actors.addAll(solid);
                actors.addAll(edges);
                if (silhouette != null)
                        actors.add(silhouette);
                data.Delete();
-               showActorsAWT();
+               showActorsVTK();
        }
        
        public void visualizeFaces(boolean showEdges, boolean showVertices) {
                errors = false;
-               clearActorsAWT();
+               clearActorsVTK();
                Collection<vtkPolyData> datas = createFaceMeshes(shape);
                for (vtkPolyData data : datas) {
                        if (data == null) {
@@ -130,7 +129,7 @@ public class vtkSolidObject {
                actors.addAll(solid);
                actors.addAll(edges);
                
-               showActorsAWT();
+               showActorsVTK();
        }
        
        public boolean hasErrors() {
@@ -138,48 +137,50 @@ public class vtkSolidObject {
        }
        
        public List<vtkProp3D> getActors() {
-               assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread());
+               assert (Thread.currentThread() == panel.getThreadQueue().getThread());
                return actors;
        }
        
        public List<vtkProp3D> getSolid() {
-               assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread());
+               assert (Thread.currentThread() == panel.getThreadQueue().getThread());
                return solid;
        }
        
        public List<vtkProp3D> getEdges() {
-               assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread());
+               assert (Thread.currentThread() == panel.getThreadQueue().getThread());
                return edges;
        }
        
        public vtkActor getSilhouette() {
-               assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread());
+               assert (Thread.currentThread() == panel.getThreadQueue().getThread());
                return silhouette;
        }
        
-       public void showActorsAWT() {
-               assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread());
-               vtkRenderer ren = panel.GetRenderer();
+       public void showActorsVTK() {
+               assert (Thread.currentThread() == panel.getThreadQueue().getThread());
+               panel.lock();
+               vtkRenderer ren = panel.getRenderer();
                for (vtkProp3D act : actors) {
                        ren.AddActor(act);
                }
+               panel.unlock();
        }
        
        public void showActors() {
-               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+               ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
                        
                        @Override
                        public void run() {
-                               showActorsAWT();
+                               showActorsVTK();
                        }
                });
        }
        
-       public void clearActorsAWT() {
-               assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread());
+       public void clearActorsVTK() {
+               assert (Thread.currentThread() == panel.getThreadQueue().getThread());
                if (actors.size() == 0)
                        return;
-               vtkRenderer ren = panel.GetRenderer();
+               vtkRenderer ren = panel.getRenderer();
                if (ren == null)
                        return;
                panel.lock();
@@ -196,11 +197,11 @@ public class vtkSolidObject {
        }
        
        private void clearActorsAWT(List<vtkProp3D> actors) {
-               assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread());
+               assert (Thread.currentThread() == panel.getThreadQueue().getThread());
                
                if (actors.size() == 0)
                        return;
-               vtkRenderer ren = panel.GetRenderer();
+               vtkRenderer ren = panel.getRenderer();
                if (ren == null)
                        return;
                panel.lock();
@@ -221,7 +222,7 @@ public class vtkSolidObject {
                actors.clear();
                solid.clear();
                edges.clear();
-               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+               ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
                        
                        @Override
                        public void run() {
@@ -243,7 +244,7 @@ public class vtkSolidObject {
                        shape.delete();
                        shape = null;
                }
-               clearActorsAWT();
+               clearActorsVTK();
        }
        
        private static double TOLERANCE = 0.01;
index 2b216e01d690417c259e95bd43bac3efa1221380..d8f33c72d979bd46b85cb54c354b34f295058fbe 100644 (file)
@@ -20,6 +20,7 @@ Require-Bundle: org.eclipse.core.runtime,
  org.simantics.selectionview.ontology;bundle-version="1.0.0",
  org.simantics.browsing.ui.swt;bundle-version="1.1.0",
  vtk;bundle-version="5.8.0",
+ vtk.rendering;bundle-version="8.2.0",
  org.simantics.g3d.vtk;bundle-version="1.0.0",
  javax.vecmath;bundle-version="1.5.2",
  org.eclipse.ui.views;bundle-version="3.5.1",
@@ -32,7 +33,8 @@ Require-Bundle: org.eclipse.core.runtime,
  org.simantics.opencascade.vtk;bundle-version="1.0.0",
  org.simantics.browsing.ui.platform;bundle-version="1.1.0",
  org.simantics.structural.ui;bundle-version="1.1.1",
- org.simantics.g3d.csg;bundle-version="1.0.0"
+ org.simantics.g3d.csg;bundle-version="1.0.0",
+ org.simantics.utils.thread.swt;bundle-version="1.1.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Export-Package: org.simantics.plant3d.editor,
index 4c116c1f26efb73d9453e850e299a43cb89992f9..5aaa9c71d646c1e5d4499e6ae71b323407edb3ca 100644 (file)
@@ -10,8 +10,8 @@ import javax.vecmath.Vector3d;
 import org.eclipse.swt.widgets.Display;
 import org.simantics.g3d.scenegraph.NodeMap;
 import org.simantics.g3d.scenegraph.base.INode;
-import org.simantics.g3d.vtk.action.vtkAction;
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
+import org.simantics.g3d.vtk.swt.InteractiveVtkComposite;
+import org.simantics.g3d.vtk.swt.vtkSwtAction;
 import org.simantics.plant3d.Activator;
 import org.simantics.plant3d.dialog.ComponentSelectionDialog;
 import org.simantics.plant3d.gizmo.TerminalSelectionGizmo;
@@ -26,13 +26,12 @@ import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
 import org.simantics.plant3d.utils.ComponentUtils;
 import org.simantics.plant3d.utils.Item;
 import org.simantics.plant3d.utils.Item.Type;
-import org.simantics.utils.threads.AWTThread;
 import org.simantics.utils.threads.ThreadUtils;
 import org.simantics.utils.ui.ExceptionUtils;
 
 import vtk.vtkProp;
 
-public class AddComponentAction extends vtkAction {
+public class AddComponentAction extends vtkSwtAction {
        
 
        private P3DRootNode root;
@@ -45,7 +44,7 @@ public class AddComponentAction extends vtkAction {
        
        private Item toAdd = null;
        
-       public AddComponentAction(InteractiveVtkPanel panel, P3DRootNode root) {
+       public AddComponentAction(InteractiveVtkComposite panel, P3DRootNode root) {
                super(panel);
                this.root = root;
                setText("Add Component");
@@ -90,14 +89,14 @@ public class AddComponentAction extends vtkAction {
                allowed = dialog.filterAllowed();
                gizmo.setComponent(component, allowed);
                super.run();
-               panel.repaint();
+               panel.refresh();
        }
        
        @Override
-       public void keyPressed(KeyEvent e) {
+       public boolean keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
                        panel.useDefaultAction();
-               
+               return true;
                
        }
        
@@ -106,7 +105,7 @@ public class AddComponentAction extends vtkAction {
                        return;
                
                super.attach();
-               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+               ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
                        public void run() {
                                attachUI();
                        }
@@ -120,12 +119,12 @@ public class AddComponentAction extends vtkAction {
                nodeMap.commit();
                deattachUI();
                super.deattach();
-               panel.repaint();
+               panel.refresh();
        }
        
        private void attachUI() {
                //panel.setCursor(activeCursor);
-               gizmo.attach(panel.GetRenderer());
+               gizmo.attach(panel);
        }
        
        private void deattachUI() {
@@ -134,23 +133,23 @@ public class AddComponentAction extends vtkAction {
        }
        
        @Override
-       public void mouseMoved(MouseEvent e) {
-               panel.getDefaultAction().mouseMoved(e);
+       public boolean mouseMoved(MouseEvent e) {
+               return getDefaultAction().mouseMoved(e);
        }
        
        @Override
-       public void mousePressed(MouseEvent e) {
-               panel.getDefaultAction().mousePressed(e);
+       public boolean mousePressed(MouseEvent e) {
+               return getDefaultAction().mousePressed(e);
        }
 
        @Override
-       public void mouseReleased(MouseEvent e) {
-               panel.getDefaultAction().mouseReleased(e);
+       public boolean mouseReleased(MouseEvent e) {
+               return getDefaultAction().mouseReleased(e);
        }
        
        @Override
-       public void mouseDragged(MouseEvent e) {
-               panel.getDefaultAction().mouseDragged(e);
+       public boolean mouseDragged(MouseEvent e) {
+               return getDefaultAction().mouseDragged(e);
        }
        
        public void doInsert(PositionType position) {
@@ -253,19 +252,21 @@ public class AddComponentAction extends vtkAction {
                }
        }
        
-       public void mouseClicked(MouseEvent e) {
+       public boolean mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1) {
                        int type = panel.getPickType();
-                       panel.setPickType(0);
+                       //panel.setPickType(0);
+                       panel.setPickType(5);
                        vtkProp[] picked = panel.pick(e.getX(), e.getY());
                        panel.setPickType(type);
                        PositionType position = gizmo.getPickedPosition(picked);
+
                        if (position != null) {
                                doInsert(position);
                                panel.useDefaultAction();
-                               return;
+                               return true;
                        }
                } 
-               panel.getDefaultAction().mouseClicked(e);
+               return getDefaultAction().mouseClicked(e);
        }
 }
index 0310311dacecbcc254a71237e82fb22bceb977ef..da7beb45a2069470f6afc96af8b17e44693ebd58 100644 (file)
@@ -18,9 +18,9 @@ import org.simantics.g3d.scenegraph.NodeMap;
 import org.simantics.g3d.scenegraph.base.INode;
 import org.simantics.g3d.tools.ConstraintDetector;
 import org.simantics.g3d.tools.DummyConstraintDetector;
-import org.simantics.g3d.vtk.action.vtkAction;
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
 import org.simantics.g3d.vtk.gizmo.TranslateAxisGizmo;
+import org.simantics.g3d.vtk.swt.InteractiveVtkComposite;
+import org.simantics.g3d.vtk.swt.vtkSwtAction;
 import org.simantics.g3d.vtk.utils.vtkUtil;
 import org.simantics.plant3d.Activator;
 import org.simantics.plant3d.gizmo.SplitPointSelectionGizmo;
@@ -38,14 +38,13 @@ import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Direction;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
 import org.simantics.plant3d.utils.ComponentUtils;
-import org.simantics.utils.threads.AWTThread;
 import org.simantics.utils.threads.ThreadUtils;
 import org.simantics.utils.ui.ExceptionUtils;
 
 import vtk.vtkProp;
 import vtk.vtkTextActor;
 
-public class RoutePipeAction extends vtkAction {
+public class RoutePipeAction extends vtkSwtAction {
        enum LockType {
                X, Y, Z, XY, YZ, XZ, NONE, CUSTOM
        };
@@ -87,7 +86,7 @@ public class RoutePipeAction extends vtkAction {
     private Set<PositionType> allowed = new HashSet<PositionType>();
     
        
-       public RoutePipeAction(InteractiveVtkPanel panel, P3DRootNode root) {
+       public RoutePipeAction(InteractiveVtkComposite panel, P3DRootNode root) {
                super(panel);
                this.root = root;
                setText("Route Pipe");
@@ -115,7 +114,7 @@ public class RoutePipeAction extends vtkAction {
                nodeMap.commit();
                deattachUI();
                super.deattach();
-               panel.repaint();
+               panel.refresh();
        }
        
        public void attach() {
@@ -123,7 +122,7 @@ public class RoutePipeAction extends vtkAction {
                        return;
                
                super.attach();
-               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+               ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
                        public void run() {
 //                             attachUI();
                                try {
@@ -145,6 +144,7 @@ public class RoutePipeAction extends vtkAction {
        
        private void deattachUI() {
                //panel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+               panel.lock();
                if (translateAxisGizmo.isAttached())
                        translateAxisGizmo.deattach();
                if (splitPointSelectionGizmo.isAttached())
@@ -152,16 +152,17 @@ public class RoutePipeAction extends vtkAction {
                if (terminalSelectionGizmo.isAttached())
                        terminalSelectionGizmo.deattach();
                if (infoActor != null) {
-                       panel.GetRenderer().RemoveActor(infoActor);
+                       panel.getRenderer().RemoveActor(infoActor);
                        infoActor.Delete();
                        infoActor = null;
                }
+               panel.unlock();
        }
        
        private List<PipelineComponent> added = new ArrayList<PipelineComponent>();
        
        @Override
-       public void keyPressed(KeyEvent e) {
+       public boolean keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
                        panel.useDefaultAction();
                if (lock != LockType.CUSTOM) {
@@ -223,12 +224,12 @@ public class RoutePipeAction extends vtkAction {
                
                
                update();
-               
+               return true;
        }
        
        
        private void update() {
-               panel.repaint();
+               panel.refresh();
        }
        private void update(double x, double y) {
                switch (state) {
@@ -276,9 +277,9 @@ public class RoutePipeAction extends vtkAction {
                        return;
                } else {
                        terminalSelectionGizmo.setComponent(startComponent, allowed);
-                       terminalSelectionGizmo.attach(panel.GetRenderer());
+                       terminalSelectionGizmo.attach(panel);
                        state = ToolState.SELECTING_POSITION;
-                       panel.repaint();
+                       update();
                }
                
        }
@@ -356,7 +357,7 @@ public class RoutePipeAction extends vtkAction {
                                straightCP.setNext(start);
                        }
                }
-               translateAxisGizmo.attach(panel.GetRenderer());
+               translateAxisGizmo.attach(panel);
                setPreviousPosition(previousPosition);
                updateCurrentPoint();
        }
@@ -402,7 +403,7 @@ public class RoutePipeAction extends vtkAction {
                        
                }
                
-               translateAxisGizmo.attach(panel.GetRenderer());
+               translateAxisGizmo.attach(panel);
                setPreviousPosition(previousPosition);
                updateCurrentPoint();
        }
@@ -412,7 +413,7 @@ public class RoutePipeAction extends vtkAction {
                Point3d p2 = new Point3d();
                start.getInlineControlPointEnds(p1, p2);
                splitPointSelectionGizmo.setSplit(p1, p2);
-               splitPointSelectionGizmo.attach(panel.GetRenderer());
+               splitPointSelectionGizmo.attach(panel);
                state = ToolState.SELECTING_SPLIT;
        }
        public void deactivate() {
@@ -475,24 +476,26 @@ public class RoutePipeAction extends vtkAction {
        }
        
        @Override
-       public void mousePressed(MouseEvent e) {
+       public boolean mousePressed(MouseEvent e) {
                if (useDefault) {
-                       panel.getDefaultAction().mousePressed(e);
+                       getDefaultAction().mousePressed(e);
                }
+               return true;
        }
 
        @Override
-       public void mouseReleased(MouseEvent e) {
+       public boolean mouseReleased(MouseEvent e) {
                if (useDefault) {
-                       panel.getDefaultAction().mouseReleased(e);
+                       getDefaultAction().mouseReleased(e);
                }
+               return true;
        }
        
        @Override
-       public void mouseClicked(MouseEvent e) {
+       public boolean mouseClicked(MouseEvent e) {
                if (useDefault) {
-                       panel.getDefaultAction().mouseClicked(e);
-                       return;
+                       getDefaultAction().mouseClicked(e);
+                       return true;
                }
                if (state == ToolState.ROUTING) {
                        try {
@@ -528,7 +531,8 @@ public class RoutePipeAction extends vtkAction {
                } else if (state == ToolState.SELECTING_POSITION) {
                        if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1) {
                                int type = panel.getPickType();
-                               panel.setPickType(0);
+                               //panel.setPickType(0);
+                               panel.setPickType(5);
                                vtkProp[] picked = panel.pick(e.getX(), e.getY());
                                panel.setPickType(type);
                                PositionType position = terminalSelectionGizmo.getPickedPosition(picked);
@@ -555,7 +559,7 @@ public class RoutePipeAction extends vtkAction {
                                splitPointSelectionGizmo.deattach();
                                if (t == null) {
                                        panel.useDefaultAction();
-                                       return;
+                                       return true;
                                }
                                try {
                                        Vector3d pos = new Vector3d(t);
@@ -579,7 +583,7 @@ public class RoutePipeAction extends vtkAction {
                                }
                        }
                }
-               
+               return true;
        }
        
        private InlineComponent createBranchSplit(InlineComponent component, Vector3d pos) throws Exception{
@@ -594,19 +598,21 @@ public class RoutePipeAction extends vtkAction {
        }
        
        @Override
-       public void mouseMoved(MouseEvent e) {
+       public boolean mouseMoved(MouseEvent e) {
                if (useDefault) {
-                       panel.getDefaultAction().mouseMoved(e);
-                       return;
+                       getDefaultAction().mouseMoved(e);
+                       return true;
                }
                step = ((e.getModifiers() & MouseEvent.CTRL_DOWN_MASK) > 0);
                update(e.getX(), e.getY());
+               return true;
        }
        
        @Override
-       public void mouseDragged(MouseEvent e) {
+       public boolean mouseDragged(MouseEvent e) {
                if (useDefault)
-                       panel.getDefaultAction().mouseDragged(e);
+                       getDefaultAction().mouseDragged(e);
+               return true;
        }
        
 
@@ -644,7 +650,7 @@ public class RoutePipeAction extends vtkAction {
                endType = null;
                endPort = null;
 
-               Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(),x, y);
+               Ray ray = vtkUtil.createMouseRay(panel.getRenderer(),x, y);
                Vector3d o = new Vector3d(ray.pos);
                Vector3d d = ray.dir;
                
@@ -709,11 +715,7 @@ public class RoutePipeAction extends vtkAction {
                    updateRoute(o,d);
                }
                  
-               panel.repaint();
-               
-
-        
-               
+               panel.refresh();
            }
            
            private boolean updateCurrentPoint(Vector3d o, Vector3d d) {
@@ -757,7 +759,7 @@ public class RoutePipeAction extends vtkAction {
                    MathTools.intersectStraightPlane(o, d, point, new Vector3d(1.0,0.0,0.0), currentPosition);
                    break;
                case NONE:
-                       Vector3d normal = new Vector3d(panel.GetRenderer().GetActiveCamera().GetDirectionOfProjection());
+                       Vector3d normal = new Vector3d(panel.getRenderer().GetActiveCamera().GetDirectionOfProjection());
                    normal.normalize();
                    
                    MathTools.intersectStraightPlane(o, d, point, normal, currentPosition);
@@ -830,7 +832,7 @@ public class RoutePipeAction extends vtkAction {
 
                                
                        infoActor.SetPosition(10,10);
-                               panel.GetRenderer().AddActor(infoActor);
+                               panel.getRenderer().AddActor(infoActor);
                }
                infoActor.SetInput(text);
            }
index 4ac0a0e72c1c8976ad48ab4603c25c8f541146b7..23096f7eabfc96e40568bef31e571ffca5405d7f 100644 (file)
@@ -9,9 +9,9 @@ import javax.vecmath.Vector3d;
 import org.simantics.g3d.math.MathTools;
 import org.simantics.g3d.math.Ray;
 import org.simantics.g3d.scenegraph.IG3DNode;
-import org.simantics.g3d.vtk.action.TranslateAction;
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
 import org.simantics.g3d.vtk.common.VTKNodeMap;
+import org.simantics.g3d.vtk.swt.InteractiveVtkComposite;
+import org.simantics.g3d.vtk.swt.TranslateAction;
 import org.simantics.g3d.vtk.utils.vtkUtil;
 import org.simantics.plant3d.Activator;
 import org.simantics.plant3d.scenegraph.InlineComponent;
@@ -24,7 +24,7 @@ public class TranslateInlineAction extends TranslateAction{
        private Vector3d e;
        private Vector3d dir;
 
-       public TranslateInlineAction(InteractiveVtkPanel panel, VTKNodeMap nodeMap) {
+       public TranslateInlineAction(InteractiveVtkComposite panel, VTKNodeMap nodeMap) {
                super(panel, nodeMap);
                setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_refresh.png"));
        }
@@ -76,13 +76,14 @@ public class TranslateInlineAction extends TranslateAction{
        }
        
        @Override
-       public void keyPressed(KeyEvent e) {
+       public boolean keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
                        panel.useDefaultAction();
                if (valid)
-                       return;
+                       return true;
                
                update();
+               return true;
        }
        
        @Override
@@ -91,13 +92,13 @@ public class TranslateInlineAction extends TranslateAction{
        }
        
        @Override
-       public void mouseDragged(MouseEvent e) {
+       public boolean mouseDragged(MouseEvent e) {
                if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) > 0 && valid) { 
                        
                        Vector3d translate = getTranslate(e.getX(), e.getY(), prevTranslate);
                        //System.out.println("translate " + translate);
                        if (translate == null)
-                               return;
+                               return true;
                        //boolean step = ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0);
                        Vector3d pos = new Vector3d(node.getWorldPosition());
                        //pos.add(translate);
@@ -110,16 +111,17 @@ public class TranslateInlineAction extends TranslateAction{
                        //nodeMap.modified(node);
                        update();
                } else {
-                       panel.getDefaultAction().mouseDragged(e);
+                       getDefaultAction().mouseDragged(e);
                        update();
                }
+               return true;
        }
        
        
        
        protected Vector3d getTranslate(double x, double y, Vector3d offset) {
                
-               Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(),x, y);
+               Ray ray = vtkUtil.createMouseRay(panel.getRenderer(),x, y);
                
                Vector3d p = node.getWorldPosition();
                
index 833cea3cbe77e9e044d93071be27c438a3244a7f..ea3795206ec184698c3aeb460eb1b2c2c956d4c3 100644 (file)
@@ -13,7 +13,7 @@ import org.simantics.g3d.ontology.G3D;
 import org.simantics.g3d.scenegraph.base.INode;
 import org.simantics.g3d.scenegraph.base.ParentNode;
 import org.simantics.g3d.vtk.common.AbstractVTKNodeMap;
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
+import org.simantics.g3d.vtk.common.VtkView;
 import org.simantics.objmap.graph.IMapping;
 import org.simantics.plant3d.ontology.Plant3D;
 import org.simantics.plant3d.scenegraph.IP3DNode;
@@ -24,7 +24,6 @@ import org.simantics.plant3d.scenegraph.ParameterizedNode;
 import org.simantics.plant3d.scenegraph.PipeRun;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
 import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
-import org.simantics.utils.threads.AWTThread;
 
 import vtk.vtkProp;
 import vtk.vtkProp3D;
@@ -33,7 +32,7 @@ public class P3DNodeMap extends AbstractVTKNodeMap<INode> {
        
        private static final boolean DEBUG = false;
 
-       public P3DNodeMap(Session session, IMapping mapping, InteractiveVtkPanel panel, P3DRootNode rootNode) {
+       public P3DNodeMap(Session session, IMapping mapping, VtkView panel, P3DRootNode rootNode) {
                super(session, mapping, panel, rootNode);
                rootNode.setNodeMap(this);
        }
@@ -60,7 +59,7 @@ public class P3DNodeMap extends AbstractVTKNodeMap<INode> {
                }
                
                if (ids.contains(Plant3D.URIs.hasGeometry)) {
-                       node.visualize(panel);
+                       node.visualize(view);
                        updateRenderObjectsFor(node);
                        updateTransform(node);
                } 
@@ -68,7 +67,7 @@ public class P3DNodeMap extends AbstractVTKNodeMap<INode> {
                        ParameterizedNode geom = (ParameterizedNode)n;
                        for (String id : geom.getParameterMap().keySet()) {
                                if (ids.contains(id)) {
-                                       node.visualize(panel);
+                                       node.visualize(view);
                                        updateRenderObjectsFor(node);
                                        updateTransform(node);
                                        break;
@@ -95,7 +94,7 @@ public class P3DNodeMap extends AbstractVTKNodeMap<INode> {
        private void updateTransform(IP3DNode node) {
                if (DEBUG) System.out.println("P3DNodeMap update Transform " + node);
 
-               node.update(panel.GetRenderer());
+               node.update(view.getRenderer());
                
                if (node instanceof ParentNode<?>) {
                        ParentNode<IP3DNode> p = (ParentNode<IP3DNode>)node;
@@ -140,12 +139,12 @@ public class P3DNodeMap extends AbstractVTKNodeMap<INode> {
                
                if (hasActor(node))
                        return;
-               if (Thread.currentThread() != AWTThread.getThreadAccess().getThread())
+               if (Thread.currentThread() != view.getThreadQueue().getThread())
                        throw new RuntimeException("Illegal thread.");
                
-               panel.lock();
+               view.lock();
                
-               node.visualize(panel);
+               node.visualize(view);
 
                for (vtkProp3D act : node.getActors()) {
                        nodeToActor.add(node, act);
@@ -160,7 +159,7 @@ public class P3DNodeMap extends AbstractVTKNodeMap<INode> {
                
                updateTransform(node);
 
-        panel.unlock();
+        view.unlock();
 
        }
        
@@ -174,7 +173,7 @@ public class P3DNodeMap extends AbstractVTKNodeMap<INode> {
        }
        
        private void remActor(IP3DVisualNode node) {
-               if (Thread.currentThread() != AWTThread.getThreadAccess().getThread())
+               if (Thread.currentThread() != view.getThreadQueue().getThread())
                        throw new RuntimeException("Illegal thread.");
 
                List<vtkProp> list = nodeToActor.getValues(node);
@@ -183,11 +182,11 @@ public class P3DNodeMap extends AbstractVTKNodeMap<INode> {
                                actorToNode.remove(obj);        
                        }
                        nodeToActor.remove(node);
-                       panel.lock();
+                       view.lock();
                        
                        node.stopVisualize();
                        
-                       panel.unlock();
+                       view.unlock();
                }
        }
        
index 033f8544cf6f71103130d6b7db37a986609959f0..b1bb5000995c394503504c3a3aa54a68bea3ab25 100644 (file)
@@ -1,6 +1,5 @@
 package org.simantics.plant3d.editor;
 
-import java.awt.Component;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -11,12 +10,10 @@ import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.DisposeEvent;
 import org.eclipse.swt.events.DisposeListener;
 import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
 import org.simantics.db.ReadGraph;
@@ -28,17 +25,17 @@ import org.simantics.g3d.scenegraph.IG3DNode;
 import org.simantics.g3d.scenegraph.NodeMap;
 import org.simantics.g3d.scenegraph.base.INode;
 import org.simantics.g3d.vtk.action.RemoveAction;
-import org.simantics.g3d.vtk.action.RotateAction;
-import org.simantics.g3d.vtk.action.TranslateAction;
-import org.simantics.g3d.vtk.action.vtkCameraAndSelectorAction;
-import org.simantics.g3d.vtk.common.ContextMenuListener;
 import org.simantics.g3d.vtk.common.HoverHighlighter;
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
 import org.simantics.g3d.vtk.common.NodeSelectionProvider2;
 import org.simantics.g3d.vtk.common.SelectionHighlighter;
+import org.simantics.g3d.vtk.common.VtkView;
 import org.simantics.g3d.vtk.shape.vtkShape;
+import org.simantics.g3d.vtk.swt.ContextMenuListener;
+import org.simantics.g3d.vtk.swt.InteractiveVtkComposite;
+import org.simantics.g3d.vtk.swt.RotateAction;
+import org.simantics.g3d.vtk.swt.TranslateAction;
+import org.simantics.g3d.vtk.swt.vtkCameraAndSelectorAction;
 import org.simantics.g3d.vtk.utils.AxesDisplay;
-import org.simantics.g3d.vtk.utils.vtkPanelUtil;
 import org.simantics.objmap.graph.IMapping;
 import org.simantics.objmap.graph.Mappings;
 import org.simantics.objmap.graph.schema.IMappingSchema;
@@ -67,17 +64,13 @@ import org.simantics.selectionview.StandardPropertyPage;
 import org.simantics.ui.workbench.IPropertyPage;
 import org.simantics.ui.workbench.IResourceEditorInput;
 import org.simantics.ui.workbench.ResourceEditorPart;
-import org.simantics.utils.threads.AWTThread;
 import org.simantics.utils.threads.ThreadUtils;
 import org.simantics.utils.ui.ExceptionUtils;
-import org.simantics.utils.ui.SWTAWTComponent;
 
 import vtk.vtkActor;
-import vtk.vtkAxesActor;
 import vtk.vtkCameraPass;
 import vtk.vtkDefaultPass;
 import vtk.vtkLightsPass;
-import vtk.vtkOrientationMarkerWidget;
 import vtk.vtkRenderPassCollection;
 import vtk.vtkRenderer;
 import vtk.vtkSequencePass;
@@ -87,8 +80,9 @@ public class Plant3DEditor extends ResourceEditorPart {
 
        private Composite parent;
        private Resource input;
-       private InteractiveVtkPanel panel;
-       private SWTAWTComponent component;
+//     private InteractiveVtkPanel panel;
+//     private SWTAWTComponent component;
+       private InteractiveVtkComposite panel;
        
        private P3DRootNode rootNode;
        private IMapping<Resource,Object> mapping;
@@ -109,28 +103,32 @@ public class Plant3DEditor extends ResourceEditorPart {
        public void createPartControl(Composite parent) {
                this.parent = parent;
                parent.setLayout (new FillLayout ());
-               component = new SWTAWTComponent(parent,SWT.NONE) {
-                       
-                       @Override
-                       protected Component createSwingComponent() {
-                               if (panel == null) {
-                                       panel = new InteractiveVtkPanel();
-                                       vtkPanelUtil.registerPanel(panel);
-                                       createScene();
-                               }
-                               return panel;
-                       }
-               };
+//             component = new SWTAWTComponent(parent,SWT.NONE) {
+//                     
+//                     @Override
+//                     protected Component createSwingComponent() {
+//                             if (panel == null) {
+//                                     panel = new InteractiveVtkPanel();
+//                                     vtkPanelUtil.registerPanel(panel);
+//                                     createScene();
+//                             }
+//                             return panel;
+//                     }
+//             };
 
                IResourceEditorInput rei = (IResourceEditorInput)getEditorInput();
                input = rei.getResource();
                
+               panel = new InteractiveVtkComposite(parent);
+               
                
                //IActionBars actionBars = getEditorSite().getActionBars();
 
                hookContextMenu();
                
-               component.syncPopulate();
+               createScene();
+
+               //component.syncPopulate();
                
                new ContextMenuListener(panel, contextMenu);
                
@@ -223,20 +221,12 @@ public class Plant3DEditor extends ResourceEditorPart {
                                public void widgetDisposed(DisposeEvent e) {
                                        getSite().getPage().removePostSelectionListener(selectionProvider);
                                        
-                                       ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
-                                               
-                                               @Override
-                                               public void run() {
-                                                       PipingRules.setEnabled(false);
-                                                       nodeMap.delete();
-                                                       PipingRules.setEnabled(true);
-                                                       vtkPanelUtil.unregisterPanel(panel);
-
-                                               }
-                                       });
+                                       PipingRules.setEnabled(false);
+                                       nodeMap.delete();
+                                       PipingRules.setEnabled(true);
                                        mapping.dispose();
-                                       component.dispose();
-                                       
+//                                     component.dispose();
+                                       //panel.getComponent().dispose();
                                        
                                }
                        });
@@ -261,7 +251,7 @@ public class Plant3DEditor extends ResourceEditorPart {
        }
        
        public void populate() {
-               ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
+               ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
                        
                        @Override
                        public void run() {
@@ -276,17 +266,18 @@ public class Plant3DEditor extends ResourceEditorPart {
                return schema;
        }
        
-       protected P3DNodeMap createNodeMap(Session session, IMapping<Resource, Object> mapping, InteractiveVtkPanel panel, P3DRootNode rootNode) {
+       protected P3DNodeMap createNodeMap(Session session, IMapping<Resource, Object> mapping, VtkView panel, P3DRootNode rootNode) {
                 return new P3DNodeMap(session, mapping, panel,rootNode);
        }
        
        @Override
        public void setFocus() {
-               component.setFocus();
+               //component.setFocus();
+               panel.getComponent().setFocus();
        }
        
        private void createScene() {
-               vtkRenderer ren1 = panel.GetRenderer();
+               vtkRenderer ren1 = panel.getRenderer();
                
                boolean multiPass = false;
                if (multiPass) {
@@ -440,9 +431,11 @@ public class Plant3DEditor extends ResourceEditorPart {
                if (IMapping.class.equals(adapter)) {
                        return mapping;
                }
-               if (InteractiveVtkPanel.class.equals(adapter)) {
+//             if (InteractiveVtkPanel.class.equals(adapter)) {
+//                     return panel;
+//             }
+               if (VtkView.class.equals(adapter))
                        return panel;
-               }
                if (ISelectionProvider.class.equals(adapter))
                        return selectionProvider;
                return super.getAdapter(adapter);
index e653cf65c247facb675e6b5bc1734450ba10c995..e5d83fb0da7202fa8fd056580da988cebacb0f37 100644 (file)
@@ -1,7 +1,5 @@
 package org.simantics.plant3d.gizmo;
 
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseMotionListener;
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -11,6 +9,7 @@ import javax.vecmath.Tuple3d;
 import javax.vecmath.Vector2d;
 import javax.vecmath.Vector3d;
 
+import org.eclipse.swt.events.MouseMoveListener;
 import org.simantics.g3d.math.MathTools;
 import org.simantics.g3d.math.Ray;
 import org.simantics.g3d.scenegraph.RenderListener;
@@ -18,9 +17,10 @@ import org.simantics.g3d.shape.Color4d;
 import org.simantics.g3d.shape.Cone;
 import org.simantics.g3d.shape.Cylinder;
 import org.simantics.g3d.shape.Mesh;
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
+import org.simantics.g3d.vtk.common.VtkView;
 import org.simantics.g3d.vtk.gizmo.vtkGizmo;
 import org.simantics.g3d.vtk.shape.MeshActor;
+import org.simantics.g3d.vtk.swt.InteractiveVtkComposite;
 import org.simantics.g3d.vtk.utils.vtkUtil;
 
 import vtk.vtkProp;
@@ -29,9 +29,10 @@ public class SplitPointSelectionGizmo extends vtkGizmo {
        
        MeshActor actor;
        
-       InteractiveVtkPanel panel;
+       VtkView panel;
        private RenderListener listener;
-       private MouseMotionListener mouseListener;
+       //private MouseMotionListener mouseListener;
+       private MouseMoveListener mouseListener;
        
        Point3d start;
        Point3d end;
@@ -44,7 +45,7 @@ public class SplitPointSelectionGizmo extends vtkGizmo {
        
        Tuple3d splitPoint = null;
        
-       public SplitPointSelectionGizmo(InteractiveVtkPanel panel) {
+       public SplitPointSelectionGizmo(VtkView panel) {
                this.panel = panel;
                
                int res = 16;
@@ -66,7 +67,7 @@ public class SplitPointSelectionGizmo extends vtkGizmo {
                this.listener = new RenderListener() {
                        @Override
                        public void preRender() {
-                               Ray ray = vtkUtil.createMouseRay(getRenderer(), mousePos.x, mousePos.y);
+                               Ray ray = vtkUtil.createMouseRay(SplitPointSelectionGizmo.this.panel.getRenderer(), mousePos.x, mousePos.y);
                                //ray.dir.add(ray.pos);
                                //if (MathTools.intersectLineLine(start, end, ray.pos, ray.dir, pa, pb)) {
                                double mu[] = new double[2];
@@ -98,20 +99,30 @@ public class SplitPointSelectionGizmo extends vtkGizmo {
                        }
                };
                
-               this.mouseListener = new MouseMotionListener() {
+//             this.mouseListener = new MouseMotionListener() {
+//                     
+//                     @Override
+//                     public void mouseMoved(MouseEvent e) {
+//                             mousePos.x = e.getX();
+//                             mousePos.y = e.getY();
+//                             SplitPointSelectionGizmo.this.panel.refresh();
+//                     }
+//                     
+//                     @Override
+//                     public void mouseDragged(MouseEvent e) {
+//                             mousePos.x = e.getX();
+//                             mousePos.y = e.getY();
+//                             SplitPointSelectionGizmo.this.panel.refresh();
+//                     }
+//             };
+               this.mouseListener = new MouseMoveListener() {
                        
                        @Override
-                       public void mouseMoved(MouseEvent e) {
-                               mousePos.x = e.getX();
-                               mousePos.y = e.getY();
-                               SplitPointSelectionGizmo.this.panel.repaint();
-                       }
-                       
-                       @Override
-                       public void mouseDragged(MouseEvent e) {
-                               mousePos.x = e.getX();
-                               mousePos.y = e.getY();
-                               SplitPointSelectionGizmo.this.panel.repaint();
+                       public void mouseMove(org.eclipse.swt.events.MouseEvent e) {
+                               mousePos.x = e.x;
+                               mousePos.y = e.y;
+                               SplitPointSelectionGizmo.this.panel.refresh();
+                               
                        }
                };
 
@@ -125,16 +136,19 @@ public class SplitPointSelectionGizmo extends vtkGizmo {
        }
        
        @Override
-       public void attach(Object renderingPart) {
+       public void attach(VtkView renderingPart) {
                super.attach(renderingPart);
                panel.addListener(listener);
-               panel.addMouseMotionListener(mouseListener);
+               // FIXME
+               //panel.addMouseMotionListener(mouseListener);
+               ((InteractiveVtkComposite)panel).getComponent().addMouseMoveListener(mouseListener);
        }
        
        @Override
        public void deattach() {
                panel.removeListener(listener);
-               panel.removeMouseMotionListener(mouseListener);
+               // FIXME
+               //panel.removeMouseMotionListener(mouseListener);
                super.deattach();
        }
        
index 287ce3401a513a27c36fd293050fb4385972b931..f194c8dbbbfa3c82923ca77ddb178d954af7b371 100644 (file)
@@ -10,11 +10,10 @@ import javax.vecmath.Vector3d;
 
 import org.simantics.g3d.scenegraph.RenderListener;
 import org.simantics.g3d.tools.PluginTools;
-import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
+import org.simantics.g3d.vtk.common.VtkView;
 import org.simantics.g3d.vtk.gizmo.vtkGizmo;
 import org.simantics.g3d.vtk.utils.vtkUtil;
 import org.simantics.plant3d.Activator;
-import org.simantics.plant3d.scenegraph.InlineComponent;
 import org.simantics.plant3d.scenegraph.PipelineComponent;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PositionType;
 
@@ -46,10 +45,10 @@ public class TerminalSelectionGizmo extends vtkGizmo {
        Vector3d prev = new Vector3d();
        Vector3d next = new Vector3d();
        
-       InteractiveVtkPanel panel;
+       VtkView panel;
        
        private RenderListener listener;
-       public TerminalSelectionGizmo(InteractiveVtkPanel panel) {
+       public TerminalSelectionGizmo(VtkView panel) {
                this.panel = panel;
                this.listener = new RenderListener() {
                        
@@ -78,8 +77,13 @@ public class TerminalSelectionGizmo extends vtkGizmo {
                };
        }
        
+       vtkRenderer getRenderer() {
+               return panel.getRenderer();
+       }
+       
+       
        @Override
-       public void attach(Object renderingPart) {
+       public void attach(VtkView renderingPart) {
                if (nextProp == null) {
                        loadData();
                        
@@ -107,26 +111,29 @@ public class TerminalSelectionGizmo extends vtkGizmo {
        }
        
        protected void attachActors() {
+               panel.lock();
                vtkRenderer ren = getRenderer();
                if (showPrev) {
-                       ren.AddActor(prevProp);
+                       ren.AddActor2D(prevProp);
                }
                if (showNext) {
-                       ren.AddActor(nextProp);
+                       ren.AddActor2D(nextProp);
                }
                if (showMiddle) {
-                       ren.AddActor(middleProp);
+                       ren.AddActor2D(middleProp);
                }
-               
+               panel.unlock();
        }
        
        @Override
        protected void deattachActors() {
                panel.removeListener(listener);
+               panel.lock();
                vtkRenderer ren = getRenderer();
                ren.RemoveActor(prevProp);
                ren.RemoveActor(nextProp);
                ren.RemoveActor(middleProp);
+               panel.unlock();
        }
        
        public void setComponent(PipelineComponent component, Set<PositionType> allowed) {
@@ -149,10 +156,11 @@ public class TerminalSelectionGizmo extends vtkGizmo {
                        throw new RuntimeException("Cannot resolve required image files.");
                
                vtkPoints points = new vtkPoints();
-               points.InsertNextPoint(-8, -8, 0.0);
-               points.InsertNextPoint( 8, -8, 0.0);
-               points.InsertNextPoint( 8,  8, 0.0);
-               points.InsertNextPoint(-8,  8, 0.0);
+               double pw = 8;
+               points.InsertNextPoint(-pw, -pw, 0.0);
+               points.InsertNextPoint( pw, -pw, 0.0);
+               points.InsertNextPoint( pw,  pw, 0.0);
+               points.InsertNextPoint(-pw,  pw, 0.0);
                
                
                vtkCellArray cellArray = new vtkCellArray();
@@ -214,6 +222,15 @@ public class TerminalSelectionGizmo extends vtkGizmo {
                middleProp.SetPickable(1);
                
                
+               middleProp.SetWidth(pw);
+               middleProp.SetHeight(pw);
+               
+               prevProp.SetWidth(pw);
+               prevProp.SetHeight(pw);
+               
+               nextProp.SetWidth(pw);
+               nextProp.SetHeight(pw);
+               
                plusReader.GetOutputPort().Delete();
                plusReader.Delete();
                middleReader.GetOutputPort().Delete();
index 54941609764669373b7e182928b25e984e1815d1..072079c22e198bb85224c0085de0116317bd4c8c 100644 (file)
@@ -27,6 +27,7 @@ import org.simantics.selectionview.ComparableTabContributor;
 import org.simantics.selectionview.PropertyTabContributorImpl;
 import org.simantics.selectionview.SelectionProcessor;
 import org.simantics.utils.datastructures.Callback;
+import org.simantics.utils.threads.SWTThread;
 
 import vtk.vtkProp;
 
@@ -67,7 +68,7 @@ public class P3DSelectionProcessor implements SelectionProcessor<Object, ReadGra
                                 vtkProp prop = propCollection.iterator().next();
                                 if (prop == null)
                                         throw new NullPointerException();
-                                result.add(new ComparableTabContributor(new VTKPropertyTabContributor(), -2, prop, "VTK"));
+                                result.add(new ComparableTabContributor(new VTKPropertyTabContributor(SWTThread.getThreadAccess()), -2, prop, "VTK"));
                         }
                         
                         if (resourceCollection.size() > 0) {
index a11f912d1609230e34bccf1246fac5dc178d44f1..9b2b750fde45a5a812f90eac25e2f47ea030cc07 100644 (file)
@@ -16,6 +16,7 @@ import org.simantics.g3d.scenegraph.MeshProvider;
 import org.simantics.g3d.scenegraph.NodeHighlighter.HighlightEventType;
 import org.simantics.g3d.scenegraph.ParametricGeometryProvider;
 import org.simantics.g3d.shape.Mesh;
+import org.simantics.g3d.vtk.common.VtkView;
 import org.simantics.g3d.vtk.shape.MeshActor;
 import org.simantics.g3d.vtk.shape.vtkMeshObject;
 import org.simantics.opencascade.OccTriangulator;
@@ -23,7 +24,6 @@ import org.simantics.opencascade.SolidModelProvider;
 import org.simantics.opencascade.vtk.vtkSolidObject;
 
 import vtk.vtkActor;
-import vtk.vtkPanel;
 import vtk.vtkProp3D;
 import vtk.vtkProperty;
 
@@ -46,7 +46,7 @@ public class GeometryComponent {
                calculatedParameters = new HashMap<String, Object>();
        }
        
-       public void visualize(vtkPanel panel) {
+       public void visualize(VtkView panel) {
                if (geometryProvider != null) {
                        updateParameters();
                        
@@ -183,7 +183,7 @@ public class GeometryComponent {
        
        public void stopVisualize() {
                if (solidObject != null) {
-                       solidObject.clearActorsAWT();
+                       solidObject.clearActorsVTK();
                        solidObject = null;
                }
                if (solidModel != null) {
@@ -191,7 +191,7 @@ public class GeometryComponent {
                        solidModel = null;
                }
                if (meshObject != null) {
-                       meshObject.clearActorsAWT();
+                       meshObject.clearActorsVTK();
                        meshObject = null;
                }
                if (mesh != null)
index feffaad3eec67a8ff23450d1afee4d5ee43a2fe9..54c14a14ad9a09e3336f21e4696b7bed88936c1f 100644 (file)
@@ -6,12 +6,12 @@ import java.util.Set;
 
 import org.simantics.g3d.scenegraph.GeometryProvider;
 import org.simantics.g3d.scenegraph.NodeHighlighter;
+import org.simantics.g3d.vtk.common.VtkView;
 import org.simantics.g3d.vtk.utils.vtkUtil;
 import org.simantics.objmap.graph.annotations.RelatedGetObj;
 import org.simantics.objmap.graph.annotations.RelatedSetObj;
 import org.simantics.plant3d.ontology.Plant3D;
 
-import vtk.vtkPanel;
 import vtk.vtkProp3D;
 import vtk.vtkRenderer;
 
@@ -34,7 +34,7 @@ public abstract class GeometryNode extends P3DNode implements ParameterizedNode,
        }
        
        @Override
-       public void visualize(vtkPanel panel) {
+       public void visualize(VtkView panel) {
                updateParameters();
                component.visualize(panel);
        }
index ff568b5c08fb65050d5dd65ff87cd30aa51b6816..1bd2b139d349585ba78f34e57190aa3a2dea8a6e 100644 (file)
@@ -2,7 +2,8 @@ package org.simantics.plant3d.scenegraph;
 
 import java.util.Collection;
 
-import vtk.vtkPanel;
+import org.simantics.g3d.vtk.common.VtkView;
+
 import vtk.vtkProp3D;
 import vtk.vtkRenderer;
 
@@ -10,7 +11,7 @@ public interface IP3DVisualNode extends IP3DNode {
        public String getName();
        public void setName(String name);
        
-       public void visualize(vtkPanel panel);
+       public void visualize(VtkView panel);
        public void stopVisualize();
        
        public void update(vtkRenderer ren);
index 26d65c7a1270e53bbc61928e8b7ac18f56529660..317904cb9112d7cc81faa77c664c4dd91037f324 100644 (file)
@@ -6,12 +6,12 @@ import java.util.Set;
 
 import org.simantics.g3d.scenegraph.GeometryProvider;
 import org.simantics.g3d.scenegraph.NodeHighlighter;
+import org.simantics.g3d.vtk.common.VtkView;
 import org.simantics.g3d.vtk.utils.vtkUtil;
 import org.simantics.objmap.graph.annotations.RelatedGetObj;
 import org.simantics.objmap.graph.annotations.RelatedSetObj;
 import org.simantics.plant3d.ontology.Plant3D;
 
-import vtk.vtkPanel;
 import vtk.vtkProp3D;
 import vtk.vtkRenderer;
 
@@ -35,7 +35,7 @@ public class P3DParentGeometryNode<T extends IP3DNode> extends P3DParentNode<T>
        }
        
        @Override
-       public void visualize(vtkPanel ren) {
+       public void visualize(VtkView ren) {
                updateParameters();
                component.visualize(ren);
        }
index 2932f1d2b1bc16a59d1e01d6d2e8d5791003c32e..0bd028307343513f88d7eb32f7717bfc929419ee 100644 (file)
@@ -11,6 +11,7 @@ import org.simantics.g3d.property.annotations.GetPropertyValue;
 import org.simantics.g3d.property.annotations.PropertyTabBlacklist;
 import org.simantics.g3d.property.annotations.SetPropertyValue;
 import org.simantics.g3d.scenegraph.IG3DNode;
+import org.simantics.g3d.vtk.common.VtkView;
 import org.simantics.objmap.graph.annotations.GraphType;
 import org.simantics.objmap.graph.annotations.RelatedElementsAdd;
 import org.simantics.objmap.graph.annotations.RelatedElementsGet;
@@ -20,7 +21,6 @@ import org.simantics.objmap.graph.annotations.RelatedSetValue;
 import org.simantics.plant3d.ontology.Plant3D;
 import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
 
-import vtk.vtkPanel;
 import vtk.vtkProp3D;
 import vtk.vtkRenderer;
 
@@ -37,7 +37,7 @@ public class PipeRun extends P3DParentNode<IP3DNode> {
        }
        
        @Override
-       public void visualize(vtkPanel panel) {
+       public void visualize(VtkView panel) {
                
        }
        
diff --git a/pom.xml b/pom.xml
index a406b5a706aed23b3ec8ba9905a2caf4ab329145..0abf255ba203f364424617351f7dc3a229ef56e6 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                <module>org.jcae.opencascade.win32.x86_64</module>
                <module>vtk</module>
                <module>vtk.win32.win32.x86_64</module>
+               <module>vtk.rendering</module>
+               <module>vtk.rendering.win32.win32.x86_64</module>
 
                <module>org.simantics.g3d</module>
                <module>org.simantics.g3d.csg</module>
index c8363ed3ad34ad505bb364c4e5935ee1e254a324..0ceb16c99f359612c72744f0e6143280269bd343 100644 (file)
@@ -2,7 +2,7 @@
 <feature
       id="vtk.lib"
       label="VTK Feature"
-      version="5.10.0.qualifier"
+      version="8.2.0.qualifier"
       os="win32"
       arch="x86_64">
 
          version="0.0.0"
          unpack="false"/>
 
+   <plugin
+         id="vtk.rendering"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="vtk.rendering.win32.win32.x86_64"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         fragment="true"
+         unpack="false"/>
+   
    <plugin
          id="vtk.win32.win32.x86_64"
          os="win32"
          install-size="0"
          version="0.0.0"
          fragment="true"/>
-
+   <!--
+   <plugin
+         id="vtk.win32.win32.x86_64.debug"
+         os="win32"
+         arch="x86_64"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         fragment="true"/>
+    -->
 </feature>
index 1c45d5def65f5e8e3b42db04edb136b9d4999ded..1bafb9f9e692a44e5adc228cf2f3faec5aa9ac03 100644 (file)
@@ -10,6 +10,6 @@
 
        <artifactId>vtk.lib</artifactId>
        <packaging>eclipse-feature</packaging>
-       <version>5.10.0-SNAPSHOT</version>
+       <version>8.2.0-SNAPSHOT</version>
 
 </project>
diff --git a/vtk.rendering.win32.win32.x86_64/pom.xml b/vtk.rendering.win32.win32.x86_64/pom.xml
new file mode 100644 (file)
index 0000000..e683c99
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+       xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+       <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <groupId>org.simantics.g3d</groupId>
+               <artifactId>org.simantics.g3d.root</artifactId>
+               <version>1.0.0-SNAPSHOT</version>
+       </parent>
+
+       <artifactId>vtk.rendering.win32.win32.x86_64</artifactId>
+       <packaging>eclipse-plugin</packaging>
+       <version>8.2.0-SNAPSHOT</version>
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.eclipse.tycho</groupId>
+                               <artifactId>target-platform-configuration</artifactId>
+                               <configuration>
+                                       <environments>
+                                               <environment>
+                                                       <os>win32</os>
+                                                       <ws>win32</ws>
+                                                       <arch>x86_64</arch>
+                                               </environment>
+                                       </environments>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+
+</project>
\ No newline at end of file
index 6dee25c0bc4d8d066ce70aa0cc86182c5f87bdbc..db3793a3faac9c6b913190df34766dc7cc691b44 100644 (file)
@@ -10,7 +10,7 @@
                <version>1.0.0-SNAPSHOT</version>
        </parent>
 
-       <artifactId>vtk</artifactId>
+       <artifactId>vtk.rendering</artifactId>
        <packaging>eclipse-plugin</packaging>
        <version>8.2.0-SNAPSHOT</version>