]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.opencascade.vtk/src/org/simantics/opencascade/vtk/vtkSolidObject.java
Using SWT thread with Plant3d
[simantics/3d.git] / org.simantics.opencascade.vtk / src / org / simantics / opencascade / vtk / vtkSolidObject.java
1 /*******************************************************************************
2  * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.opencascade.vtk;
13
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.List;
17
18 import org.jcae.opencascade.jni.BRepMesh_IncrementalMesh;
19 import org.jcae.opencascade.jni.TopAbs_ShapeEnum;
20 import org.jcae.opencascade.jni.TopExp_Explorer;
21 import org.jcae.opencascade.jni.TopoDS_Face;
22 import org.jcae.opencascade.jni.TopoDS_Shape;
23 import org.simantics.g3d.vtk.common.VtkView;
24 import org.simantics.opencascade.OCCTTool;
25 import org.simantics.utils.datastructures.Pair;
26 import org.simantics.utils.threads.ThreadUtils;
27
28 import vtk.vtkActor;
29 import vtk.vtkAlgorithmOutput;
30 import vtk.vtkCleanPolyData;
31 import vtk.vtkDataSetMapper;
32 import vtk.vtkFeatureEdges;
33 import vtk.vtkGlyph3D;
34 import vtk.vtkPolyData;
35 import vtk.vtkPolyDataMapper;
36 import vtk.vtkPolyDataNormals;
37 import vtk.vtkPolyDataSilhouette;
38 import vtk.vtkProp3D;
39 import vtk.vtkProperty;
40 import vtk.vtkRenderer;
41 import vtk.vtkSphereSource;
42
43 public class vtkSolidObject {
44         
45         public static double deflection = 0.001;
46         
47         public static double featureAngle = 30;
48         public static boolean computeNormals = true;
49         public static boolean cleanPart = false;
50         public static boolean mergePoints = false;
51         
52         private VtkView panel;
53         private TopoDS_Shape shape;
54         
55         private List<vtkProp3D> actors = new ArrayList<vtkProp3D>(2);
56         
57         private List<vtkProp3D> solid = new ArrayList<vtkProp3D>(1);
58         private List<vtkProp3D> edges =  new ArrayList<vtkProp3D>(1);
59         private vtkActor silhouette = null;
60         
61         private boolean errors = false;
62         
63         public vtkSolidObject(VtkView panel,TopoDS_Shape shape) {
64                 this.shape = shape;
65                 this.panel = panel;
66         }
67         
68         public void visualizeSolid(boolean showEdges, boolean showVertices) {
69                 visualizeSolid(true, showEdges, showVertices);
70         }
71         
72         public void visualizeSolid(boolean showFaces, boolean showEdges, boolean showVertices) {
73                 visualizeSolid(showFaces, showEdges, showVertices, false);
74         }
75         
76         public void visualizeSolid(boolean showFaces, boolean showEdges, boolean showVertices, boolean showSilhouette) {
77                 clearActorsVTK();
78                 errors = false;
79                 Pair<vtkPolyData, Boolean> res = createSolidMesh(shape);
80                 if (res == null) {
81                         errors = true;
82                         return;
83                 }
84                 vtkPolyData data = res.first;
85                 if (!res.second)
86                         errors = true;
87                 if (showFaces) {
88                         solid.add(createActor(data));           
89                 }
90                 if (showEdges) {
91                         vtkActor edge = createEdgesActor(data);
92                         edges.add(edge);                        
93                         if (showVertices) {
94                                 actors.add(createVerticesActor(edge));
95                         }
96                 }
97                 if (showSilhouette) {
98                         silhouette = createSilhouette(panel.getRenderer(), data);
99                 }
100                 actors.addAll(solid);
101                 actors.addAll(edges);
102                 if (silhouette != null)
103                         actors.add(silhouette);
104                 data.Delete();
105                 showActorsVTK();
106         }
107         
108         public void visualizeFaces(boolean showEdges, boolean showVertices) {
109                 errors = false;
110                 clearActorsVTK();
111                 Collection<vtkPolyData> datas = createFaceMeshes(shape);
112                 for (vtkPolyData data : datas) {
113                         if (data == null) {
114                                 errors = true;
115                                 continue;
116                         }
117                         
118                         solid.add(createActor(data));
119                         
120                         if (showEdges) {
121                                 vtkActor edgesActor = createEdgesActor(data); 
122                                 edges.add(edgesActor);
123                                 if (showVertices) {
124                                         actors.add(createVerticesActor(edgesActor));
125                                 }
126                         }
127                         data.Delete();
128                 }
129                 actors.addAll(solid);
130                 actors.addAll(edges);
131                 
132                 showActorsVTK();
133         }
134         
135         public boolean hasErrors() {
136                 return errors;
137         }
138         
139         public List<vtkProp3D> getActors() {
140                 assert (Thread.currentThread() == panel.getThreadQueue().getThread());
141                 return actors;
142         }
143         
144         public List<vtkProp3D> getSolid() {
145                 assert (Thread.currentThread() == panel.getThreadQueue().getThread());
146                 return solid;
147         }
148         
149         public List<vtkProp3D> getEdges() {
150                 assert (Thread.currentThread() == panel.getThreadQueue().getThread());
151                 return edges;
152         }
153         
154         public vtkActor getSilhouette() {
155                 assert (Thread.currentThread() == panel.getThreadQueue().getThread());
156                 return silhouette;
157         }
158         
159         public void showActorsVTK() {
160                 assert (Thread.currentThread() == panel.getThreadQueue().getThread());
161                 panel.lock();
162                 vtkRenderer ren = panel.getRenderer();
163                 for (vtkProp3D act : actors) {
164                         ren.AddActor(act);
165                 }
166                 panel.unlock();
167         }
168         
169         public void showActors() {
170                 ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
171                         
172                         @Override
173                         public void run() {
174                                 showActorsVTK();
175                         }
176                 });
177         }
178         
179         public void clearActorsVTK() {
180                 assert (Thread.currentThread() == panel.getThreadQueue().getThread());
181                 if (actors.size() == 0)
182                         return;
183                 vtkRenderer ren = panel.getRenderer();
184                 if (ren == null)
185                         return;
186                 panel.lock();
187                 for (vtkProp3D act : actors) {
188                         if (act.GetVTKId() != 0) {
189                                 ren.RemoveActor(act);
190                                 act.Delete();
191                         }
192                 }
193                 panel.unlock();
194                 actors.clear();
195                 solid.clear();
196                 edges.clear();
197         }
198         
199         private void clearActorsAWT(List<vtkProp3D> actors) {
200                 assert (Thread.currentThread() == panel.getThreadQueue().getThread());
201                 
202                 if (actors.size() == 0)
203                         return;
204                 vtkRenderer ren = panel.getRenderer();
205                 if (ren == null)
206                         return;
207                 panel.lock();
208                 for (vtkProp3D act : actors) {
209                         if (act.GetVTKId() != 0) {
210                                 ren.RemoveActor(act);
211                                 act.Delete();
212                         }
213                 }
214                 panel.unlock();
215         }
216         
217         public void clearActors() {
218                 if (actors.size() == 0)
219                         return;
220                 final List<vtkProp3D> temp = new ArrayList<vtkProp3D>(actors.size());
221                 temp.addAll(actors);
222                 actors.clear();
223                 solid.clear();
224                 edges.clear();
225                 ThreadUtils.asyncExec(panel.getThreadQueue(), new Runnable() {
226                         
227                         @Override
228                         public void run() {
229                                 clearActorsAWT(temp);
230                         }
231                 });
232         }
233         
234         public void dispose() {
235                 if (shape != null) {
236                         shape.delete();
237                         shape = null;
238                 }
239                 clearActors();
240         }
241         
242         public void delete() {
243                 if (shape != null) {
244                         shape.delete();
245                         shape = null;
246                 }
247                 clearActorsVTK();
248         }
249         
250         private static double TOLERANCE = 0.01;
251         
252         public static Pair<vtkPolyData, Boolean> createSolidMesh(TopoDS_Shape shape) {
253                 
254                 boolean success = true;
255                 
256                 double volume = OCCTTool.getBoundingBoxDiagonal(shape);
257                 if (volume < TOLERANCE)
258                         return null;
259                 
260                 BRepMesh_IncrementalMesh mesh = new BRepMesh_IncrementalMesh(shape,deflection*volume);
261         
262                 TopExp_Explorer expFace = new TopExp_Explorer();
263                 
264                 List<Double> meshPoints = new ArrayList<Double>();
265                 List<Integer> meshTriangles = new ArrayList<Integer>();
266                 for (expFace.init(shape, TopAbs_ShapeEnum.FACE); expFace.more(); expFace.next()) {
267                         TopoDS_Face face = (TopoDS_Face) expFace.current();
268                         if (!OCCTTool.appendToMesh(face, meshPoints, meshTriangles))
269                                 success = false;
270                         face.delete();
271                 }
272                 if (meshPoints.size() == 0 || meshTriangles.size() == 0)
273                         return null;
274                         
275                 vtkPolyData data = VTKOCCTool.createPartGrid(meshPoints, meshTriangles);
276                 
277                 expFace.delete();
278                 mesh.delete();
279                 
280                 return new Pair<vtkPolyData, Boolean>(data, success);
281         }
282         
283         public static Collection<vtkPolyData> createFaceMeshes(TopoDS_Shape shape) {
284                 
285                 double volume = OCCTTool.getBoundingBoxDiagonal(shape);
286                 Collection<vtkPolyData> faces = new ArrayList<vtkPolyData>();
287                 
288                 if (volume > TOLERANCE) {
289                 
290                         BRepMesh_IncrementalMesh mesh = new BRepMesh_IncrementalMesh(shape,deflection*volume);
291                 
292                         TopExp_Explorer expFace = new TopExp_Explorer();
293                         
294                         
295                         for (expFace.init(shape, TopAbs_ShapeEnum.FACE); expFace.more(); expFace.next()) {
296                                 TopoDS_Face face = (TopoDS_Face) expFace.current();
297                                 vtkPolyData data = VTKOCCTool.createPartGrid(face);
298                                 face.delete();
299                                 faces.add(data);
300                         }
301                         
302                         expFace.delete();
303                         mesh.delete();
304                 }
305                 
306                 return faces;
307         }
308         
309         
310         
311         public static vtkActor createActor(vtkPolyData partGrid) {
312                 
313                 
314             vtkDataSetMapper partMapper = new vtkDataSetMapper();
315             
316             vtkCleanPolyData partCleaner = null;       
317             if (cleanPart)
318             {
319                 partCleaner = new vtkCleanPolyData();
320                 partCleaner.SetInputData(partGrid);
321                 if(mergePoints) {
322                   partCleaner.PointMergingOn();
323                 } else {
324                   partCleaner.PointMergingOff();
325                 }
326             }
327             
328             if (computeNormals)
329             {
330                 vtkPolyDataNormals partNormals = new vtkPolyDataNormals();
331              
332                 if (cleanPart)
333                 {
334                         vtkAlgorithmOutput out = partCleaner.GetOutputPort();
335                     partNormals.SetInputConnection(out);
336                     out.Delete();
337                 }
338                 else partNormals.SetInputData(partGrid);
339                     
340                 partNormals.SetFeatureAngle(featureAngle); // this do not have to be neccesarily called
341                 vtkAlgorithmOutput out = partNormals.GetOutputPort();
342                 partMapper.SetInputConnection(out);
343                 out.Delete();
344                 partNormals.Delete();          
345             }
346             else
347             {
348                 if (cleanPart) {
349                         vtkAlgorithmOutput out = partCleaner.GetOutputPort();
350                         partMapper.SetInputConnection(out); // metoda 2, ne tak pekne, viz http://www.codeguru.com/cpp/g-m/opengl/article.php/c2681
351                         out.Delete();
352                 }
353                 else partMapper.SetInputData(partGrid); // metoda 1, ne tak pekne stinovani, viz: http://www.codeguru.com/cpp/g-m/opengl/article.php/c2681
354             }
355             partMapper.ScalarVisibilityOn();
356             
357             vtkActor partActor = new vtkActor();
358            // partActor.SetPickable(1);
359             vtkProperty prop = partActor.GetProperty();
360             prop.SetColor(1, 1, 0);
361             prop.Delete();
362             partActor.SetMapper(partMapper);
363             
364             partMapper.Delete();
365             
366             if (cleanPart)
367                 partCleaner.Delete();
368             
369             return partActor;
370         }
371         
372         public static vtkActor createEdgesActor(vtkPolyData partGrid) {
373                 vtkCleanPolyData partCleaner = null;       
374            
375                 if (cleanPart)
376             {
377                         partCleaner = new vtkCleanPolyData();
378                 partCleaner.SetInputData(partGrid);
379                 if(mergePoints) {
380                   partCleaner.PointMergingOn();
381                 } else {
382                   partCleaner.PointMergingOff();
383                 }
384             }
385             
386                 vtkFeatureEdges partEdges = new vtkFeatureEdges();
387             if (cleanPart) {
388                 vtkAlgorithmOutput out = partCleaner.GetOutputPort();
389                 partEdges.SetInputConnection(out);
390                 out.Delete();
391             }
392             else partEdges.SetInputData(partGrid); 
393            // partEdges.SetFeatureAngle(featureAngle);  // this do not have to be neccesarily called
394             partEdges.FeatureEdgesOn();
395             partEdges.BoundaryEdgesOn();
396             partEdges.NonManifoldEdgesOn();
397             partEdges.ManifoldEdgesOn();
398         
399             vtkDataSetMapper partEdgesMapper = new vtkDataSetMapper();
400             vtkAlgorithmOutput out = partEdges.GetOutputPort();
401             partEdgesMapper.SetInputConnection(out);
402             out.Delete();
403             partEdgesMapper.SetResolveCoincidentTopologyToPolygonOffset();
404             partEdgesMapper.ScalarVisibilityOff();
405             
406             vtkActor partEdgesActor = new vtkActor();
407            
408             vtkProperty prop = partEdgesActor.GetProperty();
409             prop.SetColor(0, 0, 0);
410             prop.SetLineWidth(2.0);
411             prop.Delete();
412             partEdgesActor.SetMapper(partEdgesMapper);
413
414             partEdgesMapper.Delete();
415             partEdges.Delete();
416             
417             if (cleanPart)
418                 partCleaner.Delete();
419             
420             return partEdgesActor;
421         }
422         
423         public static vtkActor createVerticesActor(vtkActor partEdgesActor) {
424                 vtkDataSetMapper partEdgesMapper = (vtkDataSetMapper) partEdgesActor.GetMapper();
425                 vtkAlgorithmOutput out = partEdgesMapper.GetInputConnection(0, 0);
426                 vtkFeatureEdges partEdges = (vtkFeatureEdges)out.GetProducer();
427                 
428                 vtkActor edgePointsActor = createVerticesActor(partEdges);
429                 
430                 partEdges.Delete();
431                 //out.Delete();
432                 partEdgesMapper.Delete();
433                 return edgePointsActor;
434         }
435         
436         public static vtkActor createVerticesActor(vtkFeatureEdges partEdges) {
437                 EdgePointsFilter edgePoints = new EdgePointsFilter();
438         
439          
440         vtkAlgorithmOutput out = partEdges.GetOutputPort();
441             edgePoints.SetInputConnection(out);
442             out.Delete();
443             
444             vtkSphereSource sphereSource = new vtkSphereSource();
445             vtkGlyph3D glyph3D = new vtkGlyph3D();
446             out = sphereSource.GetOutputPort();
447             glyph3D.SetSourceConnection(out);
448             out.Delete();
449             
450             out = edgePoints.GetOutputPort();
451             glyph3D.SetInputConnection(out);
452             out.Delete();
453             
454             glyph3D.SetScaleFactor(0.03);
455             
456             glyph3D.Update();
457             
458             vtkPolyDataMapper partEdgePointsMapper = new vtkPolyDataMapper();
459             out = glyph3D.GetOutputPort();
460             partEdgePointsMapper.SetInputConnection(out);
461             out.Delete();
462             
463             vtkActor edgePointsActor = new vtkActor();
464            
465             vtkProperty prop = edgePointsActor.GetProperty();
466             prop.SetColor(0, 0, 1);
467             prop.Delete();
468             edgePointsActor.SetMapper(partEdgePointsMapper);
469            
470             edgePointsActor.PickableOn();
471
472             
473             partEdgePointsMapper.Delete();
474             edgePoints.Delete();
475             sphereSource.Delete();
476             
477             return edgePointsActor;
478         }
479         
480         public static vtkActor createSilhouette(vtkRenderer ren, vtkPolyData data) {
481                 
482                 
483                 vtkPolyDataSilhouette silhouette = new vtkPolyDataSilhouette();
484                 
485                 silhouette.SetInputData(data);
486                 silhouette.SetCamera(ren.GetActiveCamera());
487                 silhouette.SetEnableFeatureAngle(0);
488                 vtkPolyDataMapper mapper = new vtkPolyDataMapper();
489                 
490                 mapper.SetInputConnection(silhouette.GetOutputPort());
491                 
492                 vtkActor actor = new vtkActor();
493                 actor.SetMapper(mapper);
494                 
495                 actor.GetProperty().SetColor(0,0,1);
496                 actor.GetProperty().SetLineWidth(6);
497                 
498                 return actor;
499                 
500                 
501                 
502         }
503
504 }