1 package org.simantics.g3d.vtk.swt;
3 import java.util.ArrayList;
6 import org.eclipse.core.runtime.Platform;
7 import org.eclipse.swt.internal.DPIUtil;
8 import org.eclipse.swt.widgets.Composite;
9 import org.simantics.g3d.scenegraph.RenderListener;
10 import org.simantics.g3d.vtk.action.vtkAction;
11 import org.simantics.g3d.vtk.common.VtkView;
12 import org.simantics.utils.threads.IThreadWorkQueue;
13 import org.simantics.utils.threads.SWTThread;
14 import org.simantics.utils.threads.ThreadUtils;
16 import vtk.vtkAbstractPicker;
17 import vtk.vtkActor2D;
18 import vtk.vtkActor2DCollection;
19 import vtk.vtkAreaPicker;
20 import vtk.vtkAssemblyNode;
21 import vtk.vtkAssemblyPath;
22 import vtk.vtkCellPicker;
24 import vtk.vtkObjectBase;
25 import vtk.vtkPointPicker;
27 import vtk.vtkProp3DCollection;
28 import vtk.vtkPropCollection;
29 import vtk.vtkPropPicker;
30 import vtk.vtkRenderWindow;
31 import vtk.vtkRenderer;
32 import vtk.vtkScenePicker;
33 import vtk.rendering.swt.vtkSwtComponent;
35 public class InteractiveVtkComposite extends vtkSwtComponent implements VtkView{
37 Composite parentComposite;
38 public InteractiveVtkComposite(Composite parentComposite) {
39 super(parentComposite);
40 this.parentComposite = parentComposite;
42 if (!Platform.inDevelopmentMode()) {
43 // This is actually a static method in C++
44 new vtkObject().GlobalWarningDisplayOff();
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;
188 public void unlock() {
189 getVTKLock().unlock();
192 private vtkScenePicker scenePicker;
196 public int getPickType() {
200 public void setPickType(int pickType) {
201 this.pickType = pickType;
204 public vtkProp[] pick(int x, int y) {
207 vtkRenderWindow rw = getRenderWindow();
208 vtkRenderer ren = getRenderer();
211 int ay = rw.GetSize()[1] - y;
214 throw new IllegalStateException("SWT Binding does not work with hw picking");
216 // ren.BreakOnError();
218 // vtkPropPicker picker = new vtkPropPicker();
220 // //picker.PickProp(x, rw.GetSize()[1] - y, ren);
221 // picker.Pick(x, rw.GetSize()[1] - y,0, ren);
225 // vtkAssemblyPath apath = picker.GetPath();
226 // return processPick(picker, apath);
228 } else if (pickType == 1) {
229 throw new IllegalStateException("SWT Binding does not work with hw picking");
230 // if (scenePicker == null) {
231 // scenePicker = new vtkScenePicker();
232 // scenePicker.SetRenderer(ren);
233 // scenePicker.EnableVertexPickingOn();
238 // vtkAssemblyPath apath = ren.PickProp(ax, ay);
242 // if (apath != null) {
243 // apath.InitTraversal();
244 // vtkAssemblyNode node = apath.GetLastNode();
245 // vtkProp test = (vtkProp) node.GetViewProp();
248 // return new vtkProp[]{test};
252 } else if (pickType == 2) {
253 vtkPointPicker picker = new vtkPointPicker();
254 //picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
255 picker.SetTolerance(0.00001);
257 picker.Pick(new double[]{ax, ay,0}, ren);
260 vtkAssemblyPath apath = picker.GetPath();
261 return processPick(picker, apath);
262 } else if (pickType == 3) {
263 vtkAreaPicker picker = new vtkAreaPicker();
265 picker.Pick(new double[]{ax, ay,0}, ren);
267 vtkAssemblyPath apath = picker.GetPath();
268 return processPick(picker, apath);
269 } else if (pickType == 4) {
270 vtkCellPicker picker = new vtkCellPicker();
271 picker.SetTolerance(0.00001);
273 picker.Pick(new double[]{ax, ay,0}, ren);
275 vtkAssemblyPath apath = picker.GetPath();
276 return processPick(picker, apath);
277 } else if (pickType == 5) {
278 vtkActor2DCollection coll = ren.GetActors2D();
279 coll.InitTraversal();
282 List<vtkActor2D> picked = new ArrayList<vtkActor2D>();
283 while ((a = coll.GetNextItem()) != null) {
284 double pos[] = a.GetPosition();
285 // TODO : width and height do not seem to affect the perceived size of Actor2D.
286 // actual size should be fetched from mapper.
287 double w = a.GetWidth();
288 double h = a.GetHeight();
289 int minx = (int)(pos[0]-w*0.5);
290 int miny = (int)(pos[1]-h*0.5);
291 int maxx = (int)(pos[0]+w*0.5);
292 int maxy = (int)(pos[1]+h*0.5);
293 if (minx <= ax && maxx >= ax &&
294 miny <= ay && maxy >= ay) {
298 return picked.toArray(new vtkProp[picked.size()]);
304 public vtkProp[] pick2(int x, int y) {
305 vtkRenderWindow rw = getRenderWindow();
306 vtkRenderer ren = getRenderer();
308 // vtkPicker picker = new vtkPicker();
309 // vtkAbstractPicker picker = new vtkAbstractPicker();
310 // picker.Pick(x, rw.GetSize()[1] - y, ren);
311 // // see page 60 of VTK user's guide
315 vtkPropPicker picker = new vtkPropPicker();
317 picker.PickProp(x, rw.GetSize()[1] - y, ren);
320 vtkPropCollection coll = picker.GetPickList();
321 return processPick(picker, coll);
323 } else if (pickType == 1) {
324 if (scenePicker == null) {
325 scenePicker = new vtkScenePicker();
326 scenePicker.SetRenderer(ren);
327 scenePicker.EnableVertexPickingOn();
328 scenePicker.DebugOn();
334 vtkAssemblyPath apath = ren.PickProp(x, rw.GetSize()[1] - y);
339 apath.InitTraversal();
342 vtkAssemblyNode node = apath.GetLastNode();
343 vtkProp test = (vtkProp) node.GetViewProp();
346 return new vtkProp[]{test};
350 } else if (pickType == 2) {
351 vtkPointPicker picker = new vtkPointPicker();
352 picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
354 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
356 vtkProp3DCollection coll = picker.GetProp3Ds();
357 return processPick(picker, coll);
358 } else if (pickType == 3) {
359 vtkAreaPicker picker = new vtkAreaPicker();
361 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
362 //picker.AreaPick(x-1, rw.GetSize()[1] - y-1,x+1,rw.GetSize()[1] - y+1, ren);
364 vtkProp3DCollection coll = picker.GetProp3Ds();
365 return processPick(picker, coll);
366 } else if (pickType == 4) {
367 vtkCellPicker picker = new vtkCellPicker();
368 picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
370 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
372 vtkProp3DCollection coll = picker.GetProp3Ds();
373 return processPick(picker, coll);
379 private vtkProp[] processPick(vtkAbstractPicker picker, vtkAssemblyPath apath) {
380 // double[] pickPos = picker.GetPickPosition();
383 apath.InitTraversal();
384 vtkProp result[] = new vtkProp[apath.GetNumberOfItems()];
385 for (int i = apath.GetNumberOfItems()-1; i >= 0; i--) {
386 vtkAssemblyNode node = apath.GetNextNode();
387 vtkProp test = (vtkProp) node.GetViewProp();
388 // System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());
399 private vtkProp[] processPick(vtkAbstractPicker picker, vtkPropCollection coll) {
400 // double[] pickPos = picker.GetPickPosition();
403 coll.InitTraversal();
404 vtkProp result[] = new vtkProp[coll.GetNumberOfItems()];
405 for (int i = coll.GetNumberOfItems()-1; i >= 0; i--) {
406 vtkProp test = coll.GetNextProp();
408 // System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());
420 public int upscale(int i) {
421 return DPIUtil.autoScaleUp(i);
425 public double upscale(double d) {
426 return (double)DPIUtil.autoScaleUp((float)d);