Open Cascade 转化为OpenSceneGraph中的Mesh
#include <osgDB/ReadFile> #include <osgViewer/Viewer> #include <osgGA/StateSetManipulator> #include <osgViewer/ViewerEventHandlers> #include <osg/Vec3> #include <osg/Array> #include <osg/Geode> #include <osg/Group> #include <osg/MatrixTransform> #pragma comment(lib, "osgd.lib") #pragma comment(lib, "osgDBd.lib") #pragma comment(lib, "osgGAd.lib") #pragma comment(lib, "osgViewerd.lib") // OpenCascade #define WNT #include <TColgp_Array2OfPnt.hxx> #include <TColStd_HArray1OfInteger.hxx> #include <TColGeom_Array2OfBezierSurface.hxx> #include <GeomConvert_CompBezierSurfacesToBSplineSurface.hxx> #include <Geom_Surface.hxx> #include <Geom_BezierSurface.hxx> #include <Geom_BSplineSurface.hxx> #include <Geom_ConicalSurface.hxx> #include <Geom_CylindricalSurface.hxx> #include <Geom_Plane.hxx> #include <Geom_ToroidalSurface.hxx> #include <Geom_SphericalSurface.hxx> // Open Cascade library. #include <gp_Pnt.hxx> #include <gp_Pln.hxx> #include <BRep_Tool.hxx> #include <TopoDS.hxx> #include <TopoDS_Edge.hxx> #include <TopoDS_Wire.hxx> #include <TopoDS_Face.hxx> #include <BRepBuilderAPI_MakeEdge.hxx> #include <BRepBuilderAPI_MakeWire.hxx> #include <BRepBuilderAPI_MakeFace.hxx> #include <BRepPrimAPI_MakeBox.hxx> #include <BRepPrimAPI_MakeCone.hxx> #include <BRepPrimAPI_MakeCylinder.hxx> #include <BRepPrimApI_MakeSphere.hxx> #include <BRepAlgoAPI_Cut.hxx> #include <BRepAlgoAPI_Common.hxx> #include <BRepMesh_IncrementalMesh.hxx> #include <TopExp_Explorer.hxx> #include <Poly_Triangulation.hxx> #include <TShort_Array1OfShortReal.hxx> #pragma comment(lib, "TKernel.lib") #pragma comment(lib, "TKMath.lib") #pragma comment(lib, "TKBRep.lib") #pragma comment(lib, "TKPrim.lib") #pragma comment(lib, "TKMesh.lib") #pragma comment(lib, "TKTopAlgo.lib") #pragma comment(lib, "TKernel.lib") #pragma comment(lib, "TKMath.lib") #pragma comment(lib, "TKG3d.lib") #pragma comment(lib, "TKGeomBase.lib") #pragma comment(lib, "TkBO.lib") // Approximation Delta. const double APPROXIMATION_DELTA = 0.1; /** * @breif Build geometry surface. */ osg::Node* buildSurface(const Geom_Surface& surface) { osg::ref_ptr<osg::Geode> geode = new osg::Geode(); gp_Pnt point; Standard_Real uFirst = 0.0; Standard_Real vFirst = 0.0; Standard_Real uLast = 0.0; Standard_Real vLast = 0.0; surface.Bounds(uFirst, uLast, vFirst, vLast); Precision::IsNegativeInfinite(uFirst) ? uFirst = -1.0 : uFirst; Precision::IsInfinite(uLast) ? uLast = 1.0 : uLast; Precision::IsNegativeInfinite(vFirst) ? vFirst = -1.0 : vFirst; Precision::IsInfinite(vLast) ? vLast = 1.0 : vLast; // Approximation in v direction. for(Standard_Real u = uFirst; u <= uLast; u += APPROXIMATION_DELTA) { osg::ref_ptr<osg::Geometry> linesGeom = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> pointsVec = new osg::Vec3Array(); for (Standard_Real v = vFirst; v <= vLast; v += APPROXIMATION_DELTA) { point = surface.Value(u, v); pointsVec->push_back(osg::Vec3(point.X(), point.Y(), point.Z())); } // Set the colors. osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array; colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 0.0f)); linesGeom->setColorArray(colors.get()); linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL); // Set the normal in the same way of color. osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array; normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); linesGeom->setNormalArray(normals.get()); linesGeom->setNormalBinding(osg::Geometry::BIND_OVERALL); // Set vertex array. linesGeom->setVertexArray(pointsVec); linesGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, pointsVec->size())); geode->addDrawable(linesGeom.get()); } // Approximation in u direction. // osg::ref_ptr<osg::Geometry> linesGeom = new osg::Geometry(); //osg::ref_ptr<osg::Vec3Array> pointsVec = new osg::Vec3Array(); for (Standard_Real v = vFirst; v <= vLast; v += APPROXIMATION_DELTA) { osg::ref_ptr<osg::Geometry> linesGeom = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> pointsVec = new osg::Vec3Array(); for (Standard_Real u = vFirst; u <= uLast; u += APPROXIMATION_DELTA) { point = surface.Value(u, v); pointsVec->push_back(osg::Vec3(point.X(), point.Y(), point.Z())); } // Set the colors. osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array; colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 0.0f)); linesGeom->setColorArray(colors.get()); linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL); // Set the normal in the same way of color. osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array; normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); linesGeom->setNormalArray(normals.get()); linesGeom->setNormalBinding(osg::Geometry::BIND_OVERALL); // Set vertex array. linesGeom->setVertexArray(pointsVec); linesGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, pointsVec->size())); geode->addDrawable(linesGeom.get()); } return geode.release(); } osg::Node* BuildShapeMesh(const TopoDS_Shape& aShape) { osg::ref_ptr<osg::Group> root = new osg::Group(); osg::ref_ptr<osg::Geode> geode = new osg::Geode(); osg::ref_ptr<osg::Geometry> triGeom = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array(); osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array(); BRepMesh_IncrementalMesh(aShape, 3); TopExp_Explorer faceExplorer; for (faceExplorer.Init(aShape, TopAbs_FACE); faceExplorer.More(); faceExplorer.Next()) { TopLoc_Location loc; TopoDS_Face aFace = TopoDS::Face(faceExplorer.Current()); Handle_Poly_Triangulation triFace = BRep_Tool::Triangulation(aFace, loc); Standard_Boolean hasNormal = triFace->HasNormals(); Standard_Boolean hasuvNormal = triFace->HasUVNodes(); Standard_Integer l = triFace->Nodes().Length(); Standard_Integer nTriangles = triFace->NbTriangles(); gp_Pnt vertex1; gp_Pnt vertex2; gp_Pnt vertex3; Standard_Integer nVertexIndex1 = 0; Standard_Integer nVertexIndex2 = 0; Standard_Integer nVertexIndex3 = 0; TColgp_Array1OfPnt nodes(1, triFace->NbNodes()); Poly_Array1OfTriangle triangles(1, triFace->NbTriangles()); nodes = triFace->Nodes(); triangles = triFace->Triangles(); for (Standard_Integer i = 1; i <= nTriangles; i++) { Poly_Triangle aTriangle = triangles.Value(i); aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3); vertex1 = nodes.Value(nVertexIndex1); vertex2 = nodes.Value(nVertexIndex2); vertex3 = nodes.Value(nVertexIndex3); gp_XYZ vector12(vertex2.XYZ() - vertex1.XYZ()); gp_XYZ vector13(vertex3.XYZ() - vertex1.XYZ()); gp_XYZ normal = vector12.Crossed(vector13); Standard_Real rModulus = normal.Modulus(); if (rModulus > gp::Resolution()) { normal.Normalize(); } else { normal.SetCoord(0., 0., 0.); } if (aFace.Orientation()!= TopAbs_FORWARD) { normal.Reverse(); } vertices->push_back(osg::Vec3(vertex1.X(), vertex1.Y(), vertex1.Z())); vertices->push_back(osg::Vec3(vertex2.X(), vertex2.Y(), vertex2.Z())); vertices->push_back(osg::Vec3(vertex3.X(), vertex3.Y(), vertex3.Z())); normals->push_back(osg::Vec3(normal.X(), normal.Y(), normal.Z())); } } triGeom->setVertexArray(vertices.get()); triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices->size())); triGeom->setNormalArray(normals); triGeom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET); geode->addDrawable(triGeom); root->addChild(geode); return root.release(); } /* @breif Test geometry surfaces of OpenCascade. 138 */ osg::Node* buildScene(void) { osg::ref_ptr<osg::Group> root = new osg::Group(); // Test Plane. Geom_Plane plane(gp::XOY()); Geom_Plane plane2(gp::YOZ()); root->addChild(buildSurface(plane)); root->addChild(buildSurface(plane2)); // Test Bezier Surface and B-Spline Surface. TColgp_Array2OfPnt array1(1,3,1,3); TColgp_Array2OfPnt array2(1,3,1,3); TColgp_Array2OfPnt array3(1,3,1,3); TColgp_Array2OfPnt array4(1,3,1,3); array1.SetValue(1,1,gp_Pnt(1,1,1)); array1.SetValue(1,2,gp_Pnt(2,1,2)); array1.SetValue(1,3,gp_Pnt(3,1,1)); array1.SetValue(2,1,gp_Pnt(1,2,1)); array1.SetValue(2,2,gp_Pnt(2,2,2)); array1.SetValue(2,3,gp_Pnt(3,2,0)); array1.SetValue(3,1,gp_Pnt(1,3,2)); array1.SetValue(3,2,gp_Pnt(2,3,1)); array1.SetValue(3,3,gp_Pnt(3,3,0)); array2.SetValue(1,1,gp_Pnt(3,1,1)); array2.SetValue(1,2,gp_Pnt(4,1,1)); array2.SetValue(1,3,gp_Pnt(5,1,2)); array2.SetValue(2,1,gp_Pnt(3,2,0)); array2.SetValue(2,2,gp_Pnt(4,2,1)); array2.SetValue(2,3,gp_Pnt(5,2,2)); array2.SetValue(3,1,gp_Pnt(3,3,0)); array2.SetValue(3,2,gp_Pnt(4,3,0)); array2.SetValue(3,3,gp_Pnt(5,3,1)); array3.SetValue(1,1,gp_Pnt(1,3,2)); array3.SetValue(1,2,gp_Pnt(2,3,1)); array3.SetValue(1,3,gp_Pnt(3,3,0)); array3.SetValue(2,1,gp_Pnt(1,4,1)); array3.SetValue(2,2,gp_Pnt(2,4,0)); array3.SetValue(2,3,gp_Pnt(3,4,1)); array3.SetValue(3,1,gp_Pnt(1,5,1)); array3.SetValue(3,2,gp_Pnt(2,5,1)); array3.SetValue(3,3,gp_Pnt(3,5,2)); array4.SetValue(1,1,gp_Pnt(3,3,0)); array4.SetValue(1,2,gp_Pnt(4,3,0)); array4.SetValue(1,3,gp_Pnt(5,3,1)); array4.SetValue(2,1,gp_Pnt(3,4,1)); array4.SetValue(2,2,gp_Pnt(4,4,1)); array4.SetValue(2,3,gp_Pnt(5,4,1)); array4.SetValue(3,1,gp_Pnt(3,5,2)); array4.SetValue(3,2,gp_Pnt(4,5,2)); array4.SetValue(3,3,gp_Pnt(5,5,1)); Geom_BezierSurface BZ1(array1); Geom_BezierSurface BZ2(array2); Geom_BezierSurface BZ3(array3); Geom_BezierSurface BZ4(array4); root->addChild(buildSurface(BZ1)); root->addChild(buildSurface(BZ2)); root->addChild(buildSurface(BZ3)); root->addChild(buildSurface(BZ4)); Handle_Geom_BezierSurface BS1 = new Geom_BezierSurface(array1); Handle_Geom_BezierSurface BS2 = new Geom_BezierSurface(array2); Handle_Geom_BezierSurface BS3 = new Geom_BezierSurface(array3); Handle_Geom_BezierSurface BS4 = new Geom_BezierSurface(array4); TColGeom_Array2OfBezierSurface bezierarray(1,2,1,2); bezierarray.SetValue(1,1,BS1); bezierarray.SetValue(1,2,BS2); bezierarray.SetValue(2,1,BS3); bezierarray.SetValue(2,2,BS4); GeomConvert_CompBezierSurfacesToBSplineSurface BB (bezierarray); if (BB.IsDone()) { Geom_BSplineSurface BSPLSURF( BB.Poles()->Array2(), BB.UKnots()->Array1(), BB.VKnots()->Array1(), BB.UMultiplicities()->Array1(), BB.VMultiplicities()->Array1(), BB.UDegree(), BB.VDegree() ); BSPLSURF.Translate(gp_Vec(0,0,2)); root->addChild(buildSurface(BSPLSURF)); } // Test Spherical Surface. Geom_SphericalSurface sphericalSurface(gp::XOY(), 1.0); sphericalSurface.Translate(gp_Vec(2.5, 0.0, 0.0)); root->addChild(buildSurface(sphericalSurface)); // Test Conical Surface. Geom_ConicalSurface conicalSurface(gp::XOY(), M_PI/8, 1.0); conicalSurface.Translate(gp_Vec(5.0, 0.0, 0.0)); root->addChild(buildSurface(conicalSurface)); // Test Cylindrical Surface. Geom_CylindricalSurface cylindricalSurface(gp::XOY(), 1.0); cylindricalSurface.Translate(gp_Vec(8.0, 0.0, 0.0)); root->addChild(buildSurface(cylindricalSurface)); // Test Toroidal Surface. Geom_ToroidalSurface toroidalSurface(gp::XOY(), 1.0, 0.2); toroidalSurface.Translate(gp_Vec(11.0, 0.0, 0.0)); root->addChild(buildSurface(toroidalSurface)); return root.release(); } /* int main(int argc, char* argv[]) { osgViewer::Viewer myViewer; myViewer.setSceneData(buildScene()); myViewer.addEventHandler(new osgGA::StateSetManipulator(myViewer.getCamera()->getOrCreateStateSet())); myViewer.addEventHandler(new osgViewer::StatsHandler); myViewer.addEventHandler(new osgViewer::WindowSizeHandler); return myViewer.run(); }*/ int main(int argc, char* argv[]) { osgViewer::Viewer myViewer; osg::ref_ptr<osg::Group> root = new osg::Group(); TopoDS_Shape theBox = BRepPrimAPI_MakeBox(500,40,40); TopoDS_Shape theSphere = BRepPrimAPI_MakeSphere(gp_Pnt(100,20,20),80); TopoDS_Shape ShapeCut = BRepAlgoAPI_Common(theSphere,theBox); root->addChild(BuildShapeMesh(ShapeCut)); myViewer.setSceneData(root); myViewer.addEventHandler(new osgGA::StateSetManipulator(myViewer.getCamera()->getOrCreateStateSet())); myViewer.addEventHandler(new osgViewer::StatsHandler); myViewer.addEventHandler(new osgViewer::WindowSizeHandler); return myViewer.run(); }