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

osg::Node* BuildShapeMesh(const TopoDS_Shape& aShape)
{
	{
		osg::ref_ptr root = new osg::Group();
		osg::ref_ptr geode = new osg::Geode();

		//1几何体//
		osg::ref_ptr triGeom = new osg::Geometry();
		osg::ref_ptr vertices = new osg::Vec3Array();
		osg::ref_ptr normals = new osg::Vec3Array();
		osg::ref_ptr colors = new osg::Vec4Array;
		osg::ref_ptr arrayIndexs2 = new osg::UIntArray;//创建三角形顶点索引数据
		osg::ref_ptr arrayIndexs = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);

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

		//3关键点//
		osg::ref_ptr keyPointGeom = new osg::Geometry();
		osg::ref_ptr vertices3 = new osg::Vec3Array();
		osg::ref_ptr 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 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 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();
}
}

 

你可能感兴趣的:(OpenCASCADE,OpenSceneGraph)