]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/swt/InteractiveVtkComposite.java
3963f16507923e419b78b430bee59c160217b561
[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         }
183         
184         public void unlock() {
185                 getVTKLock().unlock();
186         }
187         
188         private vtkScenePicker scenePicker;
189         
190         int pickType = 4;
191         
192         public int getPickType() {
193                 return pickType;
194         }
195         
196         public void setPickType(int pickType) {
197                 this.pickType = pickType;
198         }
199         
200         public vtkProp[] pick(int x, int y) {
201                 
202                 
203                 vtkRenderWindow rw = getRenderWindow();
204                 vtkRenderer ren = getRenderer();
205                 
206                 int ax = x;
207                 int ay = rw.GetSize()[1] - y;
208
209                 if (pickType == 0) {
210                         throw new IllegalStateException("SWT Binding does not work with hw picking");
211 //                      lock();
212 //                      ren.BreakOnError();
213 //                      ren.DrawOff();
214 //                      vtkPropPicker picker = new vtkPropPicker();
215 //                      picker.DebugOn();
216 //                      //picker.PickProp(x, rw.GetSize()[1] - y, ren);
217 //                      picker.Pick(x, rw.GetSize()[1] - y,0, ren);
218 //                      ren.DrawOn();
219 //                      unlock();
220 //      
221 //                      vtkAssemblyPath apath = picker.GetPath();
222 //                      return processPick(picker, apath);
223 //                      
224                 } else if (pickType == 1) {
225                         throw new IllegalStateException("SWT Binding does not work with hw picking");
226 //                      if (scenePicker == null) {
227 //                              scenePicker = new vtkScenePicker();
228 //                              scenePicker.SetRenderer(ren);
229 //                              scenePicker.EnableVertexPickingOn();
230 //                              
231 //                      }
232 //                      lock();
233 //
234 //                      vtkAssemblyPath apath = ren.PickProp(ax, ay);
235 //                      
236 //                      unlock();
237 //                      
238 //                      if (apath != null) {
239 //                              apath.InitTraversal();
240 //                              vtkAssemblyNode node = apath.GetLastNode();
241 //                              vtkProp test = (vtkProp) node.GetViewProp();
242 //                              apath.Delete();
243 //                              node.Delete();
244 //                              return new vtkProp[]{test};
245 //      
246 //                      }
247                         
248                 } else if (pickType == 2) {
249                         vtkPointPicker picker = new vtkPointPicker();
250                         //picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
251                         picker.SetTolerance(0.00001);
252                         lock();
253                         picker.Pick(new double[]{ax, ay,0}, ren);
254                         unlock();
255                         
256                         vtkAssemblyPath apath = picker.GetPath();
257                         return processPick(picker, apath);
258                 } else if (pickType == 3) {
259                         vtkAreaPicker picker = new vtkAreaPicker();
260                         lock();
261                         picker.Pick(new double[]{ax, ay,0}, ren);
262                         unlock();
263                         vtkAssemblyPath apath = picker.GetPath();
264                         return processPick(picker, apath);
265                 } else if (pickType == 4) {
266                         vtkCellPicker picker = new vtkCellPicker();
267                         picker.SetTolerance(0.00001);
268                         lock();
269                         picker.Pick(new double[]{ax, ay,0}, ren);
270                         unlock();       
271                         vtkAssemblyPath apath = picker.GetPath();
272                         return processPick(picker, apath);
273                 } else if (pickType == 5) {
274                         vtkActor2DCollection coll = ren.GetActors2D(); 
275                         coll.InitTraversal();
276                         vtkActor2D a;
277                         
278                         List<vtkActor2D> picked = new ArrayList<vtkActor2D>();
279                         while ((a = coll.GetNextItem()) != null) {
280                                 double pos[] = a.GetPosition();
281                                 // TODO : width and height do not seem to affect the perceived size of Actor2D.
282                                 //        actual size should be fetched from mapper. 
283                                 double w = a.GetWidth();
284                                 double h = a.GetHeight();
285                                 int minx = (int)(pos[0]-w*0.5);
286                                 int miny = (int)(pos[1]-h*0.5);
287                                 int maxx = (int)(pos[0]+w*0.5);
288                                 int maxy = (int)(pos[1]+h*0.5);
289                                 if (minx <= ax && maxx >= ax &&
290                                         miny <= ay && maxy >= ay) {
291                                         picked.add(a);
292                                 }
293                         }
294                         return picked.toArray(new vtkProp[picked.size()]);
295                 }
296
297                 return null;
298         }
299         
300         public vtkProp[] pick2(int x, int y) {
301                 vtkRenderWindow rw = getRenderWindow();
302                 vtkRenderer ren = getRenderer();
303                 
304 //              vtkPicker picker = new vtkPicker();
305 //              vtkAbstractPicker picker = new vtkAbstractPicker();
306 //              picker.Pick(x, rw.GetSize()[1] - y, ren);
307 //              // see page 60 of VTK user's guide
308 //
309                 if (pickType == 0) {
310         
311                         vtkPropPicker picker = new vtkPropPicker();
312                         lock();
313                         picker.PickProp(x, rw.GetSize()[1] - y, ren);
314         
315                         unlock();
316                         vtkPropCollection coll = picker.GetPickList();
317                         return processPick(picker, coll);
318                         
319                 } else if (pickType == 1) {
320                         if (scenePicker == null) {
321                                 scenePicker = new vtkScenePicker();
322                                 scenePicker.SetRenderer(ren);
323                                 scenePicker.EnableVertexPickingOn();
324                                 scenePicker.DebugOn();
325                                 
326                         }
327                         lock();
328
329                         
330                         vtkAssemblyPath apath = ren.PickProp(x, rw.GetSize()[1] - y);
331                         
332                         unlock();
333                         
334                         if (apath != null) {
335                                 apath.InitTraversal();
336
337                                 
338                                 vtkAssemblyNode node = apath.GetLastNode();
339                                 vtkProp test = (vtkProp) node.GetViewProp();
340                                 apath.Delete();
341                                 node.Delete();
342                                 return new vtkProp[]{test};
343         
344                         }
345                         
346                 } else if (pickType == 2) {
347                         vtkPointPicker picker = new vtkPointPicker();
348                         picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
349                         lock();
350                         picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
351                         unlock();
352                         vtkProp3DCollection coll = picker.GetProp3Ds();
353                         return processPick(picker, coll);
354                 } else if (pickType == 3) {
355                         vtkAreaPicker picker = new vtkAreaPicker();
356                         lock();
357                         picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
358                         //picker.AreaPick(x-1, rw.GetSize()[1] - y-1,x+1,rw.GetSize()[1] - y+1, ren);
359                         unlock();
360                         vtkProp3DCollection coll = picker.GetProp3Ds();
361                         return processPick(picker, coll);
362                 } else if (pickType == 4) {
363                         vtkCellPicker picker = new vtkCellPicker();
364                         picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
365                         lock();
366                         picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
367                         unlock();       
368                         vtkProp3DCollection coll = picker.GetProp3Ds();
369                         return processPick(picker, coll);
370                 }
371
372                 return null;
373         }
374         
375         private vtkProp[] processPick(vtkAbstractPicker picker, vtkAssemblyPath apath) {
376 //              double[] pickPos = picker.GetPickPosition();
377                 picker.Delete();
378                 if (apath != null) {
379                         apath.InitTraversal();
380                         vtkProp result[] = new vtkProp[apath.GetNumberOfItems()];
381                         for (int i = apath.GetNumberOfItems()-1; i >= 0; i--) {
382                                 vtkAssemblyNode node = apath.GetNextNode();
383                                 vtkProp test = (vtkProp) node.GetViewProp();
384 //                              System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());
385                                 result[i] = test;
386                                 node.Delete();
387                         }
388                         apath.Delete();
389                         return result;
390
391                 }
392                 return null;
393         }
394         
395         private vtkProp[] processPick(vtkAbstractPicker picker, vtkPropCollection coll) {
396 //              double[] pickPos = picker.GetPickPosition();
397                 picker.Delete();
398                 if (coll != null) {
399                         coll.InitTraversal();
400                         vtkProp result[] = new vtkProp[coll.GetNumberOfItems()];
401                         for (int i = coll.GetNumberOfItems()-1; i >= 0; i--) {
402                                 vtkProp test = coll.GetNextProp();
403                                 
404 //                              System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());
405                                 result[i] = test;
406                                 
407                         }
408                         coll.Delete();
409                         return result;
410
411                 }
412                 return null;
413         }
414         
415         
416         
417 }