解析OCC(TopoDS_Edge、Geom_Surface、TopoDS_Shape),生成OSG节点

16 篇文章 7 订阅
11 篇文章 6 订阅
//解析TopoDS_Edge,生成OSG节点
osg::Node* BuildPolylineMesh(const TopoDS_Edge& edge, double deflection = 0.1)
{
	osg::ref_ptr<osg::Geode> geode = new osg::Geode();
	osg::ref_ptr<osg::Geometry> linesGeom = new osg::Geometry();
	osg::ref_ptr<osg::Vec3Array> pointsVec = new osg::Vec3Array();

	TopLoc_Location location;

	//BRepMesh::Mesh(edge, deflection);
	BRepMesh_IncrementalMesh(edge, deflection);
	Handle_Poly_Polygon3D polyline = BRep_Tool::Polygon3D(edge, location);

	for (int i = 1; i < polyline->NbNodes(); i++)
	{
		gp_Pnt point = polyline->Nodes().Value(i);

		pointsVec->push_back(osg::Vec3(point.X(), point.Y(), point.Z()));
	}

	// Set the color of the polyline.
	osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
	colors->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 0.0f));
	linesGeom->setColorArray(colors.get());
	linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL);

	// Set vertex array.
	linesGeom->setVertexArray(pointsVec);
	linesGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, 0, pointsVec->size()));

	geode->addDrawable(linesGeom.get());

	return geode.release();
}
//解析Geom_Surface,生成OSG节点
osg::Node* buildSurfaceMesh(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();
}
//解析TopoDS_Shape,生成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, 10);
	//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.5;
			{
				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);
	return root.release();
}

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小胖七少爷

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

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

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

打赏作者

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

抵扣说明:

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

余额充值