1 package org.simantics.g3d.vtk.swt;
3 import java.util.ArrayList;
6 import org.eclipse.core.runtime.Platform;
7 import org.eclipse.swt.widgets.Composite;
8 import org.simantics.g3d.scenegraph.RenderListener;
9 import org.simantics.g3d.vtk.action.vtkAction;
10 import org.simantics.g3d.vtk.common.VtkView;
11 import org.simantics.utils.threads.IThreadWorkQueue;
12 import org.simantics.utils.threads.SWTThread;
13 import org.simantics.utils.threads.ThreadUtils;
15 import vtk.vtkAbstractPicker;
16 import vtk.vtkActor2D;
17 import vtk.vtkActor2DCollection;
18 import vtk.vtkAreaPicker;
19 import vtk.vtkAssemblyNode;
20 import vtk.vtkAssemblyPath;
21 import vtk.vtkCellPicker;
23 import vtk.vtkObjectBase;
24 import vtk.vtkPointPicker;
26 import vtk.vtkProp3DCollection;
27 import vtk.vtkPropCollection;
28 import vtk.vtkPropPicker;
29 import vtk.vtkRenderWindow;
30 import vtk.vtkRenderer;
31 import vtk.vtkScenePicker;
32 import vtk.rendering.swt.vtkSwtComponent;
34 public class InteractiveVtkComposite extends vtkSwtComponent implements VtkView{
36 Composite parentComposite;
37 public InteractiveVtkComposite(Composite parentComposite) {
38 super(parentComposite);
39 this.parentComposite = parentComposite;
41 if (!Platform.inDevelopmentMode()) {
42 // This is actually a static method in C++
43 new vtkObject().GlobalWarningDisplayOff();
47 private boolean updating = false;
48 private Object mutex = new Object();
51 public void refresh() {
52 // if (Thread.currentThread() == getThreadQueue().getThread())
55 synchronized (mutex) {
58 ThreadUtils.asyncExec(getThreadQueue(), new Runnable() {
62 if (parentComposite.isDisposed())
64 synchronized (mutex) {
76 boolean update = false;
78 public void update() {
87 public IThreadWorkQueue getThreadQueue() {
88 return SWTThread.getThreadAccess();
92 boolean render = false;
94 public void Render() {
97 // System.out.println(getClass().getSimpleName() +" render");
105 public void addListener(RenderListener l) {
109 public void removeListener(RenderListener l) {
113 private List<RenderListener> listeners = new ArrayList<RenderListener>();
115 List<RenderListener> list = new ArrayList<RenderListener>();
117 private void firePreRender() {
118 if (listeners.size() > 0) {
119 list.addAll(listeners);
120 for (RenderListener l : list)
126 private void firePostRender() {
127 if (listeners.size() > 0) {
128 list.addAll(listeners);
129 for (RenderListener l : list)
136 private List<vtkObjectBase> deletable = new ArrayList<vtkObjectBase>();
138 public void addDeletable(vtkObjectBase o) {
142 public void removeDeletable (vtkObjectBase o) {
147 public void Delete() {
148 for (vtkObjectBase o : deletable) {
149 if (o.GetVTKId() != 0) {
158 private vtkSwtAction defaultAction;
159 private vtkSwtAction currentAction;
161 public void setActiveAction(vtkAction action) {
162 if (action.equals(currentAction))
164 if (currentAction != null)
165 currentAction.deattach();
166 currentAction = (vtkSwtAction)action;
171 public void setDefaultAction(vtkAction defaultAction) {
172 this.defaultAction = (vtkSwtAction)defaultAction;
175 public void useDefaultAction() {
176 setActiveAction(defaultAction);
179 public vtkAction getDefaultAction() {
180 return defaultAction;
187 public void unlock() {
188 getVTKLock().unlock();
191 private vtkScenePicker scenePicker;
195 public int getPickType() {
199 public void setPickType(int pickType) {
200 this.pickType = pickType;
203 public vtkProp[] pick(int x, int y) {
206 vtkRenderWindow rw = getRenderWindow();
207 vtkRenderer ren = getRenderer();
210 int ay = rw.GetSize()[1] - y;
213 throw new IllegalStateException("SWT Binding does not work with hw picking");
215 // ren.BreakOnError();
217 // vtkPropPicker picker = new vtkPropPicker();
219 // //picker.PickProp(x, rw.GetSize()[1] - y, ren);
220 // picker.Pick(x, rw.GetSize()[1] - y,0, ren);
224 // vtkAssemblyPath apath = picker.GetPath();
225 // return processPick(picker, apath);
227 } else if (pickType == 1) {
228 throw new IllegalStateException("SWT Binding does not work with hw picking");
229 // if (scenePicker == null) {
230 // scenePicker = new vtkScenePicker();
231 // scenePicker.SetRenderer(ren);
232 // scenePicker.EnableVertexPickingOn();
237 // vtkAssemblyPath apath = ren.PickProp(ax, ay);
241 // if (apath != null) {
242 // apath.InitTraversal();
243 // vtkAssemblyNode node = apath.GetLastNode();
244 // vtkProp test = (vtkProp) node.GetViewProp();
247 // return new vtkProp[]{test};
251 } else if (pickType == 2) {
252 vtkPointPicker picker = new vtkPointPicker();
253 //picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
254 picker.SetTolerance(0.00001);
256 picker.Pick(new double[]{ax, ay,0}, ren);
259 vtkAssemblyPath apath = picker.GetPath();
260 return processPick(picker, apath);
261 } else if (pickType == 3) {
262 vtkAreaPicker picker = new vtkAreaPicker();
264 picker.Pick(new double[]{ax, ay,0}, ren);
266 vtkAssemblyPath apath = picker.GetPath();
267 return processPick(picker, apath);
268 } else if (pickType == 4) {
269 vtkCellPicker picker = new vtkCellPicker();
270 picker.SetTolerance(0.00001);
272 picker.Pick(new double[]{ax, ay,0}, ren);
274 vtkAssemblyPath apath = picker.GetPath();
275 return processPick(picker, apath);
276 } else if (pickType == 5) {
277 vtkActor2DCollection coll = ren.GetActors2D();
278 coll.InitTraversal();
281 List<vtkActor2D> picked = new ArrayList<vtkActor2D>();
282 while ((a = coll.GetNextItem()) != null) {
283 double pos[] = a.GetPosition();
284 // TODO : width and height do not seem to affect the perceived size of Actor2D.
285 // actual size should be fetched from mapper.
286 double w = a.GetWidth();
287 double h = a.GetHeight();
288 int minx = (int)(pos[0]-w*0.5);
289 int miny = (int)(pos[1]-h*0.5);
290 int maxx = (int)(pos[0]+w*0.5);
291 int maxy = (int)(pos[1]+h*0.5);
292 if (minx <= ax && maxx >= ax &&
293 miny <= ay && maxy >= ay) {
297 return picked.toArray(new vtkProp[picked.size()]);
303 public vtkProp[] pick2(int x, int y) {
304 vtkRenderWindow rw = getRenderWindow();
305 vtkRenderer ren = getRenderer();
307 // vtkPicker picker = new vtkPicker();
308 // vtkAbstractPicker picker = new vtkAbstractPicker();
309 // picker.Pick(x, rw.GetSize()[1] - y, ren);
310 // // see page 60 of VTK user's guide
314 vtkPropPicker picker = new vtkPropPicker();
316 picker.PickProp(x, rw.GetSize()[1] - y, ren);
319 vtkPropCollection coll = picker.GetPickList();
320 return processPick(picker, coll);
322 } else if (pickType == 1) {
323 if (scenePicker == null) {
324 scenePicker = new vtkScenePicker();
325 scenePicker.SetRenderer(ren);
326 scenePicker.EnableVertexPickingOn();
327 scenePicker.DebugOn();
333 vtkAssemblyPath apath = ren.PickProp(x, rw.GetSize()[1] - y);
338 apath.InitTraversal();
341 vtkAssemblyNode node = apath.GetLastNode();
342 vtkProp test = (vtkProp) node.GetViewProp();
345 return new vtkProp[]{test};
349 } else if (pickType == 2) {
350 vtkPointPicker picker = new vtkPointPicker();
351 picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
353 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
355 vtkProp3DCollection coll = picker.GetProp3Ds();
356 return processPick(picker, coll);
357 } else if (pickType == 3) {
358 vtkAreaPicker picker = new vtkAreaPicker();
360 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
361 //picker.AreaPick(x-1, rw.GetSize()[1] - y-1,x+1,rw.GetSize()[1] - y+1, ren);
363 vtkProp3DCollection coll = picker.GetProp3Ds();
364 return processPick(picker, coll);
365 } else if (pickType == 4) {
366 vtkCellPicker picker = new vtkCellPicker();
367 picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
369 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
371 vtkProp3DCollection coll = picker.GetProp3Ds();
372 return processPick(picker, coll);
378 private vtkProp[] processPick(vtkAbstractPicker picker, vtkAssemblyPath apath) {
379 // double[] pickPos = picker.GetPickPosition();
382 apath.InitTraversal();
383 vtkProp result[] = new vtkProp[apath.GetNumberOfItems()];
384 for (int i = apath.GetNumberOfItems()-1; i >= 0; i--) {
385 vtkAssemblyNode node = apath.GetNextNode();
386 vtkProp test = (vtkProp) node.GetViewProp();
387 // System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());
398 private vtkProp[] processPick(vtkAbstractPicker picker, vtkPropCollection coll) {
399 // double[] pickPos = picker.GetPickPosition();
402 coll.InitTraversal();
403 vtkProp result[] = new vtkProp[coll.GetNumberOfItems()];
404 for (int i = coll.GetNumberOfItems()-1; i >= 0; i--) {
405 vtkProp test = coll.GetNextProp();
407 // System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());