对于我们读取显示出来的step格式的三维模型文件,它大致包含一下基本属性信息:

基本属性包括质心坐标、面积体积大小、模型的顶点数,线段数,边框数,面数,闭合的壳和实体数等。

下面还有将模型分解为mesh(网格数据)后的最大最小公差,节点和三角面片的个数以及最大偏移量等信息。最后还能读取到模型的边界BOX。

将模型分解为单个实体solid后,进而可以读取模型的装配信息,如下,xyz轴的平移量和旋转量。

 代码的实现:

首先在主视图view 的  .h文件中进行函数接口定义:

public:
	CString getCentre(TopoDS_Shape S);
	double getArea(TopoDS_Shape S);
	double getVolume(TopoDS_Shape S);
	long getNbVertice(TopoDS_Shape S);
	long getNbEdges(TopoDS_Shape S);
	long getNbWires(TopoDS_Shape S);
	long getNbFaces(TopoDS_Shape S);
	long getNbShells(TopoDS_Shape S);
	long getNbSolids(TopoDS_Shape S);
	long getNbCompounds(TopoDS_Shape S);
	CString getMaxtol(TopoDS_Shape S);
	CString getMintol(TopoDS_Shape S);
	long getNbNodes(TopoDS_Shape S);
	long getNbTriangles(TopoDS_Shape S);
	double getDeflection(TopoDS_Shape S);
	CString getMinbndBox(TopoDS_Shape S);
	CString getMaxbndBox(TopoDS_Shape S);
	CString getRangebndBox(TopoDS_Shape S);

定义上我们所需要实现读取模型相关属性的函数,接下来进行函数实现:

1.质心坐标的读取

CString COCCMDI32View::getCentre(TopoDS_Shape S)
{
	//读取质心
	GProp_GProps CentreProps;
	BRepGProp::VolumeProperties(S, CentreProps);
	Centre centre;
	centre.x = CentreProps.CentreOfMass().X();
	centre.y = CentreProps.CentreOfMass().Y();
	centre.z = CentreProps.CentreOfMass().Z();
	

	//double类型转为CString
	CString centreX;
	centreX.Format(_T("%.9e"), centre.x);
	CString centreY;
	centreY.Format(_T("%.9e"), centre.y);
	CString centreZ;
	centreZ.Format(_T("%.9e"), centre.z);
	CString strCentre = _T("x=") + centreX + "mm" + "  ,y=" + centreY + "mm" + "  ,z=" + centreZ + "mm";
	return strCentre;
}

2.面积体积的读取

double COCCMDI32View::getArea(TopoDS_Shape S)
{
	GProp_GProps surfaceProps;
	BRepGProp::SurfaceProperties(S, surfaceProps);
	double a = surfaceProps.Mass();
	CString surface;
	surface.Format(_T("%lf"), a);
	CString strSurface = surface + _T("mm²");
	return a;
}

double COCCMDI32View::getVolume(TopoDS_Shape S)
{
	//计算体积
	GProp_GProps volumeProps;
	BRepGProp::VolumeProperties(S, volumeProps);
	double currentVolume = volumeProps.Mass();
	
	CString volume;
	volume.Format(_T("%lf"), currentVolume);
	CString strVolume = volume + _T("mm³");
	return currentVolume;
}

3.模型的顶点数,线段数,边框数,面数,闭合的壳和实体数等

long COCCMDI32View::getNbVertice(TopoDS_Shape S)
{
	//计算vertices数

	int num_vertices = 0;
	for (TopExp_Explorer vertices_exp(S, TopAbs_ShapeEnum::TopAbs_VERTEX); vertices_exp.More(); vertices_exp.Next()) {
		//TopoDS_Shape subshape = vertices_exp.Current();	
		num_vertices++;
	}
	long ver = num_vertices;
	return ver;
}

long COCCMDI32View::getNbEdges(TopoDS_Shape S)
{
	//计算edge数
	int num_edges = 0;
	for (TopExp_Explorer edges_exp(S, TopAbs_ShapeEnum::TopAbs_EDGE); edges_exp.More(); edges_exp.Next()) {
		num_edges++;
	}
	long edge = num_edges;
	return edge;
}

long COCCMDI32View::getNbWires(TopoDS_Shape S)
{
	//计算wire数
	int num_wires = 0;
	for (TopExp_Explorer wire_exp(S, TopAbs_ShapeEnum::TopAbs_WIRE); wire_exp.More(); wire_exp.Next()) {
		num_wires++;
	}
	long wire = num_wires;
	return wire;
}

long COCCMDI32View::getNbFaces(TopoDS_Shape S)
{
	int num_faces = 0;
	for (TopExp_Explorer face_exp(S, TopAbs_ShapeEnum::TopAbs_FACE); face_exp.More(); face_exp.Next()) {
		num_faces++;
	}
	long face = num_faces;
	return face;
}

long COCCMDI32View::getNbShells(TopoDS_Shape S)
{
	//计算shell数
	int num_shells = 0;
	for (TopExp_Explorer shell_exp(S, TopAbs_ShapeEnum::TopAbs_SHELL); shell_exp.More(); shell_exp.Next()) {
		num_shells++;
	}
	long shell = num_shells;
	return shell;
}

long COCCMDI32View::getNbSolids(TopoDS_Shape S)
{
	//计算solid数
	int num_solids = 0;
	for (TopExp_Explorer solid_exp(S, TopAbs_ShapeEnum::TopAbs_SOLID); solid_exp.More(); solid_exp.Next()) {
		num_solids++;
	}
	long solid = num_solids;
	return solid;
}

long COCCMDI32View::getNbCompounds(TopoDS_Shape S)
{
	//计算compound数
	int num_compounds = 0;
	for (TopExp_Explorer compound_exp(S, TopAbs_ShapeEnum::TopAbs_COMPOUND); compound_exp.More(); compound_exp.Next()) {
		num_compounds++;
	}
	long compound = num_compounds;
	return compound;
}

4.模型分解为mesh(网格数据)后的最大最小公差,节点和三角面片的个数以及最大偏移量等信息

CString COCCMDI32View::getMaxtol(TopoDS_Shape S)
{
	double maxTol = -std::numeric_limits<double>::max();
	BRepAdaptor_Curve curve;
	BRepMesh_IncrementalMesh aMesh(S, 0.1);
	aMesh.Perform(); //网格化
	CString maxtol;
	for (TopExp_Explorer face_exp(S, TopAbs_ShapeEnum::TopAbs_FACE); face_exp.More(); face_exp.Next())
	{
		TopoDS_Face aface = TopoDS::Face(face_exp.Current());
		for (TopExp_Explorer explorer2(aface, TopAbs_EDGE); explorer2.More(); explorer2.Next())
		{
			TopoDS_Edge aedge = TopoDS::Edge(explorer2.Current());
			curve.Initialize(aedge, aface);
			// 获取最大偏移量值
			double edgeOffset = curve.Tolerance();
			if (edgeOffset > maxTol)
			{
				maxTol = edgeOffset;
			}
		}
	}
	//将最小公差转化成科学计数法以CString输出
	maxtol.Format(_T("%.10e"), maxTol);
	return maxtol;
}

CString COCCMDI32View::getMintol(TopoDS_Shape S)
{
	double minTol = std::numeric_limits<double>::max();
	BRepAdaptor_Curve curve;
	BRepMesh_IncrementalMesh aMesh(S, 0.1);
	aMesh.Perform(); //网格化
	CString mintol;
	for (TopExp_Explorer face_exp(S, TopAbs_ShapeEnum::TopAbs_FACE); face_exp.More(); face_exp.Next()) {
		TopoDS_Face aface = TopoDS::Face(face_exp.Current());
		for (TopExp_Explorer explorer2(aface, TopAbs_EDGE); explorer2.More(); explorer2.Next())
		{
			TopoDS_Edge aedge = TopoDS::Edge(explorer2.Current());
			curve.Initialize(aedge, aface);
			// 获取最大偏移量值
			double edgeOffset = curve.Tolerance();
			if (edgeOffset < minTol)
			{
				minTol = edgeOffset;
			}
		}
	}
	//将最小公差转化成科学计数法以CString输出
	mintol.Format(_T("%.10e"), minTol);
	return mintol;
}

long COCCMDI32View::getNbNodes(TopoDS_Shape S)
{
	BRepMesh_IncrementalMesh aMesh(S, 0.1);
	aMesh.Perform(); //网格化
	int num_nodes = 0; //初始化mesh的节点数
	for (TopExp_Explorer face_exp(S, TopAbs_ShapeEnum::TopAbs_FACE); face_exp.More(); face_exp.Next())
	{
		TopoDS_Face aface = TopoDS::Face(face_exp.Current());
		TopLoc_Location Loc;
		Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation(aface, Loc);
		if (triangulation.IsNull()) {
			continue;
		}
		num_nodes += triangulation->NbNodes();
	}
	long node = num_nodes;
	return node;
}

long COCCMDI32View::getNbTriangles(TopoDS_Shape S)
{
	BRepMesh_IncrementalMesh aMesh(S, 0.1);
	aMesh.Perform(); //网格化
	int num_triangles = 0; //初始化mesh的节点数
	for (TopExp_Explorer face_exp(S, TopAbs_ShapeEnum::TopAbs_FACE); face_exp.More(); face_exp.Next())
	{
		TopoDS_Face aface = TopoDS::Face(face_exp.Current());
		TopLoc_Location Loc;
		Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation(aface, Loc);
		if (triangulation.IsNull()) {
			continue;
		}
		num_triangles += triangulation->NbTriangles();
	}
	long triangle = num_triangles;
	return triangle;
}

double COCCMDI32View::getDeflection(TopoDS_Shape S)
{
	BRepMesh_IncrementalMesh aMesh(S, 0.1);
	aMesh.Perform(); //网格化
	double maxDeflection = -std::numeric_limits<double>::max();
	for (TopExp_Explorer face_exp(S, TopAbs_ShapeEnum::TopAbs_FACE); face_exp.More(); face_exp.Next())
	{
		TopoDS_Face aface = TopoDS::Face(face_exp.Current());
		TopLoc_Location Loc;
		Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation(aface, Loc);
		if (triangulation.IsNull()) {
			continue;
		}
		for (int i = 1; i <= triangulation->NbNodes(); i++) {
			gp_Pnt node = triangulation->Node(i);
			double deflection = triangulation->Deflection();
			if (deflection > maxDeflection)
			{
				maxDeflection = deflection;
			}
		}
	}
	double defMax = maxDeflection;
	return defMax;
}

5.模型的边界BOX

CString COCCMDI32View::getMinbndBox(TopoDS_Shape S)
{
	//计算边界盒子
	Bnd_Box boundingBox;
	BRepBndLib::Add(S, boundingBox);
	Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
	boundingBox.Get(xMin, yMin, zMin, xMax, yMax, zMax);
	Bndbox myBndbox;
	myBndbox.box_xmin = xMin;
	myBndbox.box_ymin = yMin;
	myBndbox.box_zmin = zMin;


	//将坐标转成字符串
	CString bndbox_Xmin, bndbox_Ymin, bndbox_Zmin;
	bndbox_Xmin.Format(_T("%lf"), myBndbox.box_xmin);
	bndbox_Ymin.Format(_T("%lf"), myBndbox.box_ymin);
	bndbox_Zmin.Format(_T("%lf"), myBndbox.box_zmin);
	CString strBndbox_min = _T("x=") + bndbox_Xmin + "mm" + "  ,y=" + bndbox_Ymin + "mm" + "  ,z=" + bndbox_Zmin + "mm";
	return strBndbox_min;
}

CString COCCMDI32View::getMaxbndBox(TopoDS_Shape S)
{
	//
	Bnd_Box boundingBox;
	BRepBndLib::Add(S, boundingBox);
	Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
	boundingBox.Get(xMin, yMin, zMin, xMax, yMax, zMax);
	Bndbox myBndbox;
	
	myBndbox.box_xmax = xMax;
	myBndbox.box_ymax = yMax;
	myBndbox.box_zmax = zMax;

	//将坐标转成字符串
	CString bndbox_Xmax, bndbox_Ymax, bndbox_Zmax;
	bndbox_Xmax.Format(_T("%lf"), myBndbox.box_xmax);
	bndbox_Ymax.Format(_T("%lf"), myBndbox.box_ymax);
	bndbox_Zmax.Format(_T("%lf"), myBndbox.box_zmax);
	CString strBndbox_max = _T("x=") + bndbox_Xmax + "mm" + "  ,y=" + bndbox_Ymax + "mm" + "  ,z=" + bndbox_Zmax + "mm";
	return strBndbox_max;
}

CString COCCMDI32View::getRangebndBox(TopoDS_Shape S)
{
	//计算边界盒子
	Bnd_Box boundingBox;
	BRepBndLib::Add(S, boundingBox);
	Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
	boundingBox.Get(xMin, yMin, zMin, xMax, yMax, zMax);
	Bndbox myBndbox;
	myBndbox.box_range_x = xMax - xMin;
	myBndbox.box_range_y = yMax - yMin;
	myBndbox.box_range_z = zMax - zMin;


	//将坐标转成字符串
	CString bndbox_Xrange, bndbox_Yrange, bndbox_Zrange;
	
	bndbox_Xrange.Format(_T("%lf"), myBndbox.box_range_x);
	bndbox_Yrange.Format(_T("%lf"), myBndbox.box_range_y);
	bndbox_Zrange.Format(_T("%lf"), myBndbox.box_range_z);
	CString strBndbox_range = _T("x:") + bndbox_Xrange + "mm" + "   y:" + bndbox_Yrange + "mm" + "   z:" + bndbox_Zrange + "mm";
	return strBndbox_range;
}

下面是头文件中定义的一些结构体:

protected:
	
struct Centre
	{
		double x;
		double y;
		double z;
	};
	struct Bndbox
	{
		double box_xmin;
		double box_ymin;
		double box_zmin;
		double box_xmax;
		double box_ymax;
		double box_zmax;
		double box_range_x;
		double box_range_y;
		double box_range_z;
	};

以上就是读取相关属性的函数实现,具体怎么调用这些函数以及如何传入到属性面板中,我会在以后的文章中进行编写。 还有就是将模型激活分解之后每个实体装配信息的读取也会在后续的文章中阐述。 下面是一个最终实现的效果图:

 欢迎研究讨论。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐