X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.opencascade.vtk%2Fsrc%2Forg%2Fsimantics%2Fopencascade%2Fvtk%2FVTKOCCTool.java;h=8f8c7b1523ea589358106b8c1a9b815a7ce55a47;hb=refs%2Fchanges%2F78%2F2878%2F1;hp=187c7853e628d8a3edc69b99279cf5a183376462;hpb=87b3241ec277ba3d8e414b26186a032c9cdcaeed;p=simantics%2F3d.git diff --git a/org.simantics.opencascade.vtk/src/org/simantics/opencascade/vtk/VTKOCCTool.java b/org.simantics.opencascade.vtk/src/org/simantics/opencascade/vtk/VTKOCCTool.java index 187c7853..8f8c7b15 100644 --- a/org.simantics.opencascade.vtk/src/org/simantics/opencascade/vtk/VTKOCCTool.java +++ b/org.simantics.opencascade.vtk/src/org/simantics/opencascade/vtk/VTKOCCTool.java @@ -1,709 +1,720 @@ -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.SetInput(partGrid); - if(mergePoints) { - partCleaner.PointMergingOn(); - } else { - partCleaner.PointMergingOff(); - } - } - - if (computeNormals) - { - vtkPolyDataNormals partNormals = new vtkPolyDataNormals(); - - if (cleanPart) - { - partNormals.SetInputConnection(partCleaner.GetOutputPort()); - } - else partNormals.SetInput(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.SetInput(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.SetInput(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.AddInput(partCleaner.GetOutput()); - else stlSurfaceData.AddInput(partGrid); - stlEdgeData.AddInput(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.SetInput(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.SetInput(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.SetInput(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.SetInput(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 meshPoints, List 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(); - } -} +/******************************************************************************* + * 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 meshPoints, List 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(); + } +}