]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/InteractiveVtkComposite.java
DPI scaling for vtkView
[simantics/3d.git] / org.simantics.g3d.vtk / src / org / simantics / g3d / vtk / swt / InteractiveVtkComposite.java
1 package org.simantics.g3d.vtk.swt;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.eclipse.core.runtime.Platform;
7 import org.eclipse.swt.internal.DPIUtil;
8 import org.eclipse.swt.widgets.Composite;
9 import org.simantics.g3d.scenegraph.RenderListener;
10 import org.simantics.g3d.vtk.action.vtkAction;
11 import org.simantics.g3d.vtk.common.VtkView;
12 import org.simantics.utils.threads.IThreadWorkQueue;
13 import org.simantics.utils.threads.SWTThread;
14 import org.simantics.utils.threads.ThreadUtils;
15
16 import vtk.vtkAbstractPicker;
17 import vtk.vtkActor2D;
18 import vtk.vtkActor2DCollection;
19 import vtk.vtkAreaPicker;
20 import vtk.vtkAssemblyNode;
21 import vtk.vtkAssemblyPath;
22 import vtk.vtkCellPicker;
23 import vtk.vtkObject;
24 import vtk.vtkObjectBase;
25 import vtk.vtkPointPicker;
26 import vtk.vtkProp;
27 import vtk.vtkProp3DCollection;
28 import vtk.vtkPropCollection;
29 import vtk.vtkPropPicker;
30 import vtk.vtkRenderWindow;
31 import vtk.vtkRenderer;
32 import vtk.vtkScenePicker;
33 import vtk.rendering.swt.vtkSwtComponent;
34
35 public class InteractiveVtkComposite extends vtkSwtComponent implements VtkView{
36         
37         Composite parentComposite;
38         public InteractiveVtkComposite(Composite parentComposite) {
39                 super(parentComposite);
40                 this.parentComposite = parentComposite;
41
42                 if (!Platform.inDevelopmentMode()) {
43                         // This is actually a static method in C++
44                         new vtkObject().GlobalWarningDisplayOff();
45                 }
46         }
47         
48         private boolean updating = false;
49         private Object mutex = new Object();
50         
51         @Override
52         public void refresh() {
53 //              if (Thread.currentThread() == getThreadQueue().getThread())
54 //                      update();
55 //              else {
56                         synchronized (mutex) {
57                                 if (!updating) {
58                                         updating = true;
59                                         ThreadUtils.asyncExec(getThreadQueue(), new Runnable() {
60                                                 
61                                                 @Override
62                                                 public void run() {
63                                                         if (parentComposite.isDisposed())
64                                                                 return;
65                                                         synchronized (mutex) {
66                                                                 updating = false;
67                                                         }
68                                                         update();
69                                                 }
70                                         });
71                                         
72                                 }
73                         }
74 //              }
75         }
76         
77         boolean update = false;
78         @Override
79         public void update() {
80                 if (update)
81                         return;
82                 update = true;
83                 super.update();
84                 update = false;
85         }
86         
87         @Override
88         public IThreadWorkQueue getThreadQueue() {
89                 return SWTThread.getThreadAccess();
90         }
91         
92
93         boolean render = false;
94         @Override
95         public void Render() {
96                 if (render)
97                         return;
98 //              System.out.println(getClass().getSimpleName() +" render");
99                 render = true;
100                 firePreRender();
101                 super.Render();
102                 firePostRender();
103                 render = false;
104         }
105
106         public void addListener(RenderListener l) {
107                 listeners.add(l);
108         }
109         
110         public void removeListener(RenderListener l) {
111                 listeners.remove(l);
112         }
113         
114         private List<RenderListener> listeners = new ArrayList<RenderListener>();
115         
116         List<RenderListener> list = new ArrayList<RenderListener>();
117         
118         private void firePreRender() {
119                 if (listeners.size() > 0) {
120                         list.addAll(listeners);
121                         for (RenderListener l : list)
122                                 l.preRender();
123                         list.clear();
124                 }
125         }
126         
127         private void firePostRender() {
128                 if (listeners.size() > 0) {
129                         list.addAll(listeners);
130                         for (RenderListener l : list)
131                                 l.postRender();
132                         list.clear();
133                 }
134         }
135
136         
137         private List<vtkObjectBase> deletable = new ArrayList<vtkObjectBase>();
138         
139         public void addDeletable(vtkObjectBase o) {
140                 deletable.add(o);
141         }
142         
143         public void removeDeletable (vtkObjectBase o) {
144                 deletable.remove(o);
145         }
146         
147         @Override
148         public void Delete() {
149                 for (vtkObjectBase o : deletable) {
150                         if (o.GetVTKId() != 0) {
151                                 o.Delete();
152                         }
153                 }
154                 deletable.clear();
155                 
156                 super.Delete();
157         }
158         
159         private vtkSwtAction defaultAction;
160         private vtkSwtAction currentAction;
161         
162         public void setActiveAction(vtkAction action) {
163                 if (action.equals(currentAction))
164                         return;
165                 if (currentAction != null)
166                         currentAction.deattach();
167                 currentAction = (vtkSwtAction)action;
168                 if (action != null)
169                         action.attach();
170         }
171         
172         public void setDefaultAction(vtkAction defaultAction) {
173                 this.defaultAction = (vtkSwtAction)defaultAction;
174         }
175         
176         public void useDefaultAction() {
177                 setActiveAction(defaultAction);
178         }
179         
180         public vtkAction getDefaultAction() {
181                 return defaultAction;
182         }
183         
184         public void lock() {
185                 getVTKLock().lock();
186         }
187         
188         public void unlock() {
189                 getVTKLock().unlock();
190         }
191         
192         private vtkScenePicker scenePicker;
193         
194         int pickType = 4;
195         
196         public int getPickType() {
197                 return pickType;
198         }
199         
200         public void setPickType(int pickType) {
201                 this.pickType = pickType;
202         }
203         
204         public vtkProp[] pick(int x, int y) {
205                 
206                 
207                 vtkRenderWindow rw = getRenderWindow();
208                 vtkRenderer ren = getRenderer();
209                 
210                 int ax = x;
211                 int ay = rw.GetSize()[1] - y;
212
213                 if (pickType == 0) {
214                         throw new IllegalStateException("SWT Binding does not work with hw picking");
215 //                      lock();
216 //                      ren.BreakOnError();
217 //                      ren.DrawOff();
218 //                      vtkPropPicker picker = new vtkPropPicker();
219 //                      picker.DebugOn();
220 //                      //picker.PickProp(x, rw.GetSize()[1] - y, ren);
221 //                      picker.Pick(x, rw.GetSize()[1] - y,0, ren);
222 //                      ren.DrawOn();
223 //                      unlock();
224 //      
225 //                      vtkAssemblyPath apath = picker.GetPath();
226 //                      return processPick(picker, apath);
227 //                      
228                 } else if (pickType == 1) {
229                         throw new IllegalStateException("SWT Binding does not work with hw picking");
230 //                      if (scenePicker == null) {
231 //                              scenePicker = new vtkScenePicker();
232 //                              scenePicker.SetRenderer(ren);
233 //                              scenePicker.EnableVertexPickingOn();
234 //                              
235 //                      }
236 //                      lock();
237 //
238 //                      vtkAssemblyPath apath = ren.PickProp(ax, ay);
239 //                      
240 //                      unlock();
241 //                      
242 //                      if (apath != null) {
243 //                              apath.InitTraversal();
244 //                              vtkAssemblyNode node = apath.GetLastNode();
245 //                              vtkProp test = (vtkProp) node.GetViewProp();
246 //                              apath.Delete();
247 //                              node.Delete();
248 //                              return new vtkProp[]{test};
249 //      
250 //                      }
251                         
252                 } else if (pickType == 2) {
253                         vtkPointPicker picker = new vtkPointPicker();
254                         //picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
255                         picker.SetTolerance(0.00001);
256                         lock();
257                         picker.Pick(new double[]{ax, ay,0}, ren);
258                         unlock();
259                         
260                         vtkAssemblyPath apath = picker.GetPath();
261                         return processPick(picker, apath);
262                 } else if (pickType == 3) {
263                         vtkAreaPicker picker = new vtkAreaPicker();
264                         lock();
265                         picker.Pick(new double[]{ax, ay,0}, ren);
266                         unlock();
267                         vtkAssemblyPath apath = picker.GetPath();
268                         return processPick(picker, apath);
269                 } else if (pickType == 4) {
270                         vtkCellPicker picker = new vtkCellPicker();
271                         picker.SetTolerance(0.00001);
272                         lock();
273                         picker.Pick(new double[]{ax, ay,0}, ren);
274                         unlock();       
275                         vtkAssemblyPath apath = picker.GetPath();
276                         return processPick(picker, apath);
277                 } else if (pickType == 5) {
278                         vtkActor2DCollection coll = ren.GetActors2D(); 
279                         coll.InitTraversal();
280                         vtkActor2D a;
281                         
282                         List<vtkActor2D> picked = new ArrayList<vtkActor2D>();
283                         while ((a = coll.GetNextItem()) != null) {
284                                 double pos[] = a.GetPosition();
285                                 // TODO : width and height do not seem to affect the perceived size of Actor2D.
286                                 //        actual size should be fetched from mapper. 
287                                 double w = a.GetWidth();
288                                 double h = a.GetHeight();
289                                 int minx = (int)(pos[0]-w*0.5);
290                                 int miny = (int)(pos[1]-h*0.5);
291                                 int maxx = (int)(pos[0]+w*0.5);
292                                 int maxy = (int)(pos[1]+h*0.5);
293                                 if (minx <= ax && maxx >= ax &&
294                                         miny <= ay && maxy >= ay) {
295                                         picked.add(a);
296                                 }
297                         }
298                         return picked.toArray(new vtkProp[picked.size()]);
299                 }
300
301                 return null;
302         }
303         
304         public vtkProp[] pick2(int x, int y) {
305                 vtkRenderWindow rw = getRenderWindow();
306                 vtkRenderer ren = getRenderer();
307                 
308 //              vtkPicker picker = new vtkPicker();
309 //              vtkAbstractPicker picker = new vtkAbstractPicker();
310 //              picker.Pick(x, rw.GetSize()[1] - y, ren);
311 //              // see page 60 of VTK user's guide
312 //
313                 if (pickType == 0) {
314         
315                         vtkPropPicker picker = new vtkPropPicker();
316                         lock();
317                         picker.PickProp(x, rw.GetSize()[1] - y, ren);
318         
319                         unlock();
320                         vtkPropCollection coll = picker.GetPickList();
321                         return processPick(picker, coll);
322                         
323                 } else if (pickType == 1) {
324                         if (scenePicker == null) {
325                                 scenePicker = new vtkScenePicker();
326                                 scenePicker.SetRenderer(ren);
327                                 scenePicker.EnableVertexPickingOn();
328                                 scenePicker.DebugOn();
329                                 
330                         }
331                         lock();
332
333                         
334                         vtkAssemblyPath apath = ren.PickProp(x, rw.GetSize()[1] - y);
335                         
336                         unlock();
337                         
338                         if (apath != null) {
339                                 apath.InitTraversal();
340
341                                 
342                                 vtkAssemblyNode node = apath.GetLastNode();
343                                 vtkProp test = (vtkProp) node.GetViewProp();
344                                 apath.Delete();
345                                 node.Delete();
346                                 return new vtkProp[]{test};
347         
348                         }
349                         
350                 } else if (pickType == 2) {
351                         vtkPointPicker picker = new vtkPointPicker();
352                         picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
353                         lock();
354                         picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
355                         unlock();
356                         vtkProp3DCollection coll = picker.GetProp3Ds();
357                         return processPick(picker, coll);
358                 } else if (pickType == 3) {
359                         vtkAreaPicker picker = new vtkAreaPicker();
360                         lock();
361                         picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
362                         //picker.AreaPick(x-1, rw.GetSize()[1] - y-1,x+1,rw.GetSize()[1] - y+1, ren);
363                         unlock();
364                         vtkProp3DCollection coll = picker.GetProp3Ds();
365                         return processPick(picker, coll);
366                 } else if (pickType == 4) {
367                         vtkCellPicker picker = new vtkCellPicker();
368                         picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
369                         lock();
370                         picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
371                         unlock();       
372                         vtkProp3DCollection coll = picker.GetProp3Ds();
373                         return processPick(picker, coll);
374                 }
375
376                 return null;
377         }
378         
379         private vtkProp[] processPick(vtkAbstractPicker picker, vtkAssemblyPath apath) {
380 //              double[] pickPos = picker.GetPickPosition();
381                 picker.Delete();
382                 if (apath != null) {
383                         apath.InitTraversal();
384                         vtkProp result[] = new vtkProp[apath.GetNumberOfItems()];
385                         for (int i = apath.GetNumberOfItems()-1; i >= 0; i--) {
386                                 vtkAssemblyNode node = apath.GetNextNode();
387                                 vtkProp test = (vtkProp) node.GetViewProp();
388 //                              System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());
389                                 result[i] = test;
390                                 node.Delete();
391                         }
392                         apath.Delete();
393                         return result;
394
395                 }
396                 return null;
397         }
398         
399         private vtkProp[] processPick(vtkAbstractPicker picker, vtkPropCollection coll) {
400 //              double[] pickPos = picker.GetPickPosition();
401                 picker.Delete();
402                 if (coll != null) {
403                         coll.InitTraversal();
404                         vtkProp result[] = new vtkProp[coll.GetNumberOfItems()];
405                         for (int i = coll.GetNumberOfItems()-1; i >= 0; i--) {
406                                 vtkProp test = coll.GetNextProp();
407                                 
408 //                              System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());
409                                 result[i] = test;
410                                 
411                         }
412                         coll.Delete();
413                         return result;
414
415                 }
416                 return null;
417         }
418         
419         @Override
420         public int upscale(int i) {
421                 return DPIUtil.autoScaleUp(i);
422         }
423         
424         @Override
425         public double upscale(double d) {
426                 return (double)DPIUtil.autoScaleUp((float)d);
427         }
428         
429         
430         
431 }