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;
185 if (getComponent().getContext() != null && !getComponent().getContext().isCurrent()) {
186 @SuppressWarnings("unused")
187 int ret = getComponent().getContext().makeCurrent();
188 // System.out.println("Make current2 " + ret);
192 public void unlock() {
193 getVTKLock().unlock();
196 private vtkScenePicker scenePicker;
200 public int getPickType() {
204 public void setPickType(int pickType) {
205 this.pickType = pickType;
208 public vtkProp[] pick(int x, int y) {
211 vtkRenderWindow rw = getRenderWindow();
212 vtkRenderer ren = getRenderer();
215 int ay = rw.GetSize()[1] - y;
218 throw new IllegalStateException("SWT Binding does not work with hw picking");
220 // ren.BreakOnError();
222 // vtkPropPicker picker = new vtkPropPicker();
224 // //picker.PickProp(x, rw.GetSize()[1] - y, ren);
225 // picker.Pick(x, rw.GetSize()[1] - y,0, ren);
229 // vtkAssemblyPath apath = picker.GetPath();
230 // return processPick(picker, apath);
232 } else if (pickType == 1) {
233 throw new IllegalStateException("SWT Binding does not work with hw picking");
234 // if (scenePicker == null) {
235 // scenePicker = new vtkScenePicker();
236 // scenePicker.SetRenderer(ren);
237 // scenePicker.EnableVertexPickingOn();
242 // vtkAssemblyPath apath = ren.PickProp(ax, ay);
246 // if (apath != null) {
247 // apath.InitTraversal();
248 // vtkAssemblyNode node = apath.GetLastNode();
249 // vtkProp test = (vtkProp) node.GetViewProp();
252 // return new vtkProp[]{test};
256 } else if (pickType == 2) {
257 vtkPointPicker picker = new vtkPointPicker();
258 //picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
259 picker.SetTolerance(0.00001);
261 picker.Pick(new double[]{ax, ay,0}, ren);
264 vtkAssemblyPath apath = picker.GetPath();
265 return processPick(picker, apath);
266 } else if (pickType == 3) {
267 vtkAreaPicker picker = new vtkAreaPicker();
269 picker.Pick(new double[]{ax, ay,0}, ren);
271 vtkAssemblyPath apath = picker.GetPath();
272 return processPick(picker, apath);
273 } else if (pickType == 4) {
274 vtkCellPicker picker = new vtkCellPicker();
275 picker.SetTolerance(0.00001);
277 picker.Pick(new double[]{ax, ay,0}, ren);
279 vtkAssemblyPath apath = picker.GetPath();
280 return processPick(picker, apath);
281 } else if (pickType == 5) {
282 vtkActor2DCollection coll = ren.GetActors2D();
283 coll.InitTraversal();
286 List<vtkActor2D> picked = new ArrayList<vtkActor2D>();
287 while ((a = coll.GetNextItem()) != null) {
288 double pos[] = a.GetPosition();
289 // TODO : width and height do not seem to affect the perceived size of Actor2D.
290 // actual size should be fetched from mapper.
291 double w = a.GetWidth();
292 double h = a.GetHeight();
293 int minx = (int)(pos[0]-w*0.5);
294 int miny = (int)(pos[1]-h*0.5);
295 int maxx = (int)(pos[0]+w*0.5);
296 int maxy = (int)(pos[1]+h*0.5);
297 if (minx <= ax && maxx >= ax &&
298 miny <= ay && maxy >= ay) {
302 return picked.toArray(new vtkProp[picked.size()]);
308 public vtkProp[] pick2(int x, int y) {
309 vtkRenderWindow rw = getRenderWindow();
310 vtkRenderer ren = getRenderer();
312 // vtkPicker picker = new vtkPicker();
313 // vtkAbstractPicker picker = new vtkAbstractPicker();
314 // picker.Pick(x, rw.GetSize()[1] - y, ren);
315 // // see page 60 of VTK user's guide
319 vtkPropPicker picker = new vtkPropPicker();
321 picker.PickProp(x, rw.GetSize()[1] - y, ren);
324 vtkPropCollection coll = picker.GetPickList();
325 return processPick(picker, coll);
327 } else if (pickType == 1) {
328 if (scenePicker == null) {
329 scenePicker = new vtkScenePicker();
330 scenePicker.SetRenderer(ren);
331 scenePicker.EnableVertexPickingOn();
332 scenePicker.DebugOn();
338 vtkAssemblyPath apath = ren.PickProp(x, rw.GetSize()[1] - y);
343 apath.InitTraversal();
346 vtkAssemblyNode node = apath.GetLastNode();
347 vtkProp test = (vtkProp) node.GetViewProp();
350 return new vtkProp[]{test};
354 } else if (pickType == 2) {
355 vtkPointPicker picker = new vtkPointPicker();
356 picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
358 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
360 vtkProp3DCollection coll = picker.GetProp3Ds();
361 return processPick(picker, coll);
362 } else if (pickType == 3) {
363 vtkAreaPicker picker = new vtkAreaPicker();
365 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
366 //picker.AreaPick(x-1, rw.GetSize()[1] - y-1,x+1,rw.GetSize()[1] - y+1, ren);
368 vtkProp3DCollection coll = picker.GetProp3Ds();
369 return processPick(picker, coll);
370 } else if (pickType == 4) {
371 vtkCellPicker picker = new vtkCellPicker();
372 picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
374 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
376 vtkProp3DCollection coll = picker.GetProp3Ds();
377 return processPick(picker, coll);
383 private vtkProp[] processPick(vtkAbstractPicker picker, vtkAssemblyPath apath) {
384 // double[] pickPos = picker.GetPickPosition();
387 apath.InitTraversal();
388 vtkProp result[] = new vtkProp[apath.GetNumberOfItems()];
389 for (int i = apath.GetNumberOfItems()-1; i >= 0; i--) {
390 vtkAssemblyNode node = apath.GetNextNode();
391 vtkProp test = (vtkProp) node.GetViewProp();
392 // System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());
403 private vtkProp[] processPick(vtkAbstractPicker picker, vtkPropCollection coll) {
404 // double[] pickPos = picker.GetPickPosition();
407 coll.InitTraversal();
408 vtkProp result[] = new vtkProp[coll.GetNumberOfItems()];
409 for (int i = coll.GetNumberOfItems()-1; i >= 0; i--) {
410 vtkProp test = coll.GetNextProp();
412 // System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());