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;
21 import vtk.vtkObjectBase;
22 import vtk.vtkPointPicker;
24 import vtk.vtkProp3DCollection;
25 import vtk.vtkPropCollection;
26 import vtk.vtkPropPicker;
27 import vtk.vtkRenderWindow;
28 import vtk.vtkRenderer;
29 import vtk.vtkScenePicker;
30 import vtk.rendering.swt.vtkSwtComponent;
32 public class InteractiveVtkComposite extends vtkSwtComponent implements VtkView{
34 Composite parentComposite;
35 public InteractiveVtkComposite(Composite parentComposite) {
36 super(parentComposite);
37 this.parentComposite = parentComposite;
39 // TODO Auto-generated constructor stub
42 private boolean updating = false;
43 private Object mutex = new Object();
46 public void refresh() {
47 // if (Thread.currentThread() == getThreadQueue().getThread())
50 synchronized (mutex) {
53 ThreadUtils.asyncExec(getThreadQueue(), new Runnable() {
57 if (parentComposite.isDisposed())
59 synchronized (mutex) {
71 boolean update = false;
73 public void update() {
82 public IThreadWorkQueue getThreadQueue() {
83 return SWTThread.getThreadAccess();
87 boolean render = false;
89 public void Render() {
92 // System.out.println(getClass().getSimpleName() +" render");
100 public void addListener(RenderListener l) {
104 public void removeListener(RenderListener l) {
108 private List<RenderListener> listeners = new ArrayList<RenderListener>();
110 List<RenderListener> list = new ArrayList<RenderListener>();
112 private void firePreRender() {
113 if (listeners.size() > 0) {
114 list.addAll(listeners);
115 for (RenderListener l : list)
121 private void firePostRender() {
122 if (listeners.size() > 0) {
123 list.addAll(listeners);
124 for (RenderListener l : list)
131 private List<vtkObjectBase> deletable = new ArrayList<vtkObjectBase>();
133 public void addDeletable(vtkObjectBase o) {
137 public void removeDeletable (vtkObjectBase o) {
142 public void Delete() {
143 for (vtkObjectBase o : deletable) {
144 if (o.GetVTKId() != 0) {
153 private vtkSwtAction defaultAction;
154 private vtkSwtAction currentAction;
156 public void setActiveAction(vtkAction action) {
157 if (action.equals(currentAction))
159 if (currentAction != null)
160 currentAction.deattach();
161 currentAction = (vtkSwtAction)action;
166 public void setDefaultAction(vtkAction defaultAction) {
167 this.defaultAction = (vtkSwtAction)defaultAction;
170 public void useDefaultAction() {
171 setActiveAction(defaultAction);
174 public vtkAction getDefaultAction() {
175 return defaultAction;
180 if (getComponent().getContext() != null && !getComponent().getContext().isCurrent()) {
181 @SuppressWarnings("unused")
182 int ret = getComponent().getContext().makeCurrent();
183 // System.out.println("Make current2 " + ret);
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());