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;
22 import vtk.vtkObjectBase;
23 import vtk.vtkPointPicker;
25 import vtk.vtkProp3DCollection;
26 import vtk.vtkPropCollection;
27 import vtk.vtkPropPicker;
28 import vtk.vtkRenderWindow;
29 import vtk.vtkRenderer;
30 import vtk.vtkScenePicker;
31 import vtk.rendering.swt.vtkSwtComponent;
33 public class InteractiveVtkComposite extends vtkSwtComponent implements VtkView{
35 Composite parentComposite;
36 public InteractiveVtkComposite(Composite parentComposite) {
37 super(parentComposite);
38 this.parentComposite = parentComposite;
40 // This is actually a static method in C++
41 new vtkObject().GlobalWarningDisplayOff();
44 private boolean updating = false;
45 private Object mutex = new Object();
48 public void refresh() {
49 // if (Thread.currentThread() == getThreadQueue().getThread())
52 synchronized (mutex) {
55 ThreadUtils.asyncExec(getThreadQueue(), new Runnable() {
59 if (parentComposite.isDisposed())
61 synchronized (mutex) {
73 boolean update = false;
75 public void update() {
84 public IThreadWorkQueue getThreadQueue() {
85 return SWTThread.getThreadAccess();
89 boolean render = false;
91 public void Render() {
94 // System.out.println(getClass().getSimpleName() +" render");
102 public void addListener(RenderListener l) {
106 public void removeListener(RenderListener l) {
110 private List<RenderListener> listeners = new ArrayList<RenderListener>();
112 List<RenderListener> list = new ArrayList<RenderListener>();
114 private void firePreRender() {
115 if (listeners.size() > 0) {
116 list.addAll(listeners);
117 for (RenderListener l : list)
123 private void firePostRender() {
124 if (listeners.size() > 0) {
125 list.addAll(listeners);
126 for (RenderListener l : list)
133 private List<vtkObjectBase> deletable = new ArrayList<vtkObjectBase>();
135 public void addDeletable(vtkObjectBase o) {
139 public void removeDeletable (vtkObjectBase o) {
144 public void Delete() {
145 for (vtkObjectBase o : deletable) {
146 if (o.GetVTKId() != 0) {
155 private vtkSwtAction defaultAction;
156 private vtkSwtAction currentAction;
158 public void setActiveAction(vtkAction action) {
159 if (action.equals(currentAction))
161 if (currentAction != null)
162 currentAction.deattach();
163 currentAction = (vtkSwtAction)action;
168 public void setDefaultAction(vtkAction defaultAction) {
169 this.defaultAction = (vtkSwtAction)defaultAction;
172 public void useDefaultAction() {
173 setActiveAction(defaultAction);
176 public vtkAction getDefaultAction() {
177 return defaultAction;
182 if (getComponent().getContext() != null && !getComponent().getContext().isCurrent()) {
183 @SuppressWarnings("unused")
184 int ret = getComponent().getContext().makeCurrent();
185 // System.out.println("Make current2 " + ret);
189 public void unlock() {
190 getVTKLock().unlock();
193 private vtkScenePicker scenePicker;
197 public int getPickType() {
201 public void setPickType(int pickType) {
202 this.pickType = pickType;
205 public vtkProp[] pick(int x, int y) {
208 vtkRenderWindow rw = getRenderWindow();
209 vtkRenderer ren = getRenderer();
212 int ay = rw.GetSize()[1] - y;
215 throw new IllegalStateException("SWT Binding does not work with hw picking");
217 // ren.BreakOnError();
219 // vtkPropPicker picker = new vtkPropPicker();
221 // //picker.PickProp(x, rw.GetSize()[1] - y, ren);
222 // picker.Pick(x, rw.GetSize()[1] - y,0, ren);
226 // vtkAssemblyPath apath = picker.GetPath();
227 // return processPick(picker, apath);
229 } else if (pickType == 1) {
230 throw new IllegalStateException("SWT Binding does not work with hw picking");
231 // if (scenePicker == null) {
232 // scenePicker = new vtkScenePicker();
233 // scenePicker.SetRenderer(ren);
234 // scenePicker.EnableVertexPickingOn();
239 // vtkAssemblyPath apath = ren.PickProp(ax, ay);
243 // if (apath != null) {
244 // apath.InitTraversal();
245 // vtkAssemblyNode node = apath.GetLastNode();
246 // vtkProp test = (vtkProp) node.GetViewProp();
249 // return new vtkProp[]{test};
253 } else if (pickType == 2) {
254 vtkPointPicker picker = new vtkPointPicker();
255 //picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
256 picker.SetTolerance(0.00001);
258 picker.Pick(new double[]{ax, ay,0}, ren);
261 vtkAssemblyPath apath = picker.GetPath();
262 return processPick(picker, apath);
263 } else if (pickType == 3) {
264 vtkAreaPicker picker = new vtkAreaPicker();
266 picker.Pick(new double[]{ax, ay,0}, ren);
268 vtkAssemblyPath apath = picker.GetPath();
269 return processPick(picker, apath);
270 } else if (pickType == 4) {
271 vtkCellPicker picker = new vtkCellPicker();
272 picker.SetTolerance(0.00001);
274 picker.Pick(new double[]{ax, ay,0}, ren);
276 vtkAssemblyPath apath = picker.GetPath();
277 return processPick(picker, apath);
278 } else if (pickType == 5) {
279 vtkActor2DCollection coll = ren.GetActors2D();
280 coll.InitTraversal();
283 List<vtkActor2D> picked = new ArrayList<vtkActor2D>();
284 while ((a = coll.GetNextItem()) != null) {
285 double pos[] = a.GetPosition();
286 // TODO : width and height do not seem to affect the perceived size of Actor2D.
287 // actual size should be fetched from mapper.
288 double w = a.GetWidth();
289 double h = a.GetHeight();
290 int minx = (int)(pos[0]-w*0.5);
291 int miny = (int)(pos[1]-h*0.5);
292 int maxx = (int)(pos[0]+w*0.5);
293 int maxy = (int)(pos[1]+h*0.5);
294 if (minx <= ax && maxx >= ax &&
295 miny <= ay && maxy >= ay) {
299 return picked.toArray(new vtkProp[picked.size()]);
305 public vtkProp[] pick2(int x, int y) {
306 vtkRenderWindow rw = getRenderWindow();
307 vtkRenderer ren = getRenderer();
309 // vtkPicker picker = new vtkPicker();
310 // vtkAbstractPicker picker = new vtkAbstractPicker();
311 // picker.Pick(x, rw.GetSize()[1] - y, ren);
312 // // see page 60 of VTK user's guide
316 vtkPropPicker picker = new vtkPropPicker();
318 picker.PickProp(x, rw.GetSize()[1] - y, ren);
321 vtkPropCollection coll = picker.GetPickList();
322 return processPick(picker, coll);
324 } else if (pickType == 1) {
325 if (scenePicker == null) {
326 scenePicker = new vtkScenePicker();
327 scenePicker.SetRenderer(ren);
328 scenePicker.EnableVertexPickingOn();
329 scenePicker.DebugOn();
335 vtkAssemblyPath apath = ren.PickProp(x, rw.GetSize()[1] - y);
340 apath.InitTraversal();
343 vtkAssemblyNode node = apath.GetLastNode();
344 vtkProp test = (vtkProp) node.GetViewProp();
347 return new vtkProp[]{test};
351 } else if (pickType == 2) {
352 vtkPointPicker picker = new vtkPointPicker();
353 picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
355 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
357 vtkProp3DCollection coll = picker.GetProp3Ds();
358 return processPick(picker, coll);
359 } else if (pickType == 3) {
360 vtkAreaPicker picker = new vtkAreaPicker();
362 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
363 //picker.AreaPick(x-1, rw.GetSize()[1] - y-1,x+1,rw.GetSize()[1] - y+1, ren);
365 vtkProp3DCollection coll = picker.GetProp3Ds();
366 return processPick(picker, coll);
367 } else if (pickType == 4) {
368 vtkCellPicker picker = new vtkCellPicker();
369 picker.SetTolerance(2.0/(double)rw.GetSize()[0]);
371 picker.Pick(new double[]{x, rw.GetSize()[1] - y,0}, ren);
373 vtkProp3DCollection coll = picker.GetProp3Ds();
374 return processPick(picker, coll);
380 private vtkProp[] processPick(vtkAbstractPicker picker, vtkAssemblyPath apath) {
381 // double[] pickPos = picker.GetPickPosition();
384 apath.InitTraversal();
385 vtkProp result[] = new vtkProp[apath.GetNumberOfItems()];
386 for (int i = apath.GetNumberOfItems()-1; i >= 0; i--) {
387 vtkAssemblyNode node = apath.GetNextNode();
388 vtkProp test = (vtkProp) node.GetViewProp();
389 // System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());
400 private vtkProp[] processPick(vtkAbstractPicker picker, vtkPropCollection coll) {
401 // double[] pickPos = picker.GetPickPosition();
404 coll.InitTraversal();
405 vtkProp result[] = new vtkProp[coll.GetNumberOfItems()];
406 for (int i = coll.GetNumberOfItems()-1; i >= 0; i--) {
407 vtkProp test = coll.GetNextProp();
409 // System.out.println("Picked: " + test.GetClassName() + " " + test.GetVTKId());