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