1 package org.simantics.g3d.vtk.swt;
3 import java.util.ArrayList;
4 import java.util.Arrays;
7 import javax.vecmath.Vector3d;
9 import org.eclipse.swt.widgets.Composite;
10 import org.simantics.g3d.math.Ray;
11 import org.simantics.g3d.scenegraph.RenderListener;
12 import org.simantics.g3d.vtk.action.vtkAction;
13 import org.simantics.g3d.vtk.common.VtkView;
14 import org.simantics.g3d.vtk.utils.vtkUtil;
15 import org.simantics.utils.threads.IThreadWorkQueue;
16 import org.simantics.utils.threads.SWTThread;
17 import org.simantics.utils.threads.ThreadUtils;
19 import vtk.vtkAbstractPicker;
20 import vtk.vtkActor2D;
21 import vtk.vtkActor2DCollection;
22 import vtk.vtkAreaPicker;
23 import vtk.vtkAssemblyNode;
24 import vtk.vtkAssemblyPath;
25 import vtk.vtkCellPicker;
26 import vtk.vtkCoordinate;
27 import vtk.vtkObjectBase;
28 import vtk.vtkPointPicker;
30 import vtk.vtkProp3DCollection;
31 import vtk.vtkPropCollection;
32 import vtk.vtkPropPicker;
33 import vtk.vtkRenderWindow;
34 import vtk.vtkRenderer;
35 import vtk.vtkScenePicker;
36 import vtk.rendering.swt.vtkSwtComponent;
38 public class InteractiveVtkComposite extends vtkSwtComponent implements VtkView{
40 Composite parentComposite;
41 public InteractiveVtkComposite(Composite parentComposite) {
42 super(parentComposite);
43 this.parentComposite = parentComposite;
45 // TODO Auto-generated constructor stub
48 private boolean updating = false;
49 private Object mutex = new Object();
52 public void refresh() {
53 // if (Thread.currentThread() == getThreadQueue().getThread())
56 synchronized (mutex) {
59 ThreadUtils.asyncExec(getThreadQueue(), new Runnable() {
63 if (parentComposite.isDisposed())
65 synchronized (mutex) {
77 boolean update = false;
79 public void update() {
88 public IThreadWorkQueue getThreadQueue() {
89 return SWTThread.getThreadAccess();
93 boolean render = false;
95 public void Render() {
98 // System.out.println(getClass().getSimpleName() +" render");
106 public void addListener(RenderListener l) {
110 public void removeListener(RenderListener l) {
114 private List<RenderListener> listeners = new ArrayList<RenderListener>();
116 List<RenderListener> list = new ArrayList<RenderListener>();
118 private void firePreRender() {
119 if (listeners.size() > 0) {
120 list.addAll(listeners);
121 for (RenderListener l : list)
127 private void firePostRender() {
128 if (listeners.size() > 0) {
129 list.addAll(listeners);
130 for (RenderListener l : list)
137 private List<vtkObjectBase> deletable = new ArrayList<vtkObjectBase>();
139 public void addDeletable(vtkObjectBase o) {
143 public void removeDeletable (vtkObjectBase o) {
148 public void Delete() {
149 for (vtkObjectBase o : deletable) {
150 if (o.GetVTKId() != 0) {
159 private vtkSwtAction defaultAction;
160 private vtkSwtAction currentAction;
162 public void setActiveAction(vtkAction action) {
163 if (action.equals(currentAction))
165 if (currentAction != null)
166 currentAction.deattach();
167 currentAction = (vtkSwtAction)action;
172 public void setDefaultAction(vtkAction defaultAction) {
173 this.defaultAction = (vtkSwtAction)defaultAction;
176 public void useDefaultAction() {
177 setActiveAction(defaultAction);
180 public vtkAction getDefaultAction() {
181 return defaultAction;
186 if (getComponent().getContext() != null && !getComponent().getContext().isCurrent()) {
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());