1 package org.simantics.g3d.vtk.swt;
3 import java.util.ArrayList;
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;
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;
22 import vtk.vtkObjectBase;
23 import vtk.vtkPointPicker;
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;
33 public class InteractiveVtkComposite extends vtkSwtComponent implements VtkView{
35 Composite parentComposite;
36 public InteractiveVtkComposite(Composite parentComposite) {
37 super(parentComposite);
38 this.parentComposite = parentComposite;
40 // This is actually a static method in C++
41 new vtkObject().GlobalWarningDisplayOff();
44 private boolean updating = false;
45 private Object mutex = new Object();
48 public void refresh() {
49 // if (Thread.currentThread() == getThreadQueue().getThread())
52 synchronized (mutex) {
55 ThreadUtils.asyncExec(getThreadQueue(), new Runnable() {
59 if (parentComposite.isDisposed())
61 synchronized (mutex) {
73 boolean update = false;
75 public void update() {
84 public IThreadWorkQueue getThreadQueue() {
85 return SWTThread.getThreadAccess();
89 boolean render = false;
91 public void Render() {
94 // System.out.println(getClass().getSimpleName() +" render");
102 public void addListener(RenderListener l) {
106 public void removeListener(RenderListener l) {
110 private List<RenderListener> listeners = new ArrayList<RenderListener>();
112 List<RenderListener> list = new ArrayList<RenderListener>();
114 private void firePreRender() {
115 if (listeners.size() > 0) {
116 list.addAll(listeners);
117 for (RenderListener l : list)
123 private void firePostRender() {
124 if (listeners.size() > 0) {
125 list.addAll(listeners);
126 for (RenderListener l : list)
133 private List<vtkObjectBase> deletable = new ArrayList<vtkObjectBase>();
135 public void addDeletable(vtkObjectBase o) {
139 public void removeDeletable (vtkObjectBase o) {
144 public void Delete() {
145 for (vtkObjectBase o : deletable) {
146 if (o.GetVTKId() != 0) {
155 private vtkSwtAction defaultAction;
156 private vtkSwtAction currentAction;
158 public void setActiveAction(vtkAction action) {
159 if (action.equals(currentAction))
161 if (currentAction != null)
162 currentAction.deattach();
163 currentAction = (vtkSwtAction)action;
168 public void setDefaultAction(vtkAction defaultAction) {
169 this.defaultAction = (vtkSwtAction)defaultAction;
172 public void useDefaultAction() {
173 setActiveAction(defaultAction);
176 public vtkAction getDefaultAction() {
177 return defaultAction;
184 public void unlock() {
185 getVTKLock().unlock();
188 private vtkScenePicker scenePicker;
192 public int getPickType() {
196 public void setPickType(int pickType) {
197 this.pickType = pickType;
200 public vtkProp[] pick(int x, int y) {
203 vtkRenderWindow rw = getRenderWindow();
204 vtkRenderer ren = getRenderer();
207 int ay = rw.GetSize()[1] - y;
210 throw new IllegalStateException("SWT Binding does not work with hw picking");
212 // ren.BreakOnError();
214 // vtkPropPicker picker = new vtkPropPicker();
216 // //picker.PickProp(x, rw.GetSize()[1] - y, ren);
217 // picker.Pick(x, rw.GetSize()[1] - y,0, ren);
221 // vtkAssemblyPath apath = picker.GetPath();
222 // return processPick(picker, apath);
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();
234 // vtkAssemblyPath apath = ren.PickProp(ax, ay);
238 // if (apath != null) {
239 // apath.InitTraversal();
240 // vtkAssemblyNode node = apath.GetLastNode();
241 // vtkProp test = (vtkProp) node.GetViewProp();
244 // return new vtkProp[]{test};
248 } else if (pickType == 2) {
249 vtkPointPicker picker = new vtkPointPicker();
250 //picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
251 picker.SetTolerance(0.00001);
253 picker.Pick(new double[]{ax, ay,0}, ren);
256 vtkAssemblyPath apath = picker.GetPath();
257 return processPick(picker, apath);
258 } else if (pickType == 3) {
259 vtkAreaPicker picker = new vtkAreaPicker();
261 picker.Pick(new double[]{ax, ay,0}, ren);
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);
269 picker.Pick(new double[]{ax, ay,0}, ren);
271 vtkAssemblyPath apath = picker.GetPath();
272 return processPick(picker, apath);
273 } else if (pickType == 5) {
274 vtkActor2DCollection coll = ren.GetActors2D();
275 coll.InitTraversal();
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) {
294 return picked.toArray(new vtkProp[picked.size()]);
300 public vtkProp[] pick2(int x, int y) {
301 vtkRenderWindow rw = getRenderWindow();
302 vtkRenderer ren = getRenderer();
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
311 vtkPropPicker picker = new vtkPropPicker();
313 picker.PickProp(x, rw.GetSize()[1] - y, ren);
316 vtkPropCollection coll = picker.GetPickList();
317 return processPick(picker, coll);
319 } else if (pickType == 1) {
320 if (scenePicker == null) {
321 scenePicker = new vtkScenePicker();
322 scenePicker.SetRenderer(ren);
323 scenePicker.EnableVertexPickingOn();
324 scenePicker.DebugOn();
330 vtkAssemblyPath apath = ren.PickProp(x, rw.GetSize()[1] - y);
335 apath.InitTraversal();
338 vtkAssemblyNode node = apath.GetLastNode();
339 vtkProp test = (vtkProp) node.GetViewProp();
342 return new vtkProp[]{test};
346 } else if (pickType == 2) {
347 vtkPointPicker picker = new vtkPointPicker();
348 picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
350 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
352 vtkProp3DCollection coll = picker.GetProp3Ds();
353 return processPick(picker, coll);
354 } else if (pickType == 3) {
355 vtkAreaPicker picker = new vtkAreaPicker();
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);
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]);
366 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
368 vtkProp3DCollection coll = picker.GetProp3Ds();
369 return processPick(picker, coll);
375 private vtkProp[] processPick(vtkAbstractPicker picker, vtkAssemblyPath apath) {
376 // double[] pickPos = picker.GetPickPosition();
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());
395 private vtkProp[] processPick(vtkAbstractPicker picker, vtkPropCollection coll) {
396 // double[] pickPos = picker.GetPickPosition();
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();
404 // System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());