Opencascade与OSG结合

手头有个三维视景的项目,需要用到三维曲面绘制和计算,忽然发现了Opencascade,经过3天的奋战,终于把项目运行出来。为以后打下基础。

把代码留下。


#include "../Commen/Common.h"

#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.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::Mesh(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); 


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(); 
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
OpenCASCADE是一个C++开发的开源几何计算引擎,用于CAD、CAM和CAE领域的几何建模和处理。而OpenSceneGraph(OSG)则是一个开源的3D图形渲染引擎,用于创建实时的3D图形应用程序。 要使用OpenCASCADEOSG模块来读取STEP文件,首先需要将STEP文件转换为OGS可以理解的格式。可以使用OpenCASCADE的IGESControl或者STEPControl模块将STEP文件转换为OpenCASCADE的BREP或者IGES格式。然后,可以使用OSGosgDB模块来加载和渲染这些BREP或者IGES格式的文件。 具体步骤如下: 1. 使用OpenCASCADE的STEPControl模块读取和解析STEP文件,将其转换为BREP格式。例如可以使用以下代码: ```cpp STEPControl_Reader reader; IFSelect_ReturnStatus status = reader.ReadFile("example.step"); if (status == IFSelect_RetDone) { Standard_Integer NbRoots = reader.NbRootsForTransfer(); for (Standard_Integer n = 1; n <= NbRoots; n++) { reader.TransferRoot(n); } TopoDS_Shape shape = reader.OneShape(); // 将shape保存为BREP格式 BRepTools::Write(shape, "example.brep"); } else { // 文件读取失败 } ``` 2. 使用OSGosgDB模块加载和渲染这个BREP格式的文件。例如可以使用以下代码: ```cpp osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("example.brep"); if (node.valid()) { // 创建一个场景图并添加这个节点 osg::ref_ptr<osg::Group> root = new osg::Group; root->addChild(node); // 创建一个Viewer并设置场景图 osgViewer::Viewer viewer; viewer.setSceneData(root); // 运行Viewer viewer.run(); } else { // 文件加载失败 } ``` 通过以上步骤,就可以使用OpenCASCADEOSG模块成功读取和渲染STEP文件。当然,这只是一个简单的示例,实际应用可能需要更多的处理和配置才能达到所需的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马鸣风萧萧222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值