]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/vtkCameraAndSelectorAction.java
Using SWT thread with Plant3d
[simantics/3d.git] / org.simantics.g3d.vtk / src / org / simantics / g3d / vtk / swt / vtkCameraAndSelectorAction.java
1 /*******************************************************************************
2  * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.g3d.vtk.swt;
13
14 import java.awt.event.InputEvent;
15 import java.awt.event.MouseEvent;
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.List;
19
20 import org.eclipse.jface.viewers.ISelection;
21 import org.eclipse.jface.viewers.ISelectionChangedListener;
22 import org.eclipse.jface.viewers.ISelectionProvider;
23 import org.eclipse.jface.viewers.SelectionChangedEvent;
24 import org.eclipse.jface.viewers.StructuredSelection;
25 import org.eclipse.swt.widgets.Display;
26 import org.simantics.g3d.tools.AdaptationUtils;
27
28 import vtk.vtkCamera;
29 import vtk.vtkProp;
30 import vtk.vtkRenderWindow;
31 import vtk.vtkRenderer;
32
33 public class vtkCameraAndSelectorAction extends vtkSwtAction implements ISelectionProvider {
34         
35         protected vtkRenderer ren;
36         protected int lastX;
37         protected int lastY;
38         protected vtkRenderWindow rw;
39         protected vtkCamera cam;
40         protected int InteractionMode = 1;
41         
42         protected double activeRate = 5.0;
43         protected double passiveRate = 0.01;
44         protected boolean doNotRotate = true; 
45         
46         public vtkCameraAndSelectorAction(InteractiveVtkComposite panel) {
47                 super(panel);
48                 this.ren = panel.getRenderer();
49                 this.rw = panel.getRenderWindow();
50                 this.cam = ren.GetActiveCamera();
51         }
52         
53         public void Lock() {
54                 panel.lock();
55         }
56         
57         public void UnLock() {
58                 panel.unlock();
59         }
60         
61         public void InteractionModeRotate()
62           {
63             this.InteractionMode = 1;
64           }
65           
66           public void InteractionModeTranslate()
67           {
68             this.InteractionMode = 2;
69           }
70           
71           public void InteractionModeZoom()
72           {
73             this.InteractionMode = 3;
74           }
75           
76         public void resetCameraClippingRange() {
77             Lock();
78             ren.ResetCameraClippingRange();
79             UnLock();
80           }
81
82           public void resetCamera() {
83             Lock();
84             ren.ResetCamera();
85             UnLock();
86           }
87           
88          public boolean mousePressed(MouseEvent e)
89           {
90               
91             if (ren.VisibleActorCount() == 0) return false;
92             rw.SetDesiredUpdateRate(activeRate);
93             lastX = e.getX();
94             lastY = e.getY();
95             if ((e.getModifiers()==InputEvent.BUTTON2_MASK) ||
96                 (e.getModifiers()==(InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK)))
97               {
98                 InteractionModeTranslate();
99               }
100             else if (e.getModifiers()==InputEvent.BUTTON3_MASK)
101               {
102                 InteractionModeZoom();
103               }
104             else 
105               {
106                 InteractionModeRotate();
107               }
108             return true;
109           }
110          
111          public boolean mouseReleased(MouseEvent e)
112           {
113             rw.SetDesiredUpdateRate(passiveRate);
114             return true;
115           }
116          
117
118          
119          public boolean mouseDragged(MouseEvent e)
120           {
121             if (ren.VisibleActorCount() == 0) return false;
122             int x = e.getX();
123             int y = e.getY();
124             // rotate
125             if (this.InteractionMode == 1)
126               {
127                 cam.Azimuth(lastX - x);
128                 cam.Elevation(y - lastY);
129                 if (doNotRotate)
130                         cam.SetRoll(0);
131                 cam.OrthogonalizeViewUp();
132                 resetCameraClippingRange();
133                 //panel.UpdateLight();
134               }
135             // translate
136             if (this.InteractionMode == 2)
137               {
138                 double  FPoint[];
139                 double  PPoint[];
140                 double  APoint[] = new double[3];
141                 double  RPoint[];
142                 double focalDepth;
143                 
144                 // get the current focal point and position
145                 FPoint = cam.GetFocalPoint();
146                 PPoint = cam.GetPosition();
147                 
148                 // calculate the focal depth since we'll be using it a lot
149                 ren.SetWorldPoint(FPoint[0],FPoint[1],FPoint[2],1.0);
150                 ren.WorldToDisplay();
151                 focalDepth = ren.GetDisplayPoint()[2];
152                 
153                 APoint[0] = rw.GetSize()[0]/2.0 + (x - lastX);
154                 APoint[1] = rw.GetSize()[1]/2.0 - (y - lastY);
155                 APoint[2] = focalDepth;
156                 ren.SetDisplayPoint(APoint);
157                 ren.DisplayToWorld();
158                 RPoint = ren.GetWorldPoint();
159                 if (RPoint[3] != 0.0)
160                   {
161                     RPoint[0] = RPoint[0]/RPoint[3];
162                     RPoint[1] = RPoint[1]/RPoint[3];
163                     RPoint[2] = RPoint[2]/RPoint[3];
164                   }
165                 
166                 /*
167                  * Compute a translation vector, moving everything 1/2 
168                  * the distance to the cursor. (Arbitrary scale factor)
169                  */
170                 cam.SetFocalPoint(
171                                   (FPoint[0]-RPoint[0])/2.0 + FPoint[0],
172                                   (FPoint[1]-RPoint[1])/2.0 + FPoint[1],
173                                   (FPoint[2]-RPoint[2])/2.0 + FPoint[2]);
174                 cam.SetPosition(
175                                 (FPoint[0]-RPoint[0])/2.0 + PPoint[0],
176                                 (FPoint[1]-RPoint[1])/2.0 + PPoint[1],
177                                 (FPoint[2]-RPoint[2])/2.0 + PPoint[2]);
178                 resetCameraClippingRange();
179               }
180             // zoom
181             if (this.InteractionMode == 3)
182               {
183                 double zoomFactor;
184                 //double clippingRange[];
185                 
186                 zoomFactor = Math.pow(1.02,(y - lastY));
187                 if (cam.GetParallelProjection() == 1)
188                   {
189                     cam.SetParallelScale(cam.GetParallelScale()/zoomFactor);
190                   }
191                 else
192                   {
193                     cam.Dolly(zoomFactor);
194                     resetCameraClippingRange();
195                   }
196               }
197             lastX = x;
198             lastY = y;
199             panel.refresh();
200             return true;
201           }
202
203          
204                 private List<vtkProp> selectActors = new ArrayList<vtkProp>();
205                 private List<vtkProp> hoverActor = new ArrayList<vtkProp>();
206          
207                 @Override
208                 public boolean mouseClicked(MouseEvent e) {
209                         if (!panel.getComponent().isFocusControl())
210                                 return false;
211                         if (e.getButton() != MouseEvent.BUTTON1)
212                                 return false;
213                         vtkProp spick[] = panel.pick(e.getX(), e.getY());
214                         if (spick != null && spick.length > 0) {
215                                 for (vtkProp selectActor : spick) {
216                                         if (!e.isControlDown()) {
217                                                 selectActors.clear();
218                                                 selectActors.add(selectActor);
219                                         } else {
220                                                 if (selectActors.contains(selectActor))
221                                                         selectActors.remove(selectActor);
222                                                 else
223                                                         selectActors.add(selectActor);
224                                         }
225                                 }
226                                 fireSelectionChanged();
227                         } else if (!e.isControlDown()) {
228                                 selectActors.clear();
229                                 fireSelectionChanged();
230                         }
231                         return true;
232 //                      if (e.getClickCount() > 1)
233 //                              updatePickRay(e.getX(), e.getY());
234                         
235                 }
236                 
237 //              private void updatePickRay(double x , double y) {
238 //                      Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(), x, y);
239 //                      
240 //                      
241 //                      System.out.println(ray.pos + " " + ray.dir);
242 //                      vtkPoints linePoints = new vtkPoints();
243 //                      linePoints.InsertPoint(0,ray.pos.x, ray.pos.y, ray.pos.z);
244 //                      linePoints.InsertPoint(1, ray.pos.x + ray.dir.x, ray.pos.y + ray.dir.y, ray.pos.z + ray.dir.z);
245 //                      vtkLine aLine = new vtkLine();
246 //                      aLine.GetPointIds().SetId(0, 0);
247 //                      aLine.GetPointIds().SetId(1, 1);
248 //                      vtkUnstructuredGrid aLineGrid = new vtkUnstructuredGrid();
249 //                      aLineGrid.Allocate(1, 1);
250 //                      aLineGrid.InsertNextCell(aLine.GetCellType(), aLine.GetPointIds());
251 //                      aLineGrid.SetPoints(linePoints);
252 //                      vtkDataSetMapper aLineMapper = new vtkDataSetMapper();
253 //                      aLineMapper.SetInput(aLineGrid);
254 //                      vtkActor aLineActor = new vtkActor();
255 //                      aLineActor.SetMapper(aLineMapper);
256 //                      aLineActor.GetProperty().SetDiffuseColor(.2, 1, 1);
257 //                      
258 //                  if (rayActor != null) {
259 //                      panel.GetRenderer().RemoveActor(rayActor);
260 //                      rayActor.Delete();
261 //                  }
262 //                  rayActor = aLineActor;
263 //                  panel.GetRenderer().AddActor(rayActor);
264 //                  
265 //                  linePoints.Delete();
266 //                  aLine.Delete();
267 //                  aLineGrid.Delete();
268 //                  aLineMapper.Delete();
269 //                  panel.repaint();
270 //              }
271 //              
272 //              private vtkActor rayActor;
273                 
274                 @Override
275                 public boolean mouseMoved(MouseEvent e) {
276                         lastX = e.getX();
277                     lastY = e.getY();
278                     
279                     if (!panel.getComponent().isFocusControl())
280                                 return false;
281                         List<vtkProp> prevHover = new ArrayList<vtkProp>();
282                         prevHover.addAll(hoverActor);
283                         hoverActor.clear();
284                         vtkProp pick[] =  panel.pick(e.getX(),e.getY());
285                         if (pick != null) {
286                                 for (vtkProp p : pick)
287                                         hoverActor.add(p);
288                         }
289                                 
290                         if (!prevHover.containsAll(hoverActor) || !hoverActor.containsAll(prevHover)) {
291                                 fireHoverChanged();
292                         }
293                         return true;
294                 }
295                 
296                 public List<vtkProp> getSelectActor() {
297                         return selectActors;
298                 }
299                 
300                 public List<vtkProp> getHoverActor() {
301                         return hoverActor;
302                 }
303                 
304                 private List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();
305                  
306                 @Override
307                 public void addSelectionChangedListener(ISelectionChangedListener listener) {
308                         selectionListeners.add(listener);
309                 }
310                 
311                 @Override
312                 public ISelection getSelection() {
313                         return new StructuredSelection(selectActors);
314                 }
315                 
316                 @Override
317                 public void removeSelectionChangedListener(
318                                 ISelectionChangedListener listener) {
319                         selectionListeners.remove(listener);
320                 }
321                 
322                 @Override
323                 public void setSelection(ISelection selection) {
324                         setSelection(selection, false);
325
326                 }
327                 
328                 public void setSelection(ISelection selection, boolean fire) {
329                         Collection<vtkProp> selectedProps = AdaptationUtils.adaptToCollection(selection, vtkProp.class);
330                         
331                         selectActors.clear();
332                         selectActors.addAll(selectedProps);
333                         if (fire)
334                                 fireSelectionChanged();
335                 }
336                 
337                 private void fireSelectionChanged() {
338                         Display.getDefault().asyncExec(new Runnable() {
339                                 @Override
340                                 public void run() {
341                                         
342                                         SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, new StructuredSelection(selectActors));
343                                         for (ISelectionChangedListener l :selectionListeners) {
344                                                 l.selectionChanged(evt);
345                                         }
346                                         
347                                 }
348                         });
349                 }
350                 
351                 
352                 private List<ISelectionChangedListener> hoverListeners = new ArrayList<ISelectionChangedListener>();
353                  
354         
355                 public void addHoverChangedListener(ISelectionChangedListener listener) {
356                         hoverListeners.add(listener);
357                 }
358                 
359                 
360                 public ISelection getHoverSelection() {
361                         return new StructuredSelection(hoverActor);
362                 }
363                 
364                 public void removeHoverChangedListener(
365                                 ISelectionChangedListener listener) {
366                         hoverListeners.remove(listener);
367                 }
368
369                 private void fireHoverChanged() {
370                         Display.getDefault().asyncExec(new Runnable() {
371                                 @Override
372                                 public void run() {
373                                         StructuredSelection sel = null;
374                                         if (hoverActor == null)
375                                                 sel = new StructuredSelection();
376                                         else
377                                                 sel = new StructuredSelection(hoverActor);
378                                         SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, sel);
379                                         for (ISelectionChangedListener l :hoverListeners) {
380                                                 l.selectionChanged(evt);
381                                         }
382                                         
383                                 }
384                         });
385                 }
386                 
387                 public void focus(double x, double y, double z) {
388                         Lock();
389                         cam.SetFocalPoint(x, y, z);
390                         if (doNotRotate)
391                         cam.SetRoll(0);
392                 cam.OrthogonalizeViewUp();
393                 resetCameraClippingRange();
394                 //panel.UpdateLight();
395                         UnLock();
396                 }
397                 
398                 
399 }