]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.opencascade.vtk/src/org/simantics/opencascade/vtk/VTKOCCTool.java
vtk 8.2.0 API changes
[simantics/3d.git] / org.simantics.opencascade.vtk / src / org / simantics / opencascade / vtk / VTKOCCTool.java
index 187c7853e628d8a3edc69b99279cf5a183376462..8f8c7b1523ea589358106b8c1a9b815a7ce55a47 100644 (file)
-package org.simantics.opencascade.vtk;\r
-\r
-import java.util.List;\r
-\r
-import javax.vecmath.Matrix4d;\r
-import javax.vecmath.Point3d;\r
-\r
-import org.jcae.opencascade.jni.BRepMesh_IncrementalMesh;\r
-import org.jcae.opencascade.jni.BRep_Tool;\r
-import org.jcae.opencascade.jni.GP_Trsf;\r
-import org.jcae.opencascade.jni.Poly_Triangulation;\r
-import org.jcae.opencascade.jni.TopAbs_Orientation;\r
-import org.jcae.opencascade.jni.TopAbs_ShapeEnum;\r
-import org.jcae.opencascade.jni.TopExp_Explorer;\r
-import org.jcae.opencascade.jni.TopLoc_Location;\r
-import org.jcae.opencascade.jni.TopoDS_Face;\r
-import org.jcae.opencascade.jni.TopoDS_Shape;\r
-import org.simantics.opencascade.OCCTTool;\r
-\r
-import vtk.vtkActor;\r
-import vtk.vtkAlgorithmOutput;\r
-import vtk.vtkAppendPolyData;\r
-import vtk.vtkAssembly;\r
-import vtk.vtkCleanPolyData;\r
-import vtk.vtkDataSetMapper;\r
-import vtk.vtkFeatureEdges;\r
-import vtk.vtkGlyph3D;\r
-import vtk.vtkIdList;\r
-import vtk.vtkPoints;\r
-import vtk.vtkPolyData;\r
-import vtk.vtkPolyDataMapper;\r
-import vtk.vtkPolyDataNormals;\r
-import vtk.vtkProp;\r
-import vtk.vtkPropCollection;\r
-import vtk.vtkProperty;\r
-import vtk.vtkSphereSource;\r
-import vtk.vtkTriangle;\r
-\r
-public class VTKOCCTool {\r
-       public static vtkAssembly vtkTestAssembly() {\r
-               vtkAssembly assemblies = new vtkAssembly();\r
-               vtkPolyData partGrid = createTestPartGrid();\r
-               gridToAssembly(assemblies, partGrid);\r
-               return assemblies;\r
-       }\r
-       \r
-       public static vtkAssembly vtkOCCShapeToAssembly(TopoDS_Shape shape) {\r
-               double deflection = 0.001;\r
-\r
-               if (deflection <= 0.0) {\r
-                       deflection = 0.0005;\r
-                       System.out.println("Bad value for deflection. Using: " + deflection);\r
-               }\r
-\r
-               // FIXME : leaks memory!\r
-               //BRepTools.clean(shape);\r
-\r
-               double mass = OCCTTool.getMass(shape);\r
-\r
-               if (mass < 1.0e-12) {\r
-                       System.out.println("Non 3D-shape detected");\r
-                       System.out.println("The cad import features are currently limited to 3D models.");\r
-               }\r
-\r
-               double length = OCCTTool.getBoundingBoxDiagonal(shape);\r
-               deflection *= length; // use relative units\r
-\r
-               BRepMesh_IncrementalMesh mesh = new BRepMesh_IncrementalMesh(shape,deflection);\r
-\r
-               int faceNumber = 0;\r
-               TopExp_Explorer expFace = new TopExp_Explorer();\r
-\r
-               vtkAssembly assemblies = new vtkAssembly();\r
-               for (expFace.init(shape, TopAbs_ShapeEnum.FACE); expFace.more(); expFace.next()) {\r
-                       TopoDS_Face face = (TopoDS_Face) expFace.current();\r
-                       vtkPolyData partGrid = createPartGrid(face);\r
-                       face.delete();\r
-                       if (partGrid == null)\r
-                               continue;\r
-                       faceNumber++;\r
-                       //gridToAssembly(assemblies, partGrid, stlSurfaceData, stlEdgeData);\r
-                       gridToAssembly(assemblies, partGrid);\r
-                       \r
-               }\r
-               expFace.delete();\r
-               mesh.delete();\r
-\r
-               if (faceNumber == 0) {\r
-                       System.out\r
-                                       .println("Cad import: error: no surface triangulation was generated.");\r
-                       return null;\r
-               }\r
-\r
-               return assemblies;\r
-       }\r
-       \r
-       private static void gridToAssembly(vtkAssembly assemblies, vtkPolyData partGrid, vtkAppendPolyData stlSurfaceData, vtkAppendPolyData stlEdgeData) {\r
-        \r
-        double featureAngle = 30;\r
-\r
-        \r
-        vtkDataSetMapper partMapper = new vtkDataSetMapper();\r
-        \r
-        boolean computeNormals = true;\r
-        boolean cleanPart = true;\r
-        boolean mergePoints = false;\r
-\r
-        vtkCleanPolyData partCleaner = new vtkCleanPolyData();       \r
-        if (cleanPart)\r
-        {\r
-            partCleaner.SetInput(partGrid);\r
-            if(mergePoints) {\r
-              partCleaner.PointMergingOn();\r
-            } else {\r
-              partCleaner.PointMergingOff();\r
-            }\r
-        }\r
-        \r
-        if (computeNormals)\r
-        {\r
-            vtkPolyDataNormals partNormals = new vtkPolyDataNormals();\r
-         \r
-            if (cleanPart)\r
-            {\r
-                partNormals.SetInputConnection(partCleaner.GetOutputPort());\r
-            }\r
-            else partNormals.SetInput(partGrid);\r
-                \r
-            partNormals.SetFeatureAngle(featureAngle); // this do not have to be neccesarily called\r
-            partMapper.SetInputConnection(partNormals.GetOutputPort());\r
-            partNormals.Delete();          \r
-        }\r
-        else\r
-        {\r
-            if (cleanPart) partMapper.SetInputConnection(partCleaner.GetOutputPort()); // metoda 2, ne tak pekne, viz http://www.codeguru.com/cpp/g-m/opengl/article.php/c2681\r
-            else partMapper.SetInput(partGrid); // metoda 1, ne tak pekne stinovani, viz: http://www.codeguru.com/cpp/g-m/opengl/article.php/c2681\r
-        }\r
-        partMapper.ScalarVisibilityOn();\r
-        \r
-        vtkActor partActor = new vtkActor();\r
-\r
-        partActor.SetPickable(1);\r
-        partActor.GetProperty().SetColor(1, 1, 0);\r
-        partActor.SetMapper(partMapper);\r
-        \r
-        // EDGES OF PARTS DETECTION\r
-        vtkFeatureEdges partEdges = new vtkFeatureEdges();\r
-        if (cleanPart) partEdges.SetInputConnection(partCleaner.GetOutputPort());\r
-        else partEdges.SetInput(partGrid); \r
-        partEdges.SetFeatureAngle(featureAngle);  // this do not have to be neccesarily called\r
-        partEdges.FeatureEdgesOn();\r
-        partEdges.BoundaryEdgesOn();\r
-        partEdges.NonManifoldEdgesOn();\r
-        partEdges.ManifoldEdgesOn();\r
-\r
-        vtkDataSetMapper partEdgesMapper = new vtkDataSetMapper();\r
-        partEdgesMapper.SetInputConnection(partEdges.GetOutputPort());\r
-        partEdgesMapper.SetResolveCoincidentTopologyToPolygonOffset();\r
-        partEdgesMapper.ScalarVisibilityOff();\r
-        \r
-        vtkActor partEdgesActor = new vtkActor();\r
-        partEdgesActor.SetPickable(0);\r
-        partEdgesActor.GetProperty().SetColor(1, 0, 1);\r
-        partEdgesActor.SetMapper(partEdgesMapper);\r
-        \r
-\r
-        // Add triangles and edges to STL structures:\r
-        //--------------------------------------------\r
-        if (cleanPart) stlSurfaceData.AddInput(partCleaner.GetOutput());\r
-        else stlSurfaceData.AddInput(partGrid);\r
-        stlEdgeData.AddInput(partEdges.GetOutput());\r
-                \r
-        assemblies.AddPart(partActor);\r
-        assemblies.AddPart(partEdgesActor);        \r
-        \r
-        // Clean up:\r
-        //----------\r
-        partEdgesActor.Delete();\r
-        partEdgesMapper.Delete();\r
-        partEdges.Delete();\r
-        partActor.Delete();\r
-        partMapper.Delete();\r
-        partGrid.Delete();\r
-        partCleaner.Delete();\r
-    }\r
-\r
-public static void gridToAssembly(vtkAssembly assemblies, vtkPolyData partGrid) {\r
-    \r
-    double featureAngle = 30;\r
-\r
-    \r
-    vtkDataSetMapper partMapper = new vtkDataSetMapper();\r
-    \r
-    boolean computeNormals = true;\r
-    boolean cleanPart = false;\r
-    boolean mergePoints = false;\r
-\r
-    vtkCleanPolyData partCleaner = new vtkCleanPolyData();       \r
-    if (cleanPart)\r
-    {\r
-        partCleaner.SetInput(partGrid);\r
-        if(mergePoints) {\r
-          partCleaner.PointMergingOn();\r
-        } else {\r
-          partCleaner.PointMergingOff();\r
-        }\r
-    }\r
-    \r
-    if (computeNormals)\r
-    {\r
-        vtkPolyDataNormals partNormals = new vtkPolyDataNormals();\r
-     \r
-        if (cleanPart)\r
-        {\r
-               vtkAlgorithmOutput out = partCleaner.GetOutputPort();\r
-            partNormals.SetInputConnection(out);\r
-            out.Delete();\r
-        }\r
-        else partNormals.SetInput(partGrid);\r
-            \r
-        partNormals.SetFeatureAngle(featureAngle); // this do not have to be neccesarily called\r
-        vtkAlgorithmOutput out = partNormals.GetOutputPort();\r
-        partMapper.SetInputConnection(out);\r
-        out.Delete();\r
-        partNormals.Delete();          \r
-    }\r
-    else\r
-    {\r
-        if (cleanPart) {\r
-               vtkAlgorithmOutput out = partCleaner.GetOutputPort();\r
-               partMapper.SetInputConnection(out); // metoda 2, ne tak pekne, viz http://www.codeguru.com/cpp/g-m/opengl/article.php/c2681\r
-               out.Delete();\r
-        }\r
-        else partMapper.SetInput(partGrid); // metoda 1, ne tak pekne stinovani, viz: http://www.codeguru.com/cpp/g-m/opengl/article.php/c2681\r
-    }\r
-    partMapper.ScalarVisibilityOn();\r
-    \r
-    vtkActor partActor = new vtkActor();\r
-    partActor.SetPickable(1);\r
-    vtkProperty prop = partActor.GetProperty();\r
-    prop.SetColor(1, 1, 0);\r
-    prop.Delete();\r
-    partActor.SetMapper(partMapper);\r
-    \r
-    assemblies.AddPart(partActor);\r
-    \r
-    {\r
-           // EDGES OF PARTS DETECTION\r
-           vtkFeatureEdges partEdges = new vtkFeatureEdges();\r
-           if (cleanPart) {\r
-               vtkAlgorithmOutput out = partCleaner.GetOutputPort();\r
-               partEdges.SetInputConnection(out);\r
-               out.Delete();\r
-           }\r
-           else partEdges.SetInput(partGrid); \r
-          // partEdges.SetFeatureAngle(featureAngle);  // this do not have to be neccesarily called\r
-           partEdges.FeatureEdgesOn();\r
-           partEdges.BoundaryEdgesOn();\r
-           partEdges.NonManifoldEdgesOn();\r
-           partEdges.ManifoldEdgesOn();\r
-       \r
-           vtkDataSetMapper partEdgesMapper = new vtkDataSetMapper();\r
-           vtkAlgorithmOutput out = partEdges.GetOutputPort();\r
-           partEdgesMapper.SetInputConnection(out);\r
-           out.Delete();\r
-           partEdgesMapper.SetResolveCoincidentTopologyToPolygonOffset();\r
-           partEdgesMapper.ScalarVisibilityOff();\r
-           \r
-           vtkActor partEdgesActor = new vtkActor();\r
-          \r
-           prop = partEdgesActor.GetProperty();\r
-           prop.SetColor(0, 0, 0);\r
-           prop.SetLineWidth(2.0);\r
-           prop.Delete();\r
-           partEdgesActor.SetMapper(partEdgesMapper);\r
-           partEdgesActor.PickableOn();  \r
-           \r
-           assemblies.AddPart(partEdgesActor);        \r
-           \r
-           {\r
-\r
-               EdgePointsFilter edgePoints = new EdgePointsFilter();\r
-               \r
-                \r
-               out = partEdges.GetOutputPort();\r
-                   edgePoints.SetInputConnection(out);\r
-                   out.Delete();\r
-                   \r
-//                 vtkDataSetMapper partEdgePointsMapper = new vtkDataSetMapper();\r
-//                 out = edgePoints.GetOutputPort();\r
-//                 partEdgePointsMapper.SetInputConnection(out);\r
-//                 out.Delete();\r
-                   \r
-//                 vtkVertexGlyphFilter glyphFilter = new vtkVertexGlyphFilter();\r
-//                 out = edgePoints.GetOutputPort();\r
-//                 glyphFilter.SetInputConnection(out);\r
-//                 glyphFilter.Update();\r
-//                 out.Delete();\r
-//                 \r
-//                 vtkPolyDataMapper partEdgePointsMapper = new vtkPolyDataMapper();\r
-//                 out = glyphFilter.GetOutputPort();\r
-//                 partEdgePointsMapper.SetInputConnection(out);\r
-//                 out.Delete();\r
-                   \r
-                   vtkSphereSource sphereSource = new vtkSphereSource();\r
-                   vtkGlyph3D glyph3D = new vtkGlyph3D();\r
-                   out = sphereSource.GetOutputPort();\r
-                   glyph3D.SetSourceConnection(out);\r
-                   out.Delete();\r
-                   \r
-                   out = edgePoints.GetOutputPort();\r
-                   glyph3D.SetInputConnection(out);\r
-                   out.Delete();\r
-                   \r
-                   //glyph3D.ScalingOff();\r
-                   glyph3D.SetScaleFactor(0.03);\r
-                   \r
-                   glyph3D.Update();\r
-                   \r
-                   vtkPolyDataMapper partEdgePointsMapper = new vtkPolyDataMapper();\r
-                   out = glyph3D.GetOutputPort();\r
-                   partEdgePointsMapper.SetInputConnection(out);\r
-                   out.Delete();\r
-                   \r
-                   vtkActor edgePointsActor = new vtkActor();\r
-                  \r
-                   prop = edgePointsActor.GetProperty();\r
-                   prop.SetColor(0, 0, 1);\r
-                   //prop.SetPointSize(10.0);\r
-                   //prop.SetRepresentationToPoints();\r
-                   prop.Delete();\r
-                   edgePointsActor.SetMapper(partEdgePointsMapper);\r
-                  \r
-                   edgePointsActor.PickableOn();\r
-                   assemblies.AddPart(edgePointsActor);\r
-                   \r
-                   \r
-                   edgePointsActor.Delete();\r
-                   partEdgePointsMapper.Delete();\r
-                  // edgePoints.Delete();\r
-           }\r
-           // Clean up:\r
-           //----------\r
-           partEdgesActor.Delete();\r
-           partEdgesMapper.Delete();\r
-           partEdges.Delete();\r
-    }\r
-   \r
-    partActor.Delete();\r
-    partMapper.Delete();\r
-    partGrid.Delete();\r
-    partCleaner.Delete();\r
-}\r
-       \r
-       \r
-       \r
-       public static vtkPolyData createPartGrid ( TopoDS_Face face)\r
-    {\r
-        TopLoc_Location Location = new TopLoc_Location();\r
-        \r
-        Poly_Triangulation triangulation = BRep_Tool.triangulation(face, Location);\r
-\r
-        if(triangulation == null) {\r
-               Location.delete();\r
-               System.out.println("Encountered empty triangulation after face");\r
-               return null;\r
-        }\r
-                \r
-        boolean reverse = face.orientation()==TopAbs_Orientation.REVERSED;\r
-\r
-        int[]triangles = triangulation.triangles();\r
-        double[]nodes = triangulation.nodes();\r
-\r
-        int nofTriangles = triangulation.nbTriangles();\r
-        int nofNodes = triangulation.nbNodes();\r
-        \r
-        triangulation.delete();\r
-\r
-        if(nofTriangles < 1) {\r
-          System.out.println("No triangles for mesh on face");\r
-          Location.delete();\r
-          return null;\r
-        }\r
-\r
-        if(nofNodes < 1) {\r
-            System.out.println("No nodes for mesh on face:");\r
-            Location.delete();\r
-            return null;\r
-        }\r
-        //System.out.println("v " + nofNodes + " t " +nofTriangles);\r
-        vtkPolyData partGrid = new vtkPolyData();\r
-        partGrid.Allocate(nofTriangles, nofTriangles);\r
-\r
-        vtkTriangle triangle = new vtkTriangle();\r
-        vtkIdList list = triangle.GetPointIds();\r
-        for(int i = 0; i < nofTriangles; i++) \r
-        {\r
-          int n0, n1, n2;\r
-          if (!reverse) {\r
-                 n0 = triangles[3 * i]; \r
-                 n1 = triangles[3 * i + 1]; \r
-                 n2 = triangles[3 * i + 2];\r
-          } else {\r
-                 n0 = triangles[3 * i + 2]; \r
-                 n1 = triangles[3 * i + 1]; \r
-                 n2 = triangles[3 * i];\r
-          }\r
-          \r
-          list.SetId(0, n0);\r
-          list.SetId(1, n1);\r
-          list.SetId(2, n2);\r
-          partGrid.InsertNextCell(triangle.GetCellType(), list);\r
-          \r
-        }\r
-        list.Delete();\r
-        triangle.Delete();   \r
-        \r
-        GP_Trsf transformation = Location.transformation();\r
-        Location.delete();\r
-\r
-        double d_mat[] = new double[16];\r
-        double d_p[] = new double[3];\r
-        transformation.getValues(d_mat);\r
-        Matrix4d mat = new Matrix4d(d_mat);\r
-        \r
-        vtkPoints partPoints = new vtkPoints();\r
-        \r
-        for(int i = 0; i < nofNodes; i++) {     \r
-          // FIXME: GP_Trsf.transform(double[]) leaks memory\r
-               \r
-          //double xyz[] = new double[]{nodes[3 * i], nodes[3 * i + 1], nodes[3 * i + 2]};          \r
-          //transformation.transforms(xyz);\r
-          //partPoints.InsertPoint(i, xyz);\r
-               Point3d p = new Point3d(nodes[3 * i], nodes[3 * i + 1], nodes[3 * i + 2]);\r
-               mat.transform(p);\r
-               d_p[0] = p.x;\r
-               d_p[1] = p.y;\r
-               d_p[2] = p.z;\r
-               partPoints.InsertPoint(i, d_p);\r
-        }\r
-        \r
-        transformation.delete();\r
-        \r
-        partGrid.SetPoints(partPoints);\r
-        partPoints.Delete();\r
-       \r
-        return partGrid;\r
-    }\r
-       \r
-       \r
-       \r
-       public static vtkPolyData createPartGrid ( List<Double> meshPoints, List<Integer> meshTriangles)\r
-    {\r
-       \r
-                \r
-      \r
-\r
-        \r
-        int nofTriangles = meshTriangles.size() / 3;\r
-        int nofNodes = meshPoints.size() /3;\r
-        \r
-      \r
-        if(nofTriangles < 1) {\r
-          System.out.println("No triangles for mesh on face");\r
-          return null;\r
-        }\r
-\r
-        if(nofNodes < 1) {\r
-            System.out.println("No nodes for mesh on face:");\r
-            return null;\r
-        }\r
-        //System.out.println("v " + nofNodes + " t " +nofTriangles);\r
-        vtkPolyData partGrid = new vtkPolyData();\r
-        partGrid.Allocate(nofTriangles, nofTriangles);\r
-\r
-        vtkTriangle triangle = new vtkTriangle();\r
-        vtkIdList list = triangle.GetPointIds();\r
-        for(int i = 0; i < nofTriangles; i++) \r
-        {\r
-          int n0, n1, n2;          \r
-          n0 = meshTriangles.get(3 * i); \r
-          n1 = meshTriangles.get(3 * i + 1);\r
-          n2 = meshTriangles.get(3 * i + 2); \r
-\r
-         \r
-          list.SetId(0, n0);\r
-          list.SetId(1, n1);\r
-          list.SetId(2, n2);\r
-          partGrid.InsertNextCell(triangle.GetCellType(), list);\r
-          \r
-        }\r
-        list.Delete();\r
-        triangle.Delete();   \r
-        \r
-\r
-\r
-        double d_p[] = new double[3];\r
-\r
-        \r
-        vtkPoints partPoints = new vtkPoints();\r
-        \r
-        for(int i = 0; i < nofNodes; i++) {     \r
-\r
-               d_p[0] = meshPoints.get(3*i);\r
-               d_p[1] = meshPoints.get(3*i+1);\r
-               d_p[2] = meshPoints.get(3*i+2);\r
-               partPoints.InsertPoint(i, d_p);\r
-        }\r
-        \r
-        partGrid.SetPoints(partPoints);\r
-        partPoints.Delete();\r
-       \r
-        return partGrid;\r
-    }\r
-       \r
-       private static vtkPolyData createTestPartGrid ()\r
-    {\r
-               int size = 64;\r
-               \r
-        double[] nodes = new double[(size+1)*(size+1)*3];\r
-        int[] triangles = new int[3 * size * size * 2];\r
-\r
-        double es = 1.0;\r
-        for (int i = 0; i <= size; i++) {\r
-               for (int j = 0; j <= size; j++) {\r
-                       int index = j * size + i;\r
-                       index *= 3;\r
-                       double x = (double)i * es;\r
-                       double y = (Math.sin((double)i/(double)size)  + Math.sin((double)j/(double)size)) * es;\r
-                       double z = (double)j * es;\r
-                       nodes[index] = x;\r
-                       nodes[index+1] = y;\r
-                       nodes[index+2] = z;\r
-               }\r
-        }\r
-        \r
-        for (int i = 0; i < size; i++) {\r
-               for (int j = 0; j < size; j++) {\r
-                       int index = j * size + i;\r
-                       index *= 3;\r
-                       index *= 2;\r
-                       triangles[index  ] = (j     * (size+1) + i  );\r
-                       triangles[index+1] = (j     * (size+1) + i+1);\r
-                       triangles[index+2] = ((j+1) * (size+1) + i  );\r
-                       triangles[index+3] = ((j+1) * (size+1) + i  );\r
-                       triangles[index+4] = ((j  ) * (size+1) + i +1 );\r
-                       triangles[index+5] = ((j+1) * (size+1) + i +1 );\r
-               }\r
-        }\r
-\r
-        int nofTriangles = triangles.length / 3;\r
-        int nofNodes = nodes.length / 3;\r
-\r
-        if(nofTriangles < 1) {\r
-         \r
-          return null;\r
-        }\r
-\r
-        if(nofNodes < 1) {\r
-           \r
-            return null;\r
-        }\r
-        //System.out.println("v " + nofNodes + " t " +nofTriangles);\r
-        vtkPolyData partGrid = new vtkPolyData();\r
-        partGrid.Allocate(nofTriangles, nofTriangles);\r
-\r
-        vtkTriangle triangle = new vtkTriangle();\r
-        vtkIdList list = triangle.GetPointIds();\r
-        for(int i = 0; i < nofTriangles; i++) \r
-        {\r
-          int n0, n1, n2;          \r
-          n0 = triangles[3 * i]; n1 = triangles[3 * i + 1]; n2 = triangles[3 * i + 2]; // triangles(i).Get(n0, n1, n2);\r
-\r
-//          if(face.orientation() != TopAbs_Orientation.FORWARD) {\r
-//              int tmp = n2; n2 = n1; n1 = tmp;\r
-//          }\r
-         \r
-          list.SetId(0, n0);\r
-          list.SetId(1, n1);\r
-          list.SetId(2, n2);\r
-          partGrid.InsertNextCell(triangle.GetCellType(), list);\r
-          \r
-        }\r
-        list.Delete();\r
-        triangle.Delete();      \r
-\r
-        vtkPoints partPoints = new vtkPoints();\r
-        for(int i = 0; i < nofNodes; i++) {       \r
-            double xyz[] = new double[]{nodes[3 * i], nodes[3 * i + 1], nodes[3 * i + 2]};          \r
-            partPoints.InsertPoint(i, xyz);\r
-        }\r
-        \r
-        partGrid.SetPoints(partPoints);\r
-        \r
-        partPoints.Delete();\r
-\r
-        return partGrid;\r
-    }\r
-       \r
-       public static void test() {\r
-               TopoDS_Shape shape = null;\r
-               //shape = OccTriangulator.makeCylinder(new double[]{0,0,0}, new double[]{0,1,0}, 1, 1);\r
-               for (int t = 0; t < 5000; t++) {\r
-                       //shape = OccTriangulator.makeCylinder(new double[]{0,0,0}, new double[]{0,1,0}, 1, 1);\r
-                       int test = 2;\r
-                       if (test == 0) {\r
-                               vtkAssembly ass = VTKOCCTool.vtkOCCShapeToAssembly(shape);\r
-                               vtkPropCollection col;\r
-                       col = ass.GetParts();\r
-                       for (int i = 0; i < col.GetNumberOfItems(); i++)\r
-                       {\r
-                           vtkProp prop = (vtkProp) col.GetItemAsObject(i);\r
-                           //System.out.println(prop.Print());\r
-                           prop.Delete();\r
-                       }\r
-                       col.Delete();\r
-                       ass.Delete();\r
-                       }\r
-                       else if (test == 1) {\r
-                               //BRepTools.clean(shape);\r
-                               \r
-                               \r
-                               vtkAssembly ass = new vtkAssembly();\r
-                               \r
-                               double vol = OCCTTool.getBoundingBoxDiagonal(shape);\r
-                               double d = 0.001 * vol;\r
-                               BRepMesh_IncrementalMesh mesh = new BRepMesh_IncrementalMesh(shape,d);\r
-                               TopExp_Explorer expFace = new TopExp_Explorer();\r
-                               for (expFace.init(shape, TopAbs_ShapeEnum.FACE); expFace.more(); expFace.next()) {\r
-                                       TopoDS_Face face = (TopoDS_Face) expFace.current();\r
-                                       {\r
-//                                             TopLoc_Location Location = new TopLoc_Location();\r
-//                                             Poly_Triangulation triangulation = BRep_Tool.triangulation(face, Location);\r
-//                                             if (triangulation != null) {\r
-//                                                     \r
-//                                                     int[]triangles = triangulation.triangles();\r
-//                                             double[]nodes = triangulation.nodes();\r
-//                                             int nofTriangles = triangulation.nbTriangles();\r
-//                                             int nofNodes = triangulation.nbNodes();\r
-//                                             \r
-//                                             triangulation.delete();\r
-//                                             \r
-//                                             GP_Trsf transformation = Location.transformation();\r
-//                                             double d_mat[] = new double[16];\r
-//                                             transformation.getValues(d_mat);\r
-//                                             Matrix4d mat = new Matrix4d(d_mat);\r
-//                                             for(int i = 0; i < nofNodes; i++) {       \r
-//                                                 //double xyz[] = new double[]{nodes[3 * i], nodes[3 * i + 1], nodes[3 * i + 2]};          \r
-//                                                 Point3d p = new Point3d(nodes[3 * i], nodes[3 * i + 1], nodes[3 * i + 2]);\r
-//                                                     //transformation.transforms(xyz);\r
-//                                                 mat.transform(p);\r
-//                                             }\r
-//                                             transformation.delete();\r
-//                                             }\r
-//                                             \r
-//                                             Location.delete();\r
-                                               vtkPolyData data = VTKOCCTool.createPartGrid(face);\r
-                                               VTKOCCTool.gridToAssembly(ass, data);\r
-                                               //data.Delete();\r
-                                       }\r
-                                       face.delete();\r
-                               }\r
-                               expFace.delete();\r
-                               mesh.delete();\r
-                               \r
-                               vtkPropCollection col;\r
-                       col = ass.GetParts();\r
-                       for (int i = 0; i < col.GetNumberOfItems(); i++)\r
-                       {\r
-                           vtkProp prop = (vtkProp) col.GetItemAsObject(i);\r
-                           //System.out.println(prop.Print());\r
-                           prop.Delete();\r
-                       }\r
-                       col.Delete();\r
-                       ass.Delete();\r
-                       } else if (test == 2) {\r
-                               double[] pointStruct = new double[]{0,0,0}, dirStruct = new double[]{0,1,0};\r
-                               double radius = 1.0;\r
-                               double height = 1.0;\r
-                               \r
-                               double[] axe = new double[6];\r
-                                \r
-                       System.arraycopy(pointStruct, 0, axe, 0, 3);\r
-                       System.arraycopy(dirStruct, 0, axe, 3, 3);\r
-                       org.jcae.opencascade.jni.BRepPrimAPI_MakeCylinder cyl = new org.jcae.opencascade.jni.BRepPrimAPI_MakeCylinder(axe, radius, height, 2 * Math.PI);\r
-                       org.jcae.opencascade.jni.TopoDS_Shape tds = cyl.shape();\r
-                       cyl.delete();\r
-                       \r
-                       double vol = OCCTTool.getBoundingBoxDiagonal(tds);\r
-                               double d = 0.001 * vol;\r
-                               BRepMesh_IncrementalMesh mesh = new BRepMesh_IncrementalMesh(tds,d);\r
-//                             TopExp_Explorer expFace = new TopExp_Explorer();\r
-//                             for (expFace.init(tds, TopAbs_ShapeEnum.FACE); expFace.more(); expFace.next()) {\r
-//                                     TopoDS_Face face = (TopoDS_Face) expFace.current();\r
-//                                     {\r
-//                                             \r
-//                                     }\r
-//                                     face.delete();\r
-//                             }\r
-                               mesh.delete();\r
-                               \r
-                       tds.delete();\r
-                       }\r
-                       //shape.delete();\r
-               System.out.println(t);\r
-               }\r
-               //shape.delete();\r
-       }\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.opencascade.vtk;
+
+import java.util.List;
+
+import javax.vecmath.Matrix4d;
+import javax.vecmath.Point3d;
+
+import org.jcae.opencascade.jni.BRepMesh_IncrementalMesh;
+import org.jcae.opencascade.jni.BRep_Tool;
+import org.jcae.opencascade.jni.GP_Trsf;
+import org.jcae.opencascade.jni.Poly_Triangulation;
+import org.jcae.opencascade.jni.TopAbs_Orientation;
+import org.jcae.opencascade.jni.TopAbs_ShapeEnum;
+import org.jcae.opencascade.jni.TopExp_Explorer;
+import org.jcae.opencascade.jni.TopLoc_Location;
+import org.jcae.opencascade.jni.TopoDS_Face;
+import org.jcae.opencascade.jni.TopoDS_Shape;
+import org.simantics.opencascade.OCCTTool;
+
+import vtk.vtkActor;
+import vtk.vtkAlgorithmOutput;
+import vtk.vtkAppendPolyData;
+import vtk.vtkAssembly;
+import vtk.vtkCleanPolyData;
+import vtk.vtkDataSetMapper;
+import vtk.vtkFeatureEdges;
+import vtk.vtkGlyph3D;
+import vtk.vtkIdList;
+import vtk.vtkPoints;
+import vtk.vtkPolyData;
+import vtk.vtkPolyDataMapper;
+import vtk.vtkPolyDataNormals;
+import vtk.vtkProp;
+import vtk.vtkPropCollection;
+import vtk.vtkProperty;
+import vtk.vtkSphereSource;
+import vtk.vtkTriangle;
+
+public class VTKOCCTool {
+       public static vtkAssembly vtkTestAssembly() {
+               vtkAssembly assemblies = new vtkAssembly();
+               vtkPolyData partGrid = createTestPartGrid();
+               gridToAssembly(assemblies, partGrid);
+               return assemblies;
+       }
+       
+       public static vtkAssembly vtkOCCShapeToAssembly(TopoDS_Shape shape) {
+               double deflection = 0.001;
+
+               if (deflection <= 0.0) {
+                       deflection = 0.0005;
+                       System.out.println("Bad value for deflection. Using: " + deflection);
+               }
+
+               // FIXME : leaks memory!
+               //BRepTools.clean(shape);
+
+               double mass = OCCTTool.getMass(shape);
+
+               if (mass < 1.0e-12) {
+                       System.out.println("Non 3D-shape detected");
+                       System.out.println("The cad import features are currently limited to 3D models.");
+               }
+
+               double length = OCCTTool.getBoundingBoxDiagonal(shape);
+               deflection *= length; // use relative units
+
+               BRepMesh_IncrementalMesh mesh = new BRepMesh_IncrementalMesh(shape,deflection);
+
+               int faceNumber = 0;
+               TopExp_Explorer expFace = new TopExp_Explorer();
+
+               vtkAssembly assemblies = new vtkAssembly();
+               for (expFace.init(shape, TopAbs_ShapeEnum.FACE); expFace.more(); expFace.next()) {
+                       TopoDS_Face face = (TopoDS_Face) expFace.current();
+                       vtkPolyData partGrid = createPartGrid(face);
+                       face.delete();
+                       if (partGrid == null)
+                               continue;
+                       faceNumber++;
+                       //gridToAssembly(assemblies, partGrid, stlSurfaceData, stlEdgeData);
+                       gridToAssembly(assemblies, partGrid);
+                       
+               }
+               expFace.delete();
+               mesh.delete();
+
+               if (faceNumber == 0) {
+                       System.out
+                                       .println("Cad import: error: no surface triangulation was generated.");
+                       return null;
+               }
+
+               return assemblies;
+       }
+       
+       private static void gridToAssembly(vtkAssembly assemblies, vtkPolyData partGrid, vtkAppendPolyData stlSurfaceData, vtkAppendPolyData stlEdgeData) {
+        
+        double featureAngle = 30;
+
+        
+        vtkDataSetMapper partMapper = new vtkDataSetMapper();
+        
+        boolean computeNormals = true;
+        boolean cleanPart = true;
+        boolean mergePoints = false;
+
+        vtkCleanPolyData partCleaner = new vtkCleanPolyData();       
+        if (cleanPart)
+        {
+            partCleaner.SetInputData(partGrid);
+            if(mergePoints) {
+              partCleaner.PointMergingOn();
+            } else {
+              partCleaner.PointMergingOff();
+            }
+        }
+        
+        if (computeNormals)
+        {
+            vtkPolyDataNormals partNormals = new vtkPolyDataNormals();
+         
+            if (cleanPart)
+            {
+                partNormals.SetInputConnection(partCleaner.GetOutputPort());
+            }
+            else partNormals.SetInputData(partGrid);
+                
+            partNormals.SetFeatureAngle(featureAngle); // this do not have to be neccesarily called
+            partMapper.SetInputConnection(partNormals.GetOutputPort());
+            partNormals.Delete();          
+        }
+        else
+        {
+            if (cleanPart) partMapper.SetInputConnection(partCleaner.GetOutputPort()); // metoda 2, ne tak pekne, viz http://www.codeguru.com/cpp/g-m/opengl/article.php/c2681
+            else partMapper.SetInputData(partGrid); // metoda 1, ne tak pekne stinovani, viz: http://www.codeguru.com/cpp/g-m/opengl/article.php/c2681
+        }
+        partMapper.ScalarVisibilityOn();
+        
+        vtkActor partActor = new vtkActor();
+
+        partActor.SetPickable(1);
+        partActor.GetProperty().SetColor(1, 1, 0);
+        partActor.SetMapper(partMapper);
+        
+        // EDGES OF PARTS DETECTION
+        vtkFeatureEdges partEdges = new vtkFeatureEdges();
+        if (cleanPart) partEdges.SetInputConnection(partCleaner.GetOutputPort());
+        else partEdges.SetInputData(partGrid); 
+        partEdges.SetFeatureAngle(featureAngle);  // this do not have to be neccesarily called
+        partEdges.FeatureEdgesOn();
+        partEdges.BoundaryEdgesOn();
+        partEdges.NonManifoldEdgesOn();
+        partEdges.ManifoldEdgesOn();
+
+        vtkDataSetMapper partEdgesMapper = new vtkDataSetMapper();
+        partEdgesMapper.SetInputConnection(partEdges.GetOutputPort());
+        partEdgesMapper.SetResolveCoincidentTopologyToPolygonOffset();
+        partEdgesMapper.ScalarVisibilityOff();
+        
+        vtkActor partEdgesActor = new vtkActor();
+        partEdgesActor.SetPickable(0);
+        partEdgesActor.GetProperty().SetColor(1, 0, 1);
+        partEdgesActor.SetMapper(partEdgesMapper);
+        
+
+        // Add triangles and edges to STL structures:
+        //--------------------------------------------
+        if (cleanPart) stlSurfaceData.AddInputData(partCleaner.GetOutput());
+        else stlSurfaceData.AddInputData(partGrid);
+        stlEdgeData.AddInputData(partEdges.GetOutput());
+                
+        assemblies.AddPart(partActor);
+        assemblies.AddPart(partEdgesActor);        
+        
+        // Clean up:
+        //----------
+        partEdgesActor.Delete();
+        partEdgesMapper.Delete();
+        partEdges.Delete();
+        partActor.Delete();
+        partMapper.Delete();
+        partGrid.Delete();
+        partCleaner.Delete();
+    }
+
+public static void gridToAssembly(vtkAssembly assemblies, vtkPolyData partGrid) {
+    
+    double featureAngle = 30;
+
+    
+    vtkDataSetMapper partMapper = new vtkDataSetMapper();
+    
+    boolean computeNormals = true;
+    boolean cleanPart = false;
+    boolean mergePoints = false;
+
+    vtkCleanPolyData partCleaner = new vtkCleanPolyData();       
+    if (cleanPart)
+    {
+        partCleaner.SetInputData(partGrid);
+        if(mergePoints) {
+          partCleaner.PointMergingOn();
+        } else {
+          partCleaner.PointMergingOff();
+        }
+    }
+    
+    if (computeNormals)
+    {
+        vtkPolyDataNormals partNormals = new vtkPolyDataNormals();
+     
+        if (cleanPart)
+        {
+               vtkAlgorithmOutput out = partCleaner.GetOutputPort();
+            partNormals.SetInputConnection(out);
+            out.Delete();
+        }
+        else partNormals.SetInputData(partGrid);
+            
+        partNormals.SetFeatureAngle(featureAngle); // this do not have to be neccesarily called
+        vtkAlgorithmOutput out = partNormals.GetOutputPort();
+        partMapper.SetInputConnection(out);
+        out.Delete();
+        partNormals.Delete();          
+    }
+    else
+    {
+        if (cleanPart) {
+               vtkAlgorithmOutput out = partCleaner.GetOutputPort();
+               partMapper.SetInputConnection(out); // metoda 2, ne tak pekne, viz http://www.codeguru.com/cpp/g-m/opengl/article.php/c2681
+               out.Delete();
+        }
+        else partMapper.SetInputData(partGrid); // metoda 1, ne tak pekne stinovani, viz: http://www.codeguru.com/cpp/g-m/opengl/article.php/c2681
+    }
+    partMapper.ScalarVisibilityOn();
+    
+    vtkActor partActor = new vtkActor();
+    partActor.SetPickable(1);
+    vtkProperty prop = partActor.GetProperty();
+    prop.SetColor(1, 1, 0);
+    prop.Delete();
+    partActor.SetMapper(partMapper);
+    
+    assemblies.AddPart(partActor);
+    
+    {
+           // EDGES OF PARTS DETECTION
+           vtkFeatureEdges partEdges = new vtkFeatureEdges();
+           if (cleanPart) {
+               vtkAlgorithmOutput out = partCleaner.GetOutputPort();
+               partEdges.SetInputConnection(out);
+               out.Delete();
+           }
+           else partEdges.SetInputData(partGrid); 
+          // partEdges.SetFeatureAngle(featureAngle);  // this do not have to be neccesarily called
+           partEdges.FeatureEdgesOn();
+           partEdges.BoundaryEdgesOn();
+           partEdges.NonManifoldEdgesOn();
+           partEdges.ManifoldEdgesOn();
+       
+           vtkDataSetMapper partEdgesMapper = new vtkDataSetMapper();
+           vtkAlgorithmOutput out = partEdges.GetOutputPort();
+           partEdgesMapper.SetInputConnection(out);
+           out.Delete();
+           partEdgesMapper.SetResolveCoincidentTopologyToPolygonOffset();
+           partEdgesMapper.ScalarVisibilityOff();
+           
+           vtkActor partEdgesActor = new vtkActor();
+          
+           prop = partEdgesActor.GetProperty();
+           prop.SetColor(0, 0, 0);
+           prop.SetLineWidth(2.0);
+           prop.Delete();
+           partEdgesActor.SetMapper(partEdgesMapper);
+           partEdgesActor.PickableOn();  
+           
+           assemblies.AddPart(partEdgesActor);        
+           
+           {
+
+               EdgePointsFilter edgePoints = new EdgePointsFilter();
+               
+                
+               out = partEdges.GetOutputPort();
+                   edgePoints.SetInputConnection(out);
+                   out.Delete();
+                   
+//                 vtkDataSetMapper partEdgePointsMapper = new vtkDataSetMapper();
+//                 out = edgePoints.GetOutputPort();
+//                 partEdgePointsMapper.SetInputConnection(out);
+//                 out.Delete();
+                   
+//                 vtkVertexGlyphFilter glyphFilter = new vtkVertexGlyphFilter();
+//                 out = edgePoints.GetOutputPort();
+//                 glyphFilter.SetInputConnection(out);
+//                 glyphFilter.Update();
+//                 out.Delete();
+//                 
+//                 vtkPolyDataMapper partEdgePointsMapper = new vtkPolyDataMapper();
+//                 out = glyphFilter.GetOutputPort();
+//                 partEdgePointsMapper.SetInputConnection(out);
+//                 out.Delete();
+                   
+                   vtkSphereSource sphereSource = new vtkSphereSource();
+                   vtkGlyph3D glyph3D = new vtkGlyph3D();
+                   out = sphereSource.GetOutputPort();
+                   glyph3D.SetSourceConnection(out);
+                   out.Delete();
+                   
+                   out = edgePoints.GetOutputPort();
+                   glyph3D.SetInputConnection(out);
+                   out.Delete();
+                   
+                   //glyph3D.ScalingOff();
+                   glyph3D.SetScaleFactor(0.03);
+                   
+                   glyph3D.Update();
+                   
+                   vtkPolyDataMapper partEdgePointsMapper = new vtkPolyDataMapper();
+                   out = glyph3D.GetOutputPort();
+                   partEdgePointsMapper.SetInputConnection(out);
+                   out.Delete();
+                   
+                   vtkActor edgePointsActor = new vtkActor();
+                  
+                   prop = edgePointsActor.GetProperty();
+                   prop.SetColor(0, 0, 1);
+                   //prop.SetPointSize(10.0);
+                   //prop.SetRepresentationToPoints();
+                   prop.Delete();
+                   edgePointsActor.SetMapper(partEdgePointsMapper);
+                  
+                   edgePointsActor.PickableOn();
+                   assemblies.AddPart(edgePointsActor);
+                   
+                   
+                   edgePointsActor.Delete();
+                   partEdgePointsMapper.Delete();
+                  // edgePoints.Delete();
+           }
+           // Clean up:
+           //----------
+           partEdgesActor.Delete();
+           partEdgesMapper.Delete();
+           partEdges.Delete();
+    }
+   
+    partActor.Delete();
+    partMapper.Delete();
+    partGrid.Delete();
+    partCleaner.Delete();
+}
+       
+       
+       
+       public static vtkPolyData createPartGrid ( TopoDS_Face face)
+    {
+        TopLoc_Location Location = new TopLoc_Location();
+        
+        Poly_Triangulation triangulation = BRep_Tool.triangulation(face, Location);
+
+        if(triangulation == null) {
+               Location.delete();
+               System.out.println("Encountered empty triangulation after face");
+               return null;
+        }
+                
+        boolean reverse = face.orientation()==TopAbs_Orientation.REVERSED;
+
+        int[]triangles = triangulation.triangles();
+        double[]nodes = triangulation.nodes();
+
+        int nofTriangles = triangulation.nbTriangles();
+        int nofNodes = triangulation.nbNodes();
+        
+        triangulation.delete();
+
+        if(nofTriangles < 1) {
+          System.out.println("No triangles for mesh on face");
+          Location.delete();
+          return null;
+        }
+
+        if(nofNodes < 1) {
+            System.out.println("No nodes for mesh on face:");
+            Location.delete();
+            return null;
+        }
+        //System.out.println("v " + nofNodes + " t " +nofTriangles);
+        vtkPolyData partGrid = new vtkPolyData();
+        partGrid.Allocate(nofTriangles, nofTriangles);
+
+        vtkTriangle triangle = new vtkTriangle();
+        vtkIdList list = triangle.GetPointIds();
+        for(int i = 0; i < nofTriangles; i++) 
+        {
+          int n0, n1, n2;
+          if (!reverse) {
+                 n0 = triangles[3 * i]; 
+                 n1 = triangles[3 * i + 1]; 
+                 n2 = triangles[3 * i + 2];
+          } else {
+                 n0 = triangles[3 * i + 2]; 
+                 n1 = triangles[3 * i + 1]; 
+                 n2 = triangles[3 * i];
+          }
+          
+          list.SetId(0, n0);
+          list.SetId(1, n1);
+          list.SetId(2, n2);
+          partGrid.InsertNextCell(triangle.GetCellType(), list);
+          
+        }
+        list.Delete();
+        triangle.Delete();   
+        
+        GP_Trsf transformation = Location.transformation();
+        Location.delete();
+
+        double d_mat[] = new double[16];
+        double d_p[] = new double[3];
+        transformation.getValues(d_mat);
+        Matrix4d mat = new Matrix4d(d_mat);
+        
+        vtkPoints partPoints = new vtkPoints();
+        
+        for(int i = 0; i < nofNodes; i++) {     
+          // FIXME: GP_Trsf.transform(double[]) leaks memory
+               
+          //double xyz[] = new double[]{nodes[3 * i], nodes[3 * i + 1], nodes[3 * i + 2]};          
+          //transformation.transforms(xyz);
+          //partPoints.InsertPoint(i, xyz);
+               Point3d p = new Point3d(nodes[3 * i], nodes[3 * i + 1], nodes[3 * i + 2]);
+               mat.transform(p);
+               d_p[0] = p.x;
+               d_p[1] = p.y;
+               d_p[2] = p.z;
+               partPoints.InsertPoint(i, d_p);
+        }
+        
+        transformation.delete();
+        
+        partGrid.SetPoints(partPoints);
+        partPoints.Delete();
+       
+        return partGrid;
+    }
+       
+       
+       
+       public static vtkPolyData createPartGrid ( List<Double> meshPoints, List<Integer> meshTriangles)
+    {
+       
+                
+      
+
+        
+        int nofTriangles = meshTriangles.size() / 3;
+        int nofNodes = meshPoints.size() /3;
+        
+      
+        if(nofTriangles < 1) {
+          System.out.println("No triangles for mesh on face");
+          return null;
+        }
+
+        if(nofNodes < 1) {
+            System.out.println("No nodes for mesh on face:");
+            return null;
+        }
+        //System.out.println("v " + nofNodes + " t " +nofTriangles);
+        vtkPolyData partGrid = new vtkPolyData();
+        partGrid.Allocate(nofTriangles, nofTriangles);
+
+        vtkTriangle triangle = new vtkTriangle();
+        vtkIdList list = triangle.GetPointIds();
+        for(int i = 0; i < nofTriangles; i++) 
+        {
+          int n0, n1, n2;          
+          n0 = meshTriangles.get(3 * i); 
+          n1 = meshTriangles.get(3 * i + 1);
+          n2 = meshTriangles.get(3 * i + 2); 
+
+         
+          list.SetId(0, n0);
+          list.SetId(1, n1);
+          list.SetId(2, n2);
+          partGrid.InsertNextCell(triangle.GetCellType(), list);
+          
+        }
+        list.Delete();
+        triangle.Delete();   
+        
+
+
+        double d_p[] = new double[3];
+
+        
+        vtkPoints partPoints = new vtkPoints();
+        
+        for(int i = 0; i < nofNodes; i++) {     
+
+               d_p[0] = meshPoints.get(3*i);
+               d_p[1] = meshPoints.get(3*i+1);
+               d_p[2] = meshPoints.get(3*i+2);
+               partPoints.InsertPoint(i, d_p);
+        }
+        
+        partGrid.SetPoints(partPoints);
+        partPoints.Delete();
+       
+        return partGrid;
+    }
+       
+       private static vtkPolyData createTestPartGrid ()
+    {
+               int size = 64;
+               
+        double[] nodes = new double[(size+1)*(size+1)*3];
+        int[] triangles = new int[3 * size * size * 2];
+
+        double es = 1.0;
+        for (int i = 0; i <= size; i++) {
+               for (int j = 0; j <= size; j++) {
+                       int index = j * size + i;
+                       index *= 3;
+                       double x = (double)i * es;
+                       double y = (Math.sin((double)i/(double)size)  + Math.sin((double)j/(double)size)) * es;
+                       double z = (double)j * es;
+                       nodes[index] = x;
+                       nodes[index+1] = y;
+                       nodes[index+2] = z;
+               }
+        }
+        
+        for (int i = 0; i < size; i++) {
+               for (int j = 0; j < size; j++) {
+                       int index = j * size + i;
+                       index *= 3;
+                       index *= 2;
+                       triangles[index  ] = (j     * (size+1) + i  );
+                       triangles[index+1] = (j     * (size+1) + i+1);
+                       triangles[index+2] = ((j+1) * (size+1) + i  );
+                       triangles[index+3] = ((j+1) * (size+1) + i  );
+                       triangles[index+4] = ((j  ) * (size+1) + i +1 );
+                       triangles[index+5] = ((j+1) * (size+1) + i +1 );
+               }
+        }
+
+        int nofTriangles = triangles.length / 3;
+        int nofNodes = nodes.length / 3;
+
+        if(nofTriangles < 1) {
+         
+          return null;
+        }
+
+        if(nofNodes < 1) {
+           
+            return null;
+        }
+        //System.out.println("v " + nofNodes + " t " +nofTriangles);
+        vtkPolyData partGrid = new vtkPolyData();
+        partGrid.Allocate(nofTriangles, nofTriangles);
+
+        vtkTriangle triangle = new vtkTriangle();
+        vtkIdList list = triangle.GetPointIds();
+        for(int i = 0; i < nofTriangles; i++) 
+        {
+          int n0, n1, n2;          
+          n0 = triangles[3 * i]; n1 = triangles[3 * i + 1]; n2 = triangles[3 * i + 2]; // triangles(i).Get(n0, n1, n2);
+
+//          if(face.orientation() != TopAbs_Orientation.FORWARD) {
+//              int tmp = n2; n2 = n1; n1 = tmp;
+//          }
+         
+          list.SetId(0, n0);
+          list.SetId(1, n1);
+          list.SetId(2, n2);
+          partGrid.InsertNextCell(triangle.GetCellType(), list);
+          
+        }
+        list.Delete();
+        triangle.Delete();      
+
+        vtkPoints partPoints = new vtkPoints();
+        for(int i = 0; i < nofNodes; i++) {       
+            double xyz[] = new double[]{nodes[3 * i], nodes[3 * i + 1], nodes[3 * i + 2]};          
+            partPoints.InsertPoint(i, xyz);
+        }
+        
+        partGrid.SetPoints(partPoints);
+        
+        partPoints.Delete();
+
+        return partGrid;
+    }
+       
+       public static void test() {
+               TopoDS_Shape shape = null;
+               //shape = OccTriangulator.makeCylinder(new double[]{0,0,0}, new double[]{0,1,0}, 1, 1);
+               for (int t = 0; t < 5000; t++) {
+                       //shape = OccTriangulator.makeCylinder(new double[]{0,0,0}, new double[]{0,1,0}, 1, 1);
+                       int test = 2;
+                       if (test == 0) {
+                               vtkAssembly ass = VTKOCCTool.vtkOCCShapeToAssembly(shape);
+                               vtkPropCollection col;
+                       col = ass.GetParts();
+                       for (int i = 0; i < col.GetNumberOfItems(); i++)
+                       {
+                           vtkProp prop = (vtkProp) col.GetItemAsObject(i);
+                           //System.out.println(prop.Print());
+                           prop.Delete();
+                       }
+                       col.Delete();
+                       ass.Delete();
+                       }
+                       else if (test == 1) {
+                               //BRepTools.clean(shape);
+                               
+                               
+                               vtkAssembly ass = new vtkAssembly();
+                               
+                               double vol = OCCTTool.getBoundingBoxDiagonal(shape);
+                               double d = 0.001 * vol;
+                               BRepMesh_IncrementalMesh mesh = new BRepMesh_IncrementalMesh(shape,d);
+                               TopExp_Explorer expFace = new TopExp_Explorer();
+                               for (expFace.init(shape, TopAbs_ShapeEnum.FACE); expFace.more(); expFace.next()) {
+                                       TopoDS_Face face = (TopoDS_Face) expFace.current();
+                                       {
+//                                             TopLoc_Location Location = new TopLoc_Location();
+//                                             Poly_Triangulation triangulation = BRep_Tool.triangulation(face, Location);
+//                                             if (triangulation != null) {
+//                                                     
+//                                                     int[]triangles = triangulation.triangles();
+//                                             double[]nodes = triangulation.nodes();
+//                                             int nofTriangles = triangulation.nbTriangles();
+//                                             int nofNodes = triangulation.nbNodes();
+//                                             
+//                                             triangulation.delete();
+//                                             
+//                                             GP_Trsf transformation = Location.transformation();
+//                                             double d_mat[] = new double[16];
+//                                             transformation.getValues(d_mat);
+//                                             Matrix4d mat = new Matrix4d(d_mat);
+//                                             for(int i = 0; i < nofNodes; i++) {       
+//                                                 //double xyz[] = new double[]{nodes[3 * i], nodes[3 * i + 1], nodes[3 * i + 2]};          
+//                                                 Point3d p = new Point3d(nodes[3 * i], nodes[3 * i + 1], nodes[3 * i + 2]);
+//                                                     //transformation.transforms(xyz);
+//                                                 mat.transform(p);
+//                                             }
+//                                             transformation.delete();
+//                                             }
+//                                             
+//                                             Location.delete();
+                                               vtkPolyData data = VTKOCCTool.createPartGrid(face);
+                                               VTKOCCTool.gridToAssembly(ass, data);
+                                               //data.Delete();
+                                       }
+                                       face.delete();
+                               }
+                               expFace.delete();
+                               mesh.delete();
+                               
+                               vtkPropCollection col;
+                       col = ass.GetParts();
+                       for (int i = 0; i < col.GetNumberOfItems(); i++)
+                       {
+                           vtkProp prop = (vtkProp) col.GetItemAsObject(i);
+                           //System.out.println(prop.Print());
+                           prop.Delete();
+                       }
+                       col.Delete();
+                       ass.Delete();
+                       } else if (test == 2) {
+                               double[] pointStruct = new double[]{0,0,0}, dirStruct = new double[]{0,1,0};
+                               double radius = 1.0;
+                               double height = 1.0;
+                               
+                               double[] axe = new double[6];
+                                
+                       System.arraycopy(pointStruct, 0, axe, 0, 3);
+                       System.arraycopy(dirStruct, 0, axe, 3, 3);
+                       org.jcae.opencascade.jni.BRepPrimAPI_MakeCylinder cyl = new org.jcae.opencascade.jni.BRepPrimAPI_MakeCylinder(axe, radius, height, 2 * Math.PI);
+                       org.jcae.opencascade.jni.TopoDS_Shape tds = cyl.shape();
+                       cyl.delete();
+                       
+                       double vol = OCCTTool.getBoundingBoxDiagonal(tds);
+                               double d = 0.001 * vol;
+                               BRepMesh_IncrementalMesh mesh = new BRepMesh_IncrementalMesh(tds,d);
+//                             TopExp_Explorer expFace = new TopExp_Explorer();
+//                             for (expFace.init(tds, TopAbs_ShapeEnum.FACE); expFace.more(); expFace.next()) {
+//                                     TopoDS_Face face = (TopoDS_Face) expFace.current();
+//                                     {
+//                                             
+//                                     }
+//                                     face.delete();
+//                             }
+                               mesh.delete();
+                               
+                       tds.delete();
+                       }
+                       //shape.delete();
+               System.out.println(t);
+               }
+               //shape.delete();
+       }
+}