1 /*******************************************************************************
\r
2 * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.g3d.vtk.action;
\r
14 import java.awt.event.InputEvent;
\r
15 import java.awt.event.MouseEvent;
\r
16 import java.util.ArrayList;
\r
17 import java.util.Collection;
\r
18 import java.util.HashSet;
\r
19 import java.util.List;
\r
20 import java.util.Set;
\r
22 import org.eclipse.jface.viewers.ISelection;
\r
23 import org.eclipse.jface.viewers.ISelectionChangedListener;
\r
24 import org.eclipse.jface.viewers.ISelectionProvider;
\r
25 import org.eclipse.jface.viewers.SelectionChangedEvent;
\r
26 import org.eclipse.jface.viewers.StructuredSelection;
\r
27 import org.eclipse.swt.widgets.Display;
\r
28 import org.simantics.g3d.tools.AdaptationUtils;
\r
29 import org.simantics.g3d.vtk.common.InteractiveVtkPanel;
\r
31 import vtk.vtkActor;
\r
32 import vtk.vtkCamera;
\r
34 import vtk.vtkRenderWindow;
\r
35 import vtk.vtkRenderer;
\r
37 public class vtkCameraAndSelectorAction extends vtkAction implements ISelectionProvider {
\r
39 protected vtkRenderer ren;
\r
40 protected int lastX;
\r
41 protected int lastY;
\r
42 protected vtkRenderWindow rw;
\r
43 protected vtkCamera cam;
\r
44 protected int InteractionMode = 1;
\r
46 public vtkCameraAndSelectorAction(InteractiveVtkPanel panel) {
\r
48 this.ren = panel.GetRenderer();
\r
49 this.rw = panel.GetRenderWindow();
\r
50 this.cam = ren.GetActiveCamera();
\r
53 public void Lock() {
\r
57 public void UnLock() {
\r
61 public void InteractionModeRotate()
\r
63 this.InteractionMode = 1;
\r
66 public void InteractionModeTranslate()
\r
68 this.InteractionMode = 2;
\r
71 public void InteractionModeZoom()
\r
73 this.InteractionMode = 3;
\r
76 public void resetCameraClippingRange() {
\r
78 ren.ResetCameraClippingRange();
\r
82 public void resetCamera() {
\r
88 public void mousePressed(MouseEvent e)
\r
91 if (ren.VisibleActorCount() == 0) return;
\r
92 rw.SetDesiredUpdateRate(5.0);
\r
95 if ((e.getModifiers()==InputEvent.BUTTON2_MASK) ||
\r
96 (e.getModifiers()==(InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK)))
\r
98 InteractionModeTranslate();
\r
100 else if (e.getModifiers()==InputEvent.BUTTON3_MASK)
\r
102 InteractionModeZoom();
\r
106 InteractionModeRotate();
\r
110 public void mouseReleased(MouseEvent e)
\r
112 rw.SetDesiredUpdateRate(0.01);
\r
117 public void mouseDragged(MouseEvent e)
\r
119 if (ren.VisibleActorCount() == 0) return;
\r
123 if (this.InteractionMode == 1)
\r
125 cam.Azimuth(lastX - x);
\r
126 cam.Elevation(y - lastY);
\r
127 cam.OrthogonalizeViewUp();
\r
128 resetCameraClippingRange();
\r
129 panel.UpdateLight();
\r
132 if (this.InteractionMode == 2)
\r
136 double APoint[] = new double[3];
\r
140 // get the current focal point and position
\r
141 FPoint = cam.GetFocalPoint();
\r
142 PPoint = cam.GetPosition();
\r
144 // calculate the focal depth since we'll be using it a lot
\r
145 ren.SetWorldPoint(FPoint[0],FPoint[1],FPoint[2],1.0);
\r
146 ren.WorldToDisplay();
\r
147 focalDepth = ren.GetDisplayPoint()[2];
\r
149 APoint[0] = rw.GetSize()[0]/2.0 + (x - lastX);
\r
150 APoint[1] = rw.GetSize()[1]/2.0 - (y - lastY);
\r
151 APoint[2] = focalDepth;
\r
152 ren.SetDisplayPoint(APoint);
\r
153 ren.DisplayToWorld();
\r
154 RPoint = ren.GetWorldPoint();
\r
155 if (RPoint[3] != 0.0)
\r
157 RPoint[0] = RPoint[0]/RPoint[3];
\r
158 RPoint[1] = RPoint[1]/RPoint[3];
\r
159 RPoint[2] = RPoint[2]/RPoint[3];
\r
163 * Compute a translation vector, moving everything 1/2
\r
164 * the distance to the cursor. (Arbitrary scale factor)
\r
167 (FPoint[0]-RPoint[0])/2.0 + FPoint[0],
\r
168 (FPoint[1]-RPoint[1])/2.0 + FPoint[1],
\r
169 (FPoint[2]-RPoint[2])/2.0 + FPoint[2]);
\r
171 (FPoint[0]-RPoint[0])/2.0 + PPoint[0],
\r
172 (FPoint[1]-RPoint[1])/2.0 + PPoint[1],
\r
173 (FPoint[2]-RPoint[2])/2.0 + PPoint[2]);
\r
174 resetCameraClippingRange();
\r
177 if (this.InteractionMode == 3)
\r
180 //double clippingRange[];
\r
182 zoomFactor = Math.pow(1.02,(y - lastY));
\r
183 if (cam.GetParallelProjection() == 1)
\r
185 cam.SetParallelScale(cam.GetParallelScale()/zoomFactor);
\r
189 cam.Dolly(zoomFactor);
\r
190 resetCameraClippingRange();
\r
199 private List<vtkProp> selectActors = new ArrayList<vtkProp>();
\r
200 private List<vtkProp> hoverActor = new ArrayList<vtkProp>();
\r
203 public void mouseClicked(MouseEvent e) {
\r
204 if (!panel.isFocusOwner())
\r
206 if (e.getButton() != MouseEvent.BUTTON1)
\r
208 vtkProp spick[] = panel.pick(e.getX(), e.getY());
\r
209 if (spick != null && spick.length > 0) {
\r
210 for (vtkProp selectActor : spick) {
\r
211 if (!e.isControlDown()) {
\r
212 selectActors.clear();
\r
213 selectActors.add(selectActor);
\r
215 if (selectActors.contains(selectActor))
\r
216 selectActors.remove(selectActor);
\r
218 selectActors.add(selectActor);
\r
221 fireSelectionChanged();
\r
222 } else if (!e.isControlDown()) {
\r
223 selectActors.clear();
\r
224 fireSelectionChanged();
\r
227 // if (e.getClickCount() > 1)
\r
228 // updatePickRay(e.getX(), e.getY());
\r
232 // private void updatePickRay(double x , double y) {
\r
233 // Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(), x, y);
\r
236 // System.out.println(ray.pos + " " + ray.dir);
\r
237 // vtkPoints linePoints = new vtkPoints();
\r
238 // linePoints.InsertPoint(0,ray.pos.x, ray.pos.y, ray.pos.z);
\r
239 // linePoints.InsertPoint(1, ray.pos.x + ray.dir.x, ray.pos.y + ray.dir.y, ray.pos.z + ray.dir.z);
\r
240 // vtkLine aLine = new vtkLine();
\r
241 // aLine.GetPointIds().SetId(0, 0);
\r
242 // aLine.GetPointIds().SetId(1, 1);
\r
243 // vtkUnstructuredGrid aLineGrid = new vtkUnstructuredGrid();
\r
244 // aLineGrid.Allocate(1, 1);
\r
245 // aLineGrid.InsertNextCell(aLine.GetCellType(), aLine.GetPointIds());
\r
246 // aLineGrid.SetPoints(linePoints);
\r
247 // vtkDataSetMapper aLineMapper = new vtkDataSetMapper();
\r
248 // aLineMapper.SetInput(aLineGrid);
\r
249 // vtkActor aLineActor = new vtkActor();
\r
250 // aLineActor.SetMapper(aLineMapper);
\r
251 // aLineActor.GetProperty().SetDiffuseColor(.2, 1, 1);
\r
253 // if (rayActor != null) {
\r
254 // panel.GetRenderer().RemoveActor(rayActor);
\r
255 // rayActor.Delete();
\r
257 // rayActor = aLineActor;
\r
258 // panel.GetRenderer().AddActor(rayActor);
\r
260 // linePoints.Delete();
\r
262 // aLineGrid.Delete();
\r
263 // aLineMapper.Delete();
\r
264 // panel.repaint();
\r
267 // private vtkActor rayActor;
\r
270 public void mouseMoved(MouseEvent e) {
\r
274 if (!panel.isFocusOwner())
\r
276 List<vtkProp> prevHover = new ArrayList<vtkProp>();
\r
277 prevHover.addAll(hoverActor);
\r
278 hoverActor.clear();
\r
279 vtkProp pick[] = panel.pick(e.getX(),e.getY());
\r
280 if (pick != null) {
\r
281 for (vtkProp p : pick)
\r
285 if (!prevHover.containsAll(hoverActor) || !hoverActor.containsAll(prevHover)) {
\r
286 fireHoverChanged();
\r
290 public List<vtkProp> getSelectActor() {
\r
291 return selectActors;
\r
294 public List<vtkProp> getHoverActor() {
\r
298 private List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();
\r
301 public void addSelectionChangedListener(ISelectionChangedListener listener) {
\r
302 selectionListeners.add(listener);
\r
306 public ISelection getSelection() {
\r
307 return new StructuredSelection(selectActors);
\r
311 public void removeSelectionChangedListener(
\r
312 ISelectionChangedListener listener) {
\r
313 selectionListeners.remove(listener);
\r
317 public void setSelection(ISelection selection) {
\r
318 setSelection(selection, false);
\r
322 public void setSelection(ISelection selection, boolean fire) {
\r
323 Collection<vtkProp> selectedProps = AdaptationUtils.adaptToCollection(selection, vtkProp.class);
\r
325 selectActors.clear();
\r
326 selectActors.addAll(selectedProps);
\r
328 fireSelectionChanged();
\r
331 private void fireSelectionChanged() {
\r
332 Display.getDefault().asyncExec(new Runnable() {
\r
334 public void run() {
\r
336 SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, new StructuredSelection(selectActors));
\r
337 for (ISelectionChangedListener l :selectionListeners) {
\r
338 l.selectionChanged(evt);
\r
346 private List<ISelectionChangedListener> hoverListeners = new ArrayList<ISelectionChangedListener>();
\r
349 public void addHoverChangedListener(ISelectionChangedListener listener) {
\r
350 hoverListeners.add(listener);
\r
354 public ISelection getHoverSelection() {
\r
355 return new StructuredSelection(hoverActor);
\r
358 public void removeHoverChangedListener(
\r
359 ISelectionChangedListener listener) {
\r
360 hoverListeners.remove(listener);
\r
363 private void fireHoverChanged() {
\r
364 Display.getDefault().asyncExec(new Runnable() {
\r
366 public void run() {
\r
367 StructuredSelection sel = null;
\r
368 if (hoverActor == null)
\r
369 sel = new StructuredSelection();
\r
371 sel = new StructuredSelection(hoverActor);
\r
372 SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, sel);
\r
373 for (ISelectionChangedListener l :hoverListeners) {
\r
374 l.selectionChanged(evt);
\r