]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkCameraAndSelectorAction.java
Using SWT thread with Plant3d
[simantics/3d.git] / org.simantics.g3d.vtk / src / org / simantics / g3d / vtk / awt / 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.awt;
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 vtkAwtAction 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(InteractiveVtkPanel 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 void mousePressed(MouseEvent e)
89           {
90               
91             if (ren.VisibleActorCount() == 0) return;
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           }
109          
110          public void mouseReleased(MouseEvent e)
111           {
112             rw.SetDesiredUpdateRate(passiveRate);
113           }
114          
115
116          
117          public void mouseDragged(MouseEvent e)
118           {
119             if (ren.VisibleActorCount() == 0) return;
120             int x = e.getX();
121             int y = e.getY();
122             // rotate
123             if (this.InteractionMode == 1)
124               {
125                 cam.Azimuth(lastX - x);
126                 cam.Elevation(y - lastY);
127                 if (doNotRotate)
128                         cam.SetRoll(0);
129                 cam.OrthogonalizeViewUp();
130                 resetCameraClippingRange();
131                 panel.UpdateLight();
132               }
133             // translate
134             if (this.InteractionMode == 2)
135               {
136                 double  FPoint[];
137                 double  PPoint[];
138                 double  APoint[] = new double[3];
139                 double  RPoint[];
140                 double focalDepth;
141                 
142                 // get the current focal point and position
143                 FPoint = cam.GetFocalPoint();
144                 PPoint = cam.GetPosition();
145                 
146                 // calculate the focal depth since we'll be using it a lot
147                 ren.SetWorldPoint(FPoint[0],FPoint[1],FPoint[2],1.0);
148                 ren.WorldToDisplay();
149                 focalDepth = ren.GetDisplayPoint()[2];
150                 
151                 APoint[0] = rw.GetSize()[0]/2.0 + (x - lastX);
152                 APoint[1] = rw.GetSize()[1]/2.0 - (y - lastY);
153                 APoint[2] = focalDepth;
154                 ren.SetDisplayPoint(APoint);
155                 ren.DisplayToWorld();
156                 RPoint = ren.GetWorldPoint();
157                 if (RPoint[3] != 0.0)
158                   {
159                     RPoint[0] = RPoint[0]/RPoint[3];
160                     RPoint[1] = RPoint[1]/RPoint[3];
161                     RPoint[2] = RPoint[2]/RPoint[3];
162                   }
163                 
164                 /*
165                  * Compute a translation vector, moving everything 1/2 
166                  * the distance to the cursor. (Arbitrary scale factor)
167                  */
168                 cam.SetFocalPoint(
169                                   (FPoint[0]-RPoint[0])/2.0 + FPoint[0],
170                                   (FPoint[1]-RPoint[1])/2.0 + FPoint[1],
171                                   (FPoint[2]-RPoint[2])/2.0 + FPoint[2]);
172                 cam.SetPosition(
173                                 (FPoint[0]-RPoint[0])/2.0 + PPoint[0],
174                                 (FPoint[1]-RPoint[1])/2.0 + PPoint[1],
175                                 (FPoint[2]-RPoint[2])/2.0 + PPoint[2]);
176                 resetCameraClippingRange();
177               }
178             // zoom
179             if (this.InteractionMode == 3)
180               {
181                 double zoomFactor;
182                 //double clippingRange[];
183                 
184                 zoomFactor = Math.pow(1.02,(y - lastY));
185                 if (cam.GetParallelProjection() == 1)
186                   {
187                     cam.SetParallelScale(cam.GetParallelScale()/zoomFactor);
188                   }
189                 else
190                   {
191                     cam.Dolly(zoomFactor);
192                     resetCameraClippingRange();
193                   }
194               }
195             lastX = x;
196             lastY = y;
197             panel.Render();
198           }
199
200          
201                 private List<vtkProp> selectActors = new ArrayList<vtkProp>();
202                 private List<vtkProp> hoverActor = new ArrayList<vtkProp>();
203          
204                 @Override
205                 public void mouseClicked(MouseEvent e) {
206                         if (!panel.isFocusOwner())
207                                 return;
208                         if (e.getButton() != MouseEvent.BUTTON1)
209                                 return;
210                         vtkProp spick[] = panel.pick(e.getX(), e.getY());
211                         if (spick != null && spick.length > 0) {
212                                 for (vtkProp selectActor : spick) {
213                                         if (!e.isControlDown()) {
214                                                 selectActors.clear();
215                                                 selectActors.add(selectActor);
216                                         } else {
217                                                 if (selectActors.contains(selectActor))
218                                                         selectActors.remove(selectActor);
219                                                 else
220                                                         selectActors.add(selectActor);
221                                         }
222                                 }
223                                 fireSelectionChanged();
224                         } else if (!e.isControlDown()) {
225                                 selectActors.clear();
226                                 fireSelectionChanged();
227                         }
228                         
229 //                      if (e.getClickCount() > 1)
230 //                              updatePickRay(e.getX(), e.getY());
231                         
232                 }
233                 
234 //              private void updatePickRay(double x , double y) {
235 //                      Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(), x, y);
236 //                      
237 //                      
238 //                      System.out.println(ray.pos + " " + ray.dir);
239 //                      vtkPoints linePoints = new vtkPoints();
240 //                      linePoints.InsertPoint(0,ray.pos.x, ray.pos.y, ray.pos.z);
241 //                      linePoints.InsertPoint(1, ray.pos.x + ray.dir.x, ray.pos.y + ray.dir.y, ray.pos.z + ray.dir.z);
242 //                      vtkLine aLine = new vtkLine();
243 //                      aLine.GetPointIds().SetId(0, 0);
244 //                      aLine.GetPointIds().SetId(1, 1);
245 //                      vtkUnstructuredGrid aLineGrid = new vtkUnstructuredGrid();
246 //                      aLineGrid.Allocate(1, 1);
247 //                      aLineGrid.InsertNextCell(aLine.GetCellType(), aLine.GetPointIds());
248 //                      aLineGrid.SetPoints(linePoints);
249 //                      vtkDataSetMapper aLineMapper = new vtkDataSetMapper();
250 //                      aLineMapper.SetInput(aLineGrid);
251 //                      vtkActor aLineActor = new vtkActor();
252 //                      aLineActor.SetMapper(aLineMapper);
253 //                      aLineActor.GetProperty().SetDiffuseColor(.2, 1, 1);
254 //                      
255 //                  if (rayActor != null) {
256 //                      panel.GetRenderer().RemoveActor(rayActor);
257 //                      rayActor.Delete();
258 //                  }
259 //                  rayActor = aLineActor;
260 //                  panel.GetRenderer().AddActor(rayActor);
261 //                  
262 //                  linePoints.Delete();
263 //                  aLine.Delete();
264 //                  aLineGrid.Delete();
265 //                  aLineMapper.Delete();
266 //                  panel.repaint();
267 //              }
268 //              
269 //              private vtkActor rayActor;
270                 
271                 @Override
272                 public void mouseMoved(MouseEvent e) {
273                         lastX = e.getX();
274                     lastY = e.getY();
275                     
276                         if (!panel.isFocusOwner())
277                                 return;
278                         List<vtkProp> prevHover = new ArrayList<vtkProp>();
279                         prevHover.addAll(hoverActor);
280                         hoverActor.clear();
281                         vtkProp pick[] =  panel.pick(e.getX(),e.getY());
282                         if (pick != null) {
283                                 for (vtkProp p : pick)
284                                         hoverActor.add(p);
285                         }
286                                 
287                         if (!prevHover.containsAll(hoverActor) || !hoverActor.containsAll(prevHover)) {
288                                 fireHoverChanged();
289                         }
290                 }
291                 
292                 public List<vtkProp> getSelectActor() {
293                         return selectActors;
294                 }
295                 
296                 public List<vtkProp> getHoverActor() {
297                         return hoverActor;
298                 }
299                 
300                 private List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();
301                  
302                 @Override
303                 public void addSelectionChangedListener(ISelectionChangedListener listener) {
304                         selectionListeners.add(listener);
305                 }
306                 
307                 @Override
308                 public ISelection getSelection() {
309                         return new StructuredSelection(selectActors);
310                 }
311                 
312                 @Override
313                 public void removeSelectionChangedListener(
314                                 ISelectionChangedListener listener) {
315                         selectionListeners.remove(listener);
316                 }
317                 
318                 @Override
319                 public void setSelection(ISelection selection) {
320                         setSelection(selection, false);
321
322                 }
323                 
324                 public void setSelection(ISelection selection, boolean fire) {
325                         Collection<vtkProp> selectedProps = AdaptationUtils.adaptToCollection(selection, vtkProp.class);
326                         
327                         selectActors.clear();
328                         selectActors.addAll(selectedProps);
329                         if (fire)
330                                 fireSelectionChanged();
331                 }
332                 
333                 private void fireSelectionChanged() {
334                         Display.getDefault().asyncExec(new Runnable() {
335                                 @Override
336                                 public void run() {
337                                         
338                                         SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, new StructuredSelection(selectActors));
339                                         for (ISelectionChangedListener l :selectionListeners) {
340                                                 l.selectionChanged(evt);
341                                         }
342                                         
343                                 }
344                         });
345                 }
346                 
347                 
348                 private List<ISelectionChangedListener> hoverListeners = new ArrayList<ISelectionChangedListener>();
349                  
350         
351                 public void addHoverChangedListener(ISelectionChangedListener listener) {
352                         hoverListeners.add(listener);
353                 }
354                 
355                 
356                 public ISelection getHoverSelection() {
357                         return new StructuredSelection(hoverActor);
358                 }
359                 
360                 public void removeHoverChangedListener(
361                                 ISelectionChangedListener listener) {
362                         hoverListeners.remove(listener);
363                 }
364
365                 private void fireHoverChanged() {
366                         Display.getDefault().asyncExec(new Runnable() {
367                                 @Override
368                                 public void run() {
369                                         StructuredSelection sel = null;
370                                         if (hoverActor == null)
371                                                 sel = new StructuredSelection();
372                                         else
373                                                 sel = new StructuredSelection(hoverActor);
374                                         SelectionChangedEvent evt = new SelectionChangedEvent(vtkCameraAndSelectorAction.this, sel);
375                                         for (ISelectionChangedListener l :hoverListeners) {
376                                                 l.selectionChanged(evt);
377                                         }
378                                         
379                                 }
380                         });
381                 }
382                 
383                 public void focus(double x, double y, double z) {
384                         Lock();
385                         cam.SetFocalPoint(x, y, z);
386                         if (doNotRotate)
387                         cam.SetRoll(0);
388                 cam.OrthogonalizeViewUp();
389                 resetCameraClippingRange();
390                 panel.UpdateLight();
391                         UnLock();
392                 }
393                 
394                 
395 }