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();
}
原文地址:https://www.cnblogs.com/2018shawn/p/11156440.html