解析OCC几何体,并在OSG中渲染显示

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();

		//1几何体//
		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();
		osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
		osg::ref_ptr<osg::UIntArray> arrayIndexs2 = new osg::UIntArray;//创建三角形顶点索引数据
		osg::ref_ptr<osg::DrawElementsUInt> arrayIndexs = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);

		//2法线///
		osg::ref_ptr<osg::Geometry> lineGeom = new osg::Geometry();
		osg::ref_ptr<osg::Vec3Array> vertices2 = new osg::Vec3Array();
		osg::ref_ptr<osg::Vec4Array> colors2 = new osg::Vec4Array;

		//3关键点//
		osg::ref_ptr<osg::Geometry> keyPointGeom = new osg::Geometry();
		osg::ref_ptr<osg::Vec3Array> vertices3 = new osg::Vec3Array();
		osg::ref_ptr<osg::Vec4Array> colors3 = new osg::Vec4Array;

		BRepMesh_IncrementalMesh(aShape, 1);
		//BRepMesh::Mesh(aShape, 3);//6.8.0后删除了
		cout << std::endl;
		gp_Pnt vertex1;
		gp_Pnt vertex2;
		gp_Pnt vertex3;

		Standard_Integer nVertexIndex1 = 0;
		Standard_Integer nVertexIndex2 = 0;
		Standard_Integer nVertexIndex3 = 0;

		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);
			if (triFace.IsNull())
			{
				continue;
			}

			Standard_Boolean hasNormal = triFace->HasNormals();
			Standard_Boolean hasuvNormal = triFace->HasUVNodes();
			Standard_Integer l = triFace->Nodes().Length();
			Standard_Integer nTriangles = triFace->NbTriangles();

			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++)
			{
				vertex1.SetCoord(0.0, 0.0, 0.0);
				vertex2.SetCoord(0.0, 0.0, 0.0);
				vertex3.SetCoord(0.0, 0.0, 0.0);

				nVertexIndex1 = 0;
				nVertexIndex2 = 0;
				nVertexIndex3 = 0;

				Poly_Triangle aTriangle = triangles.Value(i);
				aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3);
				cout << "\tnVertexIndex1 = " << nVertexIndex1 << "\tnVertexIndex2 = " << nVertexIndex2 << "\tnVertexIndex3 = " << nVertexIndex3 << std::endl;

				//顶点
				//vertex1 = nodes.Value(nVertexIndex1).Transformed(loc.Transformation());
				//vertex1 = nodes.Value(nVertexIndex2).Transformed(loc.Transformation());
				//vertex1 = nodes.Value(nVertexIndex3).Transformed(loc.Transformation());
				vertex1 = nodes.Value(nVertexIndex1);
				//vertex1.SetCoord(vertex1.X() + 10.0, vertex1.Y() + 10.0, vertex1.Z() + 10.0);
				vertex2 = nodes.Value(nVertexIndex2);
				//vertex2.SetCoord(vertex2.X() + 10.0, vertex2.Y() + 10.0, vertex2.Z() + 10.0);
				vertex3 = nodes.Value(nVertexIndex3);
				//vertex3.SetCoord(vertex3.X() + 10.0, vertex3.Y() + 10.0, vertex3.Z() + 10.0);

				cout << "******" << "\tvertex1 = " << vertex1.X() << "," << vertex1.Y() << "," << vertex1.Z()
					<< "\tvertex2 = " << vertex2.X() << "," << vertex2.Y() << "," << vertex2.Z()
					<< "\tvertex3 = " << vertex3.X() << "," << vertex3.Y() << "," << vertex3.Z() << std::endl;
				cout << std::endl;
				//gp_Dir dir(0.0,1.0,0.0);
				//gp_Dir dir = triFace->Normal(i);

				//1几何体//
				{
					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()));

					colors->push_back(osg::Vec4(1.0, 1.0, 0.0, 1.0));

					//arrayIndexs->push_back(nVertexIndex1);
					//arrayIndexs->push_back(nVertexIndex2);
					//arrayIndexs->push_back(nVertexIndex3);
				}

				///2法线//
				double ratio = 0.1;
				{
					gp_XYZ vector12(vertex2.XYZ() - vertex1.XYZ());
					gp_XYZ vector13(vertex3.XYZ() - vertex1.XYZ());
					gp_XYZ normal123 = vector13.Crossed(vector12);
					Standard_Real rModulus = normal123.Modulus();
					if (rModulus > gp::Resolution())
					{
						normal123.Normalize();
					}
					else {
						normal123.SetCoord(0., 0., 0.);
					}

					if (aFace.Orientation() != TopAbs_REVERSED)
					{
						normal123.Reverse();
					}


					//第1个顶点
					{
						gp_XYZ vector12(vertex2.XYZ() - vertex1.XYZ());
						gp_XYZ vector13(vertex3.XYZ() - vertex1.XYZ());
						gp_XYZ normal10 = vector13.Crossed(vector12);
						Standard_Real rModulus = normal10.Modulus();
						if (rModulus > gp::Resolution())
						{
							normal10.Normalize();
						}
						else {
							normal10.SetCoord(0., 0., 0.);
						}

						if (aFace.Orientation() != TopAbs_REVERSED)
						{
							normal10.Reverse();
						}

						//normals->push_back(osg::Vec3(dir.X(), dir.Y(), dir.Z()));
						normals->push_back(osg::Vec3(normal123.X(), normal123.Y(), normal123.Z()));

						vertices2->push_back(osg::Vec3(vertex1.X(), vertex1.Y(), vertex1.Z()));
						vertices2->push_back(osg::Vec3(vertex1.X(), vertex1.Y(), vertex1.Z()) + osg::Vec3(ratio * normal10.X(), ratio * normal10.Y(), ratio * normal10.Z()));
						colors2->push_back(osg::Vec4(1.0, 0.0, 0.0, 1.0));
						colors2->push_back(osg::Vec4(1.0, 0.0, 0.0, 1.0));
					}
					//第2个顶点
					{
						gp_XYZ vector21(vertex1.XYZ() - vertex2.XYZ());
						gp_XYZ vector23(vertex3.XYZ() - vertex2.XYZ());
						gp_XYZ normal20 = vector21.Crossed(vector23);
						Standard_Real rModulus = normal20.Modulus();
						if (rModulus > gp::Resolution())
						{
							normal20.Normalize();
						}
						else {
							normal20.SetCoord(0., 0., 0.);
						}

						if (aFace.Orientation() != TopAbs_REVERSED)
						{
							normal20.Reverse();
						}

						//normals->push_back(osg::Vec3(dir.X(), dir.Y(), dir.Z()));
						normals->push_back(osg::Vec3(normal123.X(), normal123.Y(), normal123.Z()));

						vertices2->push_back(osg::Vec3(vertex2.X(), vertex2.Y(), vertex2.Z()));
						vertices2->push_back(osg::Vec3(vertex2.X(), vertex2.Y(), vertex2.Z()) + osg::Vec3(ratio * normal20.X(), ratio * normal20.Y(), ratio * normal20.Z()));
						colors2->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0));
						colors2->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0));
					}
					//第3个顶点
					{
						gp_XYZ vector31(vertex1.XYZ() - vertex3.XYZ());
						gp_XYZ vector32(vertex2.XYZ() - vertex3.XYZ());
						gp_XYZ normal30 = vector32.Crossed(vector31);
						Standard_Real rModulus = normal30.Modulus();
						if (rModulus > gp::Resolution())
						{
							normal30.Normalize();
						}
						else {
							normal30.SetCoord(0., 0., 0.);
						}

						if (aFace.Orientation() != TopAbs_REVERSED)
						{
							normal30.Reverse();
						}

						//normals->push_back(osg::Vec3(dir.X(), dir.Y(), dir.Z()));
						normals->push_back(osg::Vec3(normal123.X(), normal123.Y(), normal123.Z()));

						vertices2->push_back(osg::Vec3(vertex3.X(), vertex3.Y(), vertex3.Z()));
						vertices2->push_back(osg::Vec3(vertex3.X(), vertex3.Y(), vertex3.Z()) + osg::Vec3(ratio * normal30.X(), ratio * normal30.Y(), ratio * normal30.Z()));
						colors2->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));
						colors2->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));
					}
				}

				3关键点//
				{
					vertices3->push_back(osg::Vec3(vertex1.X(), vertex1.Y(), vertex1.Z()));
					vertices3->push_back(osg::Vec3(vertex2.X(), vertex2.Y(), vertex2.Z()));
					vertices3->push_back(osg::Vec3(vertex3.X(), vertex3.Y(), vertex3.Z()));

					colors3->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0));
			}
		}
	}

		//1三角面片(几何体)//
		if (vertices->size() > 0)
		{
			//triGeom->setUseDisplayList(false);
			triGeom->setVertexArray(vertices.get());
			triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices->size()));
			//triGeom->addPrimitiveSet(arrayIndexs);
			std::cout << vertices->size() << "\t" << arrayIndexs->size() << std::endl;
#if 1
			triGeom->setNormalArray(normals);
			triGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
#else
			//自动生成法线,效果不好
			//NodePrimitiveSetNormalVisitor mv;
			//triGeom->accept(mv);
#endif
			triGeom->setColorArray(colors, osg::Array::BIND_OVERALL);

			//triGeom->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
			//triGeom->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
			//triGeom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);

			geode->addDrawable(triGeom);
		}


		//2法线//
		if (vertices2->size())
		{
			lineGeom->setVertexArray(vertices2.get());
			lineGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vertices2->size()));

			lineGeom->setColorArray(colors2, osg::Array::BIND_PER_VERTEX);
			lineGeom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);

			geode->addDrawable(lineGeom);
		}

		//3点//
		if (vertices3->size() > 0)
		{
			keyPointGeom->setVertexArray(vertices3.get());
			keyPointGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, vertices3->size()));
			keyPointGeom->setColorArray(colors3, osg::Array::BIND_OVERALL);
			osg::ref_ptr<osg::Point> pointSize = new osg::Point;
			pointSize->setSize(7.5);
			keyPointGeom->getOrCreateStateSet()->setAttribute(pointSize);
			keyPointGeom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);

			geode->addDrawable(keyPointGeom);

			//osg::ref_ptr<osgFX::Outline> outline = new osgFX::Outline;
			//outline->setWidth(8);
			//outline->setColor(osg::Vec4(1, 0, 0, 1));
			//outline->addChild(triGeom.get());
			//root->addChild(outline.get());

			//osg::PolygonMode* pm = new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, /*osg::PolygonMode::FILL | */osg::PolygonMode::LINE);
			//triGeom->getOrCreateStateSet()->setAttributeAndModes(pm, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
			//triGeom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
		}

		Use SmoothingVisitor to find the vertex average normals.
		//osgUtil::SmoothingVisitor sv;
		//sv.apply(*geode);

		root->addChild(geode);

		osg::MatrixTransform* mtAxes = new osg::MatrixTransform;
		mtAxes->setMatrix(osg::Matrix::scale(2.0, 2.0, 2.0));
		mtAxes->addChild(osgDB::readNodeFile("axes.osgt"));
		root->addChild(mtAxes);

		return root.release();
}
}

 

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
要加载并显示 OCC 模型,您需要使用 OpenSceneGraph(OSG)和 OpenCASCADE(OCC),并将它们集成在一起。以下是加载 OCC 模型并在 OSG 显示的基本步骤: 1. 安装 OSGOCC 并将其设置为您的项目依赖项。 2. 使用 OCC API 加载模型并将其转换为 OSG 几何体。 ```cpp #include <OpenCASCADE/TopoDS.hxx> #include <OpenCASCADE/BRepTools.hxx> #include <OpenCASCADE/IGESControl_Reader.hxx> #include <osg/Geometry> #include <osg/Geode> osg::ref_ptr<osg::Node> loadOCCModel(const std::string& fileName) { // Step 1: Load the model using OCC API TopoDS_Shape shape; IGESControl_Reader reader; reader.ReadFile(fileName.c_str()); reader.TransferRoots(); shape = reader.OneShape(); // Step 2: Convert the OCC geometry to OSG geometry osg::ref_ptr<osg::Geode> geode = new osg::Geode; BRepTools::Clean(shape); BRepTools::Update(shape); TopExp_Explorer exp(shape, TopAbs_FACE); while (exp.More()) { TopoDS_Face face = TopoDS::Face(exp.Current()); Handle(Geom_Surface) surface = BRep_Tool::Surface(face); if (!surface.IsNull()) { // Create OSG geometry from OCC surface osg::ref_ptr<osg::Geometry> geom = new osg::Geometry; // Add vertices to the geometry // ... // Add primitives to the geometry // ... geode->addDrawable(geom); } exp.Next(); } return geode; } ``` 3. 将 OSG 几何体添加到场景图显示。 ```cpp #include <osgViewer/Viewer> int main(int argc, char** argv) { // Create the viewer osgViewer::Viewer viewer; // Load the model and add it to the scene osg::ref_ptr<osg::Node> model = loadOCCModel("model.igs"); viewer.setSceneData(model); // Start the viewer return viewer.run(); } ``` 这只是一个基本示例,您可能需要根据您的要求进行适当的修改。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小胖七少爷

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

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

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

打赏作者

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

抵扣说明:

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

余额充值