From 84132a1d750c45f9161afbd58b78572964e50d26 Mon Sep 17 00:00:00 2001 From: Marko Luukkainen Date: Wed, 7 Aug 2019 17:46:11 +0300 Subject: [PATCH] Using SWT thread with Plant3d gitlab #21 Change-Id: I15483236ec95a4e41622c71db182e0a2d6bbaaac --- .../simantics/g3d/csg/editor/CSGEditor2.java | 883 +++++------ .../simantics/g3d/csg/editor/CSGNodeMap.java | 258 ++-- .../g3d/csg/scenegraph2/CSGnode.java | 239 ++- .../g3d/csg/scenegraph2/CSGparentNode.java | 638 ++++---- .../g3d/csg/scenegraph2/ICSGnode.java | 78 +- org.simantics.g3d.vtk/META-INF/MANIFEST.MF | 6 +- .../simantics/g3d/vtk/action/vtkAction.java | 108 +- .../{common => awt}/ContextMenuListener.java | 2 +- .../{common => awt}/InteractiveVtkPanel.java | 34 +- .../g3d/vtk/{action => awt}/RotateAction.java | 1315 ++++++++--------- .../vtk/{action => awt}/TranslateAction.java | 17 +- .../simantics/g3d/vtk/awt/vtkAwtAction.java | 102 ++ .../vtkCameraAndSelectorAction.java | 5 +- .../g3d/vtk/common/AbstractVTKNodeMap.java | 25 +- .../g3d/vtk/common/HoverHighlighter.java | 108 +- .../g3d/vtk/common/SelectionHighlighter.java | 13 +- .../org/simantics/g3d/vtk/common/VtkView.java | 32 + .../g3d/vtk/gizmo/RotateAxisGizmo.java | 160 +- .../g3d/vtk/gizmo/TranslateAxisGizmo.java | 238 +-- .../org/simantics/g3d/vtk/gizmo/vtkGizmo.java | 294 ++-- .../vtk/handlers/CameraPositionHandler.java | 153 +- .../handlers/ParallelPerspectiveHandler.java | 164 +- .../property/VTKPropertyTabContributor.java | 247 ++-- .../g3d/vtk/shape/vtkMeshObject.java | 43 +- .../g3d/vtk/swt/ContextMenuListener.java | 49 + .../g3d/vtk/swt/InteractiveVtkComposite.java | 425 ++++++ .../simantics/g3d/vtk/swt/RotateAction.java | 661 +++++++++ .../g3d/vtk/swt/TranslateAction.java | 479 ++++++ .../vtk/swt/vtkCameraAndSelectorAction.java | 399 +++++ .../simantics/g3d/vtk/swt/vtkSwtAction.java | 105 ++ .../simantics/g3d/vtk/utils/AxesDisplay.java | 6 +- .../src/org/simantics/g3d/gizmo/Gizmo.java | 56 +- ...nnotatedPropertyTabContributorFactory.java | 2 + .../META-INF/MANIFEST.MF | 3 +- .../opencascade/vtk/vtkSolidObject.java | 51 +- org.simantics.plant3d/META-INF/MANIFEST.MF | 4 +- .../plant3d/actions/AddComponentAction.java | 47 +- .../plant3d/actions/RoutePipeAction.java | 80 +- .../actions/TranslateInlineAction.java | 20 +- .../simantics/plant3d/editor/P3DNodeMap.java | 25 +- .../plant3d/editor/Plant3DEditor.java | 87 +- .../gizmo/SplitPointSelectionGizmo.java | 58 +- .../plant3d/gizmo/TerminalSelectionGizmo.java | 43 +- .../property/P3DSelectionProcessor.java | 3 +- .../plant3d/scenegraph/GeometryComponent.java | 8 +- .../plant3d/scenegraph/GeometryNode.java | 4 +- .../plant3d/scenegraph/IP3DVisualNode.java | 5 +- .../scenegraph/P3DParentGeometryNode.java | 4 +- .../simantics/plant3d/scenegraph/PipeRun.java | 4 +- pom.xml | 2 + vtk.lib.feature/feature.xml | 28 +- vtk.lib.feature/pom.xml | 2 +- vtk.rendering.win32.win32.x86_64/pom.xml | 35 + vtk.rendering/pom.xml | 2 +- 54 files changed, 5075 insertions(+), 2784 deletions(-) rename org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/{common => awt}/ContextMenuListener.java (95%) rename org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/{common => awt}/InteractiveVtkPanel.java (93%) rename org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/{action => awt}/RotateAction.java (95%) rename org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/{action => awt}/TranslateAction.java (96%) create mode 100644 org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkAwtAction.java rename org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/{action => awt}/vtkCameraAndSelectorAction.java (98%) create mode 100644 org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/VtkView.java create mode 100644 org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/ContextMenuListener.java create mode 100644 org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/InteractiveVtkComposite.java create mode 100644 org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/RotateAction.java create mode 100644 org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/TranslateAction.java create mode 100644 org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java create mode 100644 org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkSwtAction.java create mode 100644 vtk.rendering.win32.win32.x86_64/pom.xml diff --git a/org.simantics.g3d.csg/src/org/simantics/g3d/csg/editor/CSGEditor2.java b/org.simantics.g3d.csg/src/org/simantics/g3d/csg/editor/CSGEditor2.java index 8f5db655..bed44873 100644 --- a/org.simantics.g3d.csg/src/org/simantics/g3d/csg/editor/CSGEditor2.java +++ b/org.simantics.g3d.csg/src/org/simantics/g3d/csg/editor/CSGEditor2.java @@ -1,440 +1,443 @@ -/******************************************************************************* - * 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.action.RotateAction; -import org.simantics.g3d.vtk.action.TranslateAction; -import org.simantics.g3d.vtk.action.vtkCameraAndSelectorAction; -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.VTKContentOutlinePage; -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 mapping; - - private NodeSelectionProvider2 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(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 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 nodes = new ArrayList(); - 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 primitives = new ArrayList(); -// 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 booleanOps = new ArrayList(); -// 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(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; - } - return super.getAdapter(adapter); - } - - public Set getPropertyContexts() { - Set result = new HashSet(); - result.add("http://www.simantics.org/Project-1.0/ProjectBrowseContext"); - return result; - } -} +/******************************************************************************* + * 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 mapping; + + private NodeSelectionProvider2 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(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 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 nodes = new ArrayList(); + 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 primitives = new ArrayList(); +// 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 booleanOps = new ArrayList(); +// 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(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 getPropertyContexts() { + Set result = new HashSet(); + result.add("http://www.simantics.org/Project-1.0/ProjectBrowseContext"); + return result; + } +} diff --git a/org.simantics.g3d.csg/src/org/simantics/g3d/csg/editor/CSGNodeMap.java b/org.simantics.g3d.csg/src/org/simantics/g3d/csg/editor/CSGNodeMap.java index a207d5f2..b4eaa148 100644 --- a/org.simantics.g3d.csg/src/org/simantics/g3d/csg/editor/CSGNodeMap.java +++ b/org.simantics.g3d.csg/src/org/simantics/g3d/csg/editor/CSGNodeMap.java @@ -1,130 +1,128 @@ -/******************************************************************************* - * 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.common.AbstractVTKNodeMap; -import org.simantics.g3d.vtk.common.InteractiveVtkPanel; -import org.simantics.objmap.graph.IMapping; -import org.simantics.utils.threads.AWTThread; - -import vtk.vtkProp; -import vtk.vtkProp3D; -import vtk.vtkRenderer; - -public class CSGNodeMap extends AbstractVTKNodeMap { - - - - 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 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 p = (ParentNode)node; - for (ICSGnode n : p.getNodes()) - remActor(n); - } - - remActor(node); - addActor(node); - - } - - @Override - protected Collection getActors(ICSGnode node) { - List props = new ArrayList(); - 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() != AWTThread.getThreadAccess().getThread()) - throw new RuntimeException("Illegal thread."); - - panel.lock(); - - node.visualize(panel); - - for (vtkProp3D act : node.getActors()) { - nodeToActor.add(node, act); - actorToNode.put(act, node); - } - - panel.unlock(); - - } - - - - private boolean hasActor(ICSGnode node) { - List list = nodeToActor.getValues(node); - if (list == null || list.size() == 0) - return false; - return true; - } - - private void remActor(ICSGnode node) { - if (Thread.currentThread() != AWTThread.getThreadAccess().getThread()) - throw new RuntimeException("Illegal thread."); - - List list = nodeToActor.getValues(node); - if (list != null) { - for (vtkProp obj : list) { - actorToNode.remove(obj); - } - nodeToActor.remove(node); - panel.lock(); - - node.stopVisualize(); - - panel.unlock(); - } - } - - -} +/******************************************************************************* + * 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 { + + + + 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 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 p = (ParentNode)node; + for (ICSGnode n : p.getNodes()) + remActor(n); + } + + remActor(node); + addActor(node); + + } + + @Override + protected Collection getActors(ICSGnode node) { + List props = new ArrayList(); + 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 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 list = nodeToActor.getValues(node); + if (list != null) { + for (vtkProp obj : list) { + actorToNode.remove(obj); + } + nodeToActor.remove(node); + view.lock(); + + node.stopVisualize(); + + view.unlock(); + } + } + + +} diff --git a/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/CSGnode.java b/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/CSGnode.java index a28e5a3a..68c1c015 100644 --- a/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/CSGnode.java +++ b/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/CSGnode.java @@ -1,120 +1,119 @@ -/******************************************************************************* - * 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.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.vtkPanel; -import vtk.vtkProp3D; -import vtk.vtkRenderer; - -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(vtkPanel 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 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(); - } - - - -} +/******************************************************************************* + * 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 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(); + } + + + +} diff --git a/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/CSGparentNode.java b/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/CSGparentNode.java index 24f2ac4c..6f83fdbf 100644 --- a/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/CSGparentNode.java +++ b/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/CSGparentNode.java @@ -1,319 +1,319 @@ -/******************************************************************************* - * 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.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.vtkPanel; -import vtk.vtkProp3D; - -@PropertyContributor -public abstract class CSGparentNode extends ParentNode 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 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 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 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(vtkPanel 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 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; - } -} +/******************************************************************************* + * 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 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 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 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 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 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; + } +} diff --git a/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/ICSGnode.java b/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/ICSGnode.java index 2f6ef6b7..3f0568cd 100644 --- a/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/ICSGnode.java +++ b/org.simantics.g3d.csg/src/org/simantics/g3d/csg/scenegraph2/ICSGnode.java @@ -1,39 +1,39 @@ -/******************************************************************************* - * 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 vtk.vtkPanel; -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(vtkPanel panel); - public void stopVisualize(); - - public Collection getActors(); - - public void deattach(); -} +/******************************************************************************* + * 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 getActors(); + + public void deattach(); +} diff --git a/org.simantics.g3d.vtk/META-INF/MANIFEST.MF b/org.simantics.g3d.vtk/META-INF/MANIFEST.MF index a3757760..3a9a0aae 100644 --- a/org.simantics.g3d.vtk/META-INF/MANIFEST.MF +++ b/org.simantics.g3d.vtk/META-INF/MANIFEST.MF @@ -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 diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/vtkAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/vtkAction.java index f95c875f..01327c51 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/vtkAction.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/vtkAction.java @@ -1,99 +1,9 @@ -/******************************************************************************* - * 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.action; - -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.eclipse.jface.action.Action; -import org.simantics.g3d.vtk.common.InteractiveVtkPanel; - -public abstract class vtkAction extends Action implements KeyListener, MouseListener, MouseMotionListener { - - protected InteractiveVtkPanel panel; - - public vtkAction(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); - } - - @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) { - - } -} +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(); +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/ContextMenuListener.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/ContextMenuListener.java similarity index 95% rename from org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/ContextMenuListener.java rename to org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/ContextMenuListener.java index 3f42fca1..fbf2dcdd 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/ContextMenuListener.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/ContextMenuListener.java @@ -1,4 +1,4 @@ -package org.simantics.g3d.vtk.common; +package org.simantics.g3d.vtk.awt; import java.awt.event.MouseEvent; diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/InteractiveVtkPanel.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/InteractiveVtkPanel.java 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 e6129b5d..df91a5d4 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/InteractiveVtkPanel.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/InteractiveVtkPanel.java @@ -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(); + } + + + } diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/RotateAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/RotateAction.java 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 d47456fd..f7ffc553 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/RotateAction.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/RotateAction.java @@ -1,658 +1,657 @@ -/******************************************************************************* - * 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.action; - -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.MathTools; -import org.simantics.g3d.math.Ray; -import org.simantics.g3d.math.EulerTools.Order; -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.InteractiveVtkPanel; -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 - * - */ -public class RotateAction extends vtkAction{ - - 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.GetRenderer()); - } - - 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; - panel.getDefaultAction().mousePressed(e); - panel.setCursor(activeCursor); - } - } else { - panel.getDefaultAction().mousePressed(e); - } - } - - - - @Override - public void mouseReleased(MouseEvent e) { - if (e.getButton() == MouseEvent.BUTTON1) { - valid = false; - worldOrientation = null; - panel.setCursor(activeCursor); - } else { - panel.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 { - panel.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) { - panel.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; - } - -} +/******************************************************************************* + * 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 + * + */ +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; + } + +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/TranslateAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/TranslateAction.java 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 7000edae..d7d81331 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/TranslateAction.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/TranslateAction.java @@ -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 index 00000000..2a2ea3e5 --- /dev/null +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkAwtAction.java @@ -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) { + + } +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/vtkCameraAndSelectorAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkCameraAndSelectorAction.java 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 b4a387bc..f1e6f324 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/vtkCameraAndSelectorAction.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkCameraAndSelectorAction.java @@ -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; diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/AbstractVTKNodeMap.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/AbstractVTKNodeMap.java index 35d3105f..646fbe41 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/AbstractVTKNodeMap.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/AbstractVTKNodeMap.java @@ -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 implements VTKNodeMap< protected Session session; protected IMapping mapping; - protected InteractiveVtkPanel panel; + protected VtkView view; protected MapList nodeToActor = new MapList(); protected Map actorToNode = new HashMap(); protected ParentNode rootNode; - public AbstractVTKNodeMap(Session session, IMapping mapping, InteractiveVtkPanel panel, ParentNode rootNode) { + public AbstractVTKNodeMap(Session session, IMapping mapping, VtkView view, ParentNode 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 implements VTKNodeMap< protected abstract void updateActor(E node,Set ids); public void repaint() { - panel.repaint(); + view.refresh(); } public void populate() { @@ -128,14 +125,16 @@ public abstract class AbstractVTKNodeMap implements VTKNodeMap< @Override public void updateRenderObjectsFor(INode node) { List toDelete = new ArrayList(); + 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 coll = getActors((E)node); if (coll == null) @@ -165,7 +164,7 @@ public abstract class AbstractVTKNodeMap implements VTKNodeMap< added.add(new Pair(node, id)); rangeModified = true; } - panel.repaint(); + view.refresh(); } @SuppressWarnings("unchecked") @@ -181,7 +180,7 @@ public abstract class AbstractVTKNodeMap implements VTKNodeMap< removed.add(new Pair(node, id)); rangeModified = true; } - panel.repaint(); + view.refresh(); } @SuppressWarnings("unchecked") @@ -198,7 +197,7 @@ public abstract class AbstractVTKNodeMap implements VTKNodeMap< updated.add(node, id); rangeModified = true; } - panel.repaint(); + view.refresh(); } private boolean graphUpdates = false; @@ -461,7 +460,7 @@ public abstract class AbstractVTKNodeMap implements VTKNodeMap< @Override public void delete() { changeTracking = false; - panel.removeListener(this); + view.removeListener(this); mapping.removeMappingListener(this); List nodes = new ArrayList(nodeToActor.getKeySize()); diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/HoverHighlighter.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/HoverHighlighter.java index f80af054..7acb3f54 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/HoverHighlighter.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/HoverHighlighter.java @@ -1,55 +1,53 @@ -/******************************************************************************* - * 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; - -import vtk.vtkPanel; - -public class HoverHighlighter extends SelectionHighlighter { - - - public HoverHighlighter(vtkPanel 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); - } - -} +/******************************************************************************* + * 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); + } + +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/SelectionHighlighter.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/SelectionHighlighter.java index 95ba7aee..dec74211 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/SelectionHighlighter.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/SelectionHighlighter.java @@ -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 implements ISelectionChang - vtkPanel panel; + VtkView panel; VTKNodeMap nodeMap; List selectedNodes = new ArrayList(); @@ -48,7 +47,7 @@ public class SelectionHighlighter implements ISelectionChang HighlightObjectType type = HighlightObjectType.Node; - public SelectionHighlighter(vtkPanel panel, VTKNodeMap nodeMap) { + public SelectionHighlighter(VtkView panel, VTKNodeMap nodeMap) { this.panel = panel; this.nodeMap = nodeMap; } @@ -57,7 +56,7 @@ public class SelectionHighlighter 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 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 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 index 00000000..5bbd9c9e --- /dev/null +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/common/VtkView.java @@ -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); + +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/RotateAxisGizmo.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/RotateAxisGizmo.java index c547f513..94ea902c 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/RotateAxisGizmo.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/RotateAxisGizmo.java @@ -1,80 +1,80 @@ -/******************************************************************************* - * 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.action.RotateAction; -import org.simantics.g3d.vtk.shape.vtkShape; - -import vtk.vtkActor; -import vtk.vtkProp; - -public class RotateAxisGizmo extends vtkGizmo{ - - private List parts = new ArrayList(); - int type = -1; - - - @Override - public Collection 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(); - } - - -} +/******************************************************************************* + * 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 parts = new ArrayList(); + int type = -1; + + + @Override + public Collection 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(); + } + + +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/TranslateAxisGizmo.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/TranslateAxisGizmo.java index 0bd70cf2..64b32d3e 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/TranslateAxisGizmo.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/TranslateAxisGizmo.java @@ -1,119 +1,119 @@ -/******************************************************************************* - * 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.action.TranslateAction; -import org.simantics.g3d.vtk.shape.vtkShape; - -import vtk.vtkActor; -import vtk.vtkProp; - -public class TranslateAxisGizmo extends vtkGizmo{ - - private List parts = new ArrayList(); - int type = -1; - - - @Override - public Collection 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 (getRenderer() != null) { - deattachActors(); - attachActors(); - } - } - - -} +/******************************************************************************* + * 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 parts = new ArrayList(); + int type = -1; + + + @Override + public Collection 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(); + } + } + + +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/vtkGizmo.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/vtkGizmo.java index 0fc6dbb2..dacbc008 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/vtkGizmo.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/gizmo/vtkGizmo.java @@ -1,143 +1,151 @@ -/******************************************************************************* - * 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 vtk.vtkProp; -import vtk.vtkProp3D; -import vtk.vtkRenderer; - -public abstract class vtkGizmo implements Gizmo { - - private vtkRenderer ren1; - private Collection gizmo; - - private Tuple3d position; - private AxisAngle4d orientation; - private Tuple3d scale; - - @Override - public void attach(Object renderingPart) { - if (ren1 != null) - throw new RuntimeException("Gizmo is attached"); - ren1 = (vtkRenderer)renderingPart; - attachActors(); - } - - @Override - public void deattach() { - if (ren1 == null) - throw new RuntimeException("Gizmo is not attached"); - deattachActors(); - ren1 = null; - } - - public boolean isAttached() { - return (ren1 != null); - } - - protected void attachActors() { - gizmo = getGizmo(); - for (vtkProp p : gizmo) { - ren1.AddActor(p); - } - if (position != null) - setPosition(position); - if (orientation != null) - setRotation(orientation); - if (scale != null) - setScale(scale); - } - - protected void deattachActors() { - for (vtkProp p : gizmo) { - ren1.RemoveActor(p); - } - } - - @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 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 vtkRenderer getRenderer() { - return ren1; - } - - - -} +/******************************************************************************* + * 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 { + + private VtkView view; + private Collection 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 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; + } + + + +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/handlers/CameraPositionHandler.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/handlers/CameraPositionHandler.java index 218668ec..c3e0e54a 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/handlers/CameraPositionHandler.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/handlers/CameraPositionHandler.java @@ -1,77 +1,76 @@ -/******************************************************************************* - * 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.InteractiveVtkPanel; -import org.simantics.utils.threads.AWTThread; -import org.simantics.utils.threads.ThreadUtils; - -public class CameraPositionHandler extends AbstractHandler { - - - private Map cameraPos = new HashMap(); - - @Override - public Object execute(ExecutionEvent event) throws ExecutionException { - - final IWorkbenchPart ap = HandlerUtil.getActiveEditor(event); - final InteractiveVtkPanel panel = (InteractiveVtkPanel)ap.getAdapter(InteractiveVtkPanel.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(AWTThread.getThreadAccess(), 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.repaint(); - } - }); - - return null; - - } - - -} +/******************************************************************************* + * 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 cameraPos = new HashMap(); + + @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; + + } + + +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/handlers/ParallelPerspectiveHandler.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/handlers/ParallelPerspectiveHandler.java index aad92f98..855a0d14 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/handlers/ParallelPerspectiveHandler.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/handlers/ParallelPerspectiveHandler.java @@ -1,82 +1,82 @@ -/******************************************************************************* - * 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.InteractiveVtkPanel; -import org.simantics.utils.threads.AWTThread; -import org.simantics.utils.threads.ThreadUtils; - -public class ParallelPerspectiveHandler extends AbstractHandler { - - - private Map cameraPos = new HashMap(); - - @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 InteractiveVtkPanel panel = (InteractiveVtkPanel)ap.getAdapter(InteractiveVtkPanel.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.repaint(); - - } - }); - - return null; - - } - - - -} +/******************************************************************************* + * 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 cameraPos = new HashMap(); + + @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; + + } + + + +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/property/VTKPropertyTabContributor.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/property/VTKPropertyTabContributor.java index 10176616..7686aaa1 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/property/VTKPropertyTabContributor.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/property/VTKPropertyTabContributor.java @@ -1,121 +1,126 @@ -/******************************************************************************* - * 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.AWTThread; -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{ - - 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(AWTThread.getThreadAccess(), 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; - } - } - -} +/******************************************************************************* + * 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; + } + } + +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/shape/vtkMeshObject.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/shape/vtkMeshObject.java index 0e60a270..466d0864 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/shape/vtkMeshObject.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/shape/vtkMeshObject.java @@ -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 index 00000000..c7ed54a0 --- /dev/null +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/ContextMenuListener.java @@ -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 index 00000000..b20bcac7 --- /dev/null +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/InteractiveVtkComposite.java @@ -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 listeners = new ArrayList(); + + List list = new ArrayList(); + + 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 deletable = new ArrayList(); + + 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 picked = new ArrayList(); + 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 index 00000000..1b2d7914 --- /dev/null +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/RotateAction.java @@ -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 + * + */ +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 index 00000000..32274f03 --- /dev/null +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/TranslateAction.java @@ -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 index 00000000..5b3e3a1f --- /dev/null +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java @@ -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 selectActors = new ArrayList(); + private List hoverActor = new ArrayList(); + + @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 prevHover = new ArrayList(); + 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 getSelectActor() { + return selectActors; + } + + public List getHoverActor() { + return hoverActor; + } + + private List selectionListeners = new ArrayList(); + + @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 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 hoverListeners = new ArrayList(); + + + 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 index 00000000..9d4332c1 --- /dev/null +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkSwtAction.java @@ -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; + } + + + +} diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/utils/AxesDisplay.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/utils/AxesDisplay.java index ed1a503a..13ffac08 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/utils/AxesDisplay.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/utils/AxesDisplay.java @@ -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; } diff --git a/org.simantics.g3d/src/org/simantics/g3d/gizmo/Gizmo.java b/org.simantics.g3d/src/org/simantics/g3d/gizmo/Gizmo.java index f207dc56..9b9b0727 100644 --- a/org.simantics.g3d/src/org/simantics/g3d/gizmo/Gizmo.java +++ b/org.simantics.g3d/src/org/simantics/g3d/gizmo/Gizmo.java @@ -1,28 +1,28 @@ -/******************************************************************************* - * 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 { - - - public boolean isPartOf(T pickedObject); - - - public void attach(Object renderingPart); - public void deattach(); - - public void setPosition(Tuple3d position); - public void setRotation(AxisAngle4d q); -} +/******************************************************************************* + * 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 { + + + public boolean isPartOf(T pickedObject); + + + public void attach(T2 renderingPart); + public void deattach(); + + public void setPosition(Tuple3d position); + public void setRotation(AxisAngle4d q); +} diff --git a/org.simantics.g3d/src/org/simantics/g3d/property/AnnotatedPropertyTabContributorFactory.java b/org.simantics.g3d/src/org/simantics/g3d/property/AnnotatedPropertyTabContributorFactory.java index f5db540e..c3d7376f 100644 --- a/org.simantics.g3d/src/org/simantics/g3d/property/AnnotatedPropertyTabContributorFactory.java +++ b/org.simantics.g3d/src/org/simantics/g3d/property/AnnotatedPropertyTabContributorFactory.java @@ -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)) diff --git a/org.simantics.opencascade.vtk/META-INF/MANIFEST.MF b/org.simantics.opencascade.vtk/META-INF/MANIFEST.MF index f9a953f9..9297e52d 100644 --- a/org.simantics.opencascade.vtk/META-INF/MANIFEST.MF +++ b/org.simantics.opencascade.vtk/META-INF/MANIFEST.MF @@ -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 diff --git a/org.simantics.opencascade.vtk/src/org/simantics/opencascade/vtk/vtkSolidObject.java b/org.simantics.opencascade.vtk/src/org/simantics/opencascade/vtk/vtkSolidObject.java index f2501e95..797c9ae2 100644 --- a/org.simantics.opencascade.vtk/src/org/simantics/opencascade/vtk/vtkSolidObject.java +++ b/org.simantics.opencascade.vtk/src/org/simantics/opencascade/vtk/vtkSolidObject.java @@ -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 actors = new ArrayList(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 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 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 getActors() { - assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread()); + assert (Thread.currentThread() == panel.getThreadQueue().getThread()); return actors; } public List getSolid() { - assert (Thread.currentThread() == AWTThread.getThreadAccess().getThread()); + assert (Thread.currentThread() == panel.getThreadQueue().getThread()); return solid; } public List 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 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; diff --git a/org.simantics.plant3d/META-INF/MANIFEST.MF b/org.simantics.plant3d/META-INF/MANIFEST.MF index 2b216e01..d8f33c72 100644 --- a/org.simantics.plant3d/META-INF/MANIFEST.MF +++ b/org.simantics.plant3d/META-INF/MANIFEST.MF @@ -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, diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/actions/AddComponentAction.java b/org.simantics.plant3d/src/org/simantics/plant3d/actions/AddComponentAction.java index 4c116c1f..5aaa9c71 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/actions/AddComponentAction.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/actions/AddComponentAction.java @@ -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); } } diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java b/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java index 0310311d..da7beb45 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/actions/RoutePipeAction.java @@ -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 allowed = new HashSet(); - 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 added = new ArrayList(); @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); } diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/actions/TranslateInlineAction.java b/org.simantics.plant3d/src/org/simantics/plant3d/actions/TranslateInlineAction.java index 4ac0a0e7..23096f7e 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/actions/TranslateInlineAction.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/actions/TranslateInlineAction.java @@ -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(); diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/editor/P3DNodeMap.java b/org.simantics.plant3d/src/org/simantics/plant3d/editor/P3DNodeMap.java index 833cea3c..ea379520 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/editor/P3DNodeMap.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/editor/P3DNodeMap.java @@ -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 { 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 { } 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 { 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 { 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 p = (ParentNode)node; @@ -140,12 +139,12 @@ public class P3DNodeMap extends AbstractVTKNodeMap { 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 { updateTransform(node); - panel.unlock(); + view.unlock(); } @@ -174,7 +173,7 @@ public class P3DNodeMap extends AbstractVTKNodeMap { } private void remActor(IP3DVisualNode node) { - if (Thread.currentThread() != AWTThread.getThreadAccess().getThread()) + if (Thread.currentThread() != view.getThreadQueue().getThread()) throw new RuntimeException("Illegal thread."); List list = nodeToActor.getValues(node); @@ -183,11 +182,11 @@ public class P3DNodeMap extends AbstractVTKNodeMap { actorToNode.remove(obj); } nodeToActor.remove(node); - panel.lock(); + view.lock(); node.stopVisualize(); - panel.unlock(); + view.unlock(); } } diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java b/org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java index 033f8544..b1bb5000 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/editor/Plant3DEditor.java @@ -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 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 mapping, InteractiveVtkPanel panel, P3DRootNode rootNode) { + protected P3DNodeMap createNodeMap(Session session, IMapping 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); diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/gizmo/SplitPointSelectionGizmo.java b/org.simantics.plant3d/src/org/simantics/plant3d/gizmo/SplitPointSelectionGizmo.java index e653cf65..e5d83fb0 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/gizmo/SplitPointSelectionGizmo.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/gizmo/SplitPointSelectionGizmo.java @@ -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(); } diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/gizmo/TerminalSelectionGizmo.java b/org.simantics.plant3d/src/org/simantics/plant3d/gizmo/TerminalSelectionGizmo.java index 287ce340..f194c8db 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/gizmo/TerminalSelectionGizmo.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/gizmo/TerminalSelectionGizmo.java @@ -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 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(); diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/property/P3DSelectionProcessor.java b/org.simantics.plant3d/src/org/simantics/plant3d/property/P3DSelectionProcessor.java index 54941609..072079c2 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/property/P3DSelectionProcessor.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/property/P3DSelectionProcessor.java @@ -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 0) { diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/GeometryComponent.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/GeometryComponent.java index a11f912d..9b2b750f 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/GeometryComponent.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/GeometryComponent.java @@ -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(); } - 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) diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/GeometryNode.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/GeometryNode.java index feffaad3..54c14a14 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/GeometryNode.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/GeometryNode.java @@ -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); } diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/IP3DVisualNode.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/IP3DVisualNode.java index ff568b5c..1bd2b139 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/IP3DVisualNode.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/IP3DVisualNode.java @@ -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); diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/P3DParentGeometryNode.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/P3DParentGeometryNode.java index 26d65c7a..317904cb 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/P3DParentGeometryNode.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/P3DParentGeometryNode.java @@ -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 extends P3DParentNode } @Override - public void visualize(vtkPanel ren) { + public void visualize(VtkView ren) { updateParameters(); component.visualize(ren); } diff --git a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java index 2932f1d2..0bd02830 100644 --- a/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java +++ b/org.simantics.plant3d/src/org/simantics/plant3d/scenegraph/PipeRun.java @@ -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 { } @Override - public void visualize(vtkPanel panel) { + public void visualize(VtkView panel) { } diff --git a/pom.xml b/pom.xml index a406b5a7..0abf255b 100644 --- a/pom.xml +++ b/pom.xml @@ -101,6 +101,8 @@ org.jcae.opencascade.win32.x86_64 vtk vtk.win32.win32.x86_64 + vtk.rendering + vtk.rendering.win32.win32.x86_64 org.simantics.g3d org.simantics.g3d.csg diff --git a/vtk.lib.feature/feature.xml b/vtk.lib.feature/feature.xml index c8363ed3..0ceb16c9 100644 --- a/vtk.lib.feature/feature.xml +++ b/vtk.lib.feature/feature.xml @@ -2,7 +2,7 @@ @@ -25,6 +25,21 @@ version="0.0.0" unpack="false"/> + + + + - + diff --git a/vtk.lib.feature/pom.xml b/vtk.lib.feature/pom.xml index 1c45d5de..1bafb9f9 100644 --- a/vtk.lib.feature/pom.xml +++ b/vtk.lib.feature/pom.xml @@ -10,6 +10,6 @@ vtk.lib eclipse-feature - 5.10.0-SNAPSHOT + 8.2.0-SNAPSHOT diff --git a/vtk.rendering.win32.win32.x86_64/pom.xml b/vtk.rendering.win32.win32.x86_64/pom.xml new file mode 100644 index 00000000..e683c997 --- /dev/null +++ b/vtk.rendering.win32.win32.x86_64/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + + org.simantics.g3d + org.simantics.g3d.root + 1.0.0-SNAPSHOT + + + vtk.rendering.win32.win32.x86_64 + eclipse-plugin + 8.2.0-SNAPSHOT + + + + + org.eclipse.tycho + target-platform-configuration + + + + win32 + win32 + x86_64 + + + + + + + + \ No newline at end of file diff --git a/vtk.rendering/pom.xml b/vtk.rendering/pom.xml index 6dee25c0..db3793a3 100644 --- a/vtk.rendering/pom.xml +++ b/vtk.rendering/pom.xml @@ -10,7 +10,7 @@ 1.0.0-SNAPSHOT - vtk + vtk.rendering eclipse-plugin 8.2.0-SNAPSHOT -- 2.47.1