2021-08-10.shp

该代码实现从.shp文件中读取头信息和形状数据,包括点、线和多边形,存储为自定义类的对象。同时,它将这些数据写入新的.shp文件,并将相关信息插入到MySQL数据库中。主要涉及数据结构如Header、Point、Shape和PolygonShape类,以及数据库操作如连接、查询和插入。

创建存储文件头的头文件 header.h
头中定义header类

class Header {
public:
	int FileCode;
	int Unused;
	int FileLength;
	int Version;
	int ShapeType;
	double Xmin;
	double Ymin;
	double Xmax;
	double Ymax;
	double Zmin;
	double Zmax;
	double Mmin;
	double Mmax;
};

创建存储格式的头文件 shape.h
point->line->polygon
先要创建一个point类

class Point { //点
public:
	double X;
	double Y;
	Point() {}
	void set_Point(double x, double y)
	{
		X = x;
		Y = y;

	}
};

然后根据polygon的属性 创建Shape 类

class Shape
{
public:
	int ShapeType;
	int RecordNumber;
	int ContentLength;
	double  Box[4];//边界
	int NumParts;
	int NumPoints;
	int* Parts = new int[NumParts];
	//以上是记录头,下面是记录的Points
	std::vector<Point> Points;//存储所有点的位置
	std::vector<PointM> PointMs;
	double M_Range[2];
	double* M_Array = new double[NumPoints];
};

然后创建Polygon 类继承Shape, 属性已经有了在类中只考虑向属性存储

class PolygonShape :public Shape {//多边
public:
	PolygonShape() {}
	void set_ShapeType(int a) {
		ShapeType = a;
	}
	void set_NumParts(int a) {
		NumParts = a;
	}
	void set_NumPoints(int a) {
		NumPoints = a;
	}
	void set_Box(double* a) {
		memcpy(Box, a, 4 * sizeof(double));
	}

	void set_Parts(int* a) {
		memcpy(this->Parts, a, NumParts * sizeof(int));
	}
	void set_Points(Point a) {
		Points.push_back(a);
	}
	void set_RecordNumber(int a) {
		RecordNumber = a;
	}
	void set_ContentLength(int a) {
		ContentLength = a;
	}
	void vectorclose() {
		Points.clear();
	}
};

需要向数据库中写入 创建 database.h 头文件

#include <iostream>
#include <string>
#include <mysql.h>
#include <string>
using namespace std;
MYSQL mysql; //实例MYSQL
MYSQL_FIELD* fd;//字段列数组 
char filed[32][100];//存字段名二维数组 可存32个字段
MYSQL_RES* res;//这个结构代表返回行的一个查询结果集合 
MYSQL_ROW column;//标识数据行的列 
char sql[150];//sql语句 
//连接数据库
bool ConnectDatabase() { 
		mysql_init(&mysql);//初始化mysql
		const char host[] = "localhost";
		const char username[] = "root";
		const char password[] = "7029";
		const char databasename[] = "shp";
		const int port = 3306;
		if (!(mysql_real_connect(&mysql, host, username, password, databasename, port, NULL, 0)))
		{cout << "error connect \n";
		 return false;
		}
		else {cout << "connect successful\n";
			return true;}
	    }
	//释放数据库的连接
	void freeconnect() {
		mysql_free_result(res); //释放一个结果集合使用的内存 
		mysql_close(&mysql);//关闭服务器连接 
	}
	//查询

bool QueryDatabase() {
		mysql_query(&mysql, "set names gbk");
	    //执行SQL语句  返回0 查询成功,返回1查询失败  
		if (mysql_query(&mysql, "select * from  header")) 
		{   printf("Query failed (%s)\n", mysql_error(&mysql));
			return false;}
		else
		{    printf("query success\n");
			}
	   //MYSQL_RES* res 存储行的查询结果
		res = mysql_store_result(&mysql);
	   //打印数据行数  
		printf("number of dataline returned: %d\n", mysql_affected_rows(&mysql));
		for (int i = 0; fd = mysql_fetch_field(res); i++)  //从结果中取得每一个字段存入fd中
		   {strcpy(field[i], fd->name);}
		int j = mysql_num_fields(res); // 获取列数  
		for (int i = 0; i < j; i++)  //打印字段  
				{printf("%10s\n", field[i]);}
		while (column = mysql_fetch_row(res))
			{for (int i = 0; i < j; i++)
				printf("%10s\t", column[i]);
				printf("\n");}
		return true;
		}
//创建表涉及到3个表 头文件,记录头,记录
bool create_table() {
		string str0 = "create table header_data(FileCode int , FileLength int ,Version int ,ShapeType int );";
	    string str1 = "create table record_header_data(RecordNumber int primary key , ContentLength int ,ShapeType int ,NumParts int ,NumPoints int);"; //可将RecordNumber作主键标识
		string str2 = "create table point_record_data(X double ,Y double ,RecordNumber int );";//可将RecordNumber作为此表的外键标识
		mysql_query(&mysql, str0.c_str());
		mysql_query(&mysql, str1.c_str());
		mysql_query(&mysql, str2.c_str());
		return 1;
}
//向头文件表插入数据
bool insert_header_data(int FileCode, int FileLength, int Version, int ShapeType, double xmin, double ymin, double xmax, double ymax ) {
		string str;
		str = "insert into header_data values(";
		str += to_string(FileCode);
		str += ",";
		str += to_string(FileLength);
		str += ",";
		str += to_string(Version);
		str += ",";
		str += to_string(ShapeType);
		str += ",";
		str += to_string(xmin);
		str += ",";
		str += to_string(ymin);
		str += ",";
		str += to_string(xmax);
		str += ",";
		str += to_string(ymax);
		str += ");";
		cout << str;
		if (mysql_query(&mysql, str.c_str()))//执行sql语句 
		{	cout << "insert error";
			return false;}
		else {	cout << "insert  successful";
		    	return true;
		    	}
	}
//向记录头表插入数据
bool insert_recordheader_data(int RecordNumber, int ContentLength, int ShapeType, int NumParts,int NumPoints ) {
		string str;
		str = "insert into record_header_data values(";
		str += to_string(RecordNumber);
		str += ",";
		str += to_string(ContentLength);
		str += ",";
		str += to_string(ShapeType);
		str += ",";
		str += to_string(NumParts);
		str += ",";
		str += to_string(NumPoints);
		str += ");";
		cout << str;
		if (mysql_query(&mysql, str.c_str()))//执行sql语句 
		{	cout << "insert error";
			return false;}
		else {	cout << "insert  successful";
			return true;}
	}
//向记录表插入数据
bool insert_pointrecord_data(double x,double y ,int record ) {
		string str;
		str = "insert into point_record_data values(";
		str += to_string(x);
		str += ",";
		str += to_string(y);
		str += ",";
		str += to_string(record);
		str += ");";
		cout << str;
		if (mysql_query(&mysql, str.c_str()))//执行sql语句 
		{   cout << "insert error\n";
		    return false;}
		else {
			cout << "insert  successful\n";
			return true;
		}
	}

然后主函数include 头文件 对.shp进行读取和写入

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "shape.h"
#include "header.h"
#include"database.h"
using namespace std;
PolygonShape abc;//实例PolygonShape
Header header;//实例 header
std::vector<PolygonShape> polygon;//创建存储polygon的vector容器
//BT函数用来地址大小端的转换
template<class T>
T BT(T m)
{
	//union联合体内所有的数据公用一个内存
	union n_
	{
		T n;
		char mem[sizeof(T)];
	};
	n_ big, smal;
	big.n = m;
	for (int i = 0; i < sizeof(T); i++)
	{
		smal.mem[i] = big.mem[sizeof(T) - i - 1];//低位和高位转换
	}
	return smal.n;
}
//定义一个读取文件头的函数
void ReadFileHeard(FILE * ShpFile_fp) {
	// 读取坐标文件头的内容开始
	int Unused;
	fread(&header.FileCode, sizeof(int), 1, ShpFile_fp);
	header.FileCode = BT(header.FileCode);//FileCode为大端
	printf("FileCode=%d\n", header.FileCode);
	for (int i = 0;i < 5;i++)//根据格式 有五个空的int
		fread(&Unused, sizeof(int), 1, ShpFile_fp);
	//5个过后读取文件长度	
	fread(&header.FileLength, sizeof(int), 1, ShpFile_fp);
	header.FileLength = BT(header.FileLength);
	printf("FileLength=%d\n", header.FileLength);
	fread(&header.Version, sizeof(int), 1, ShpFile_fp);//读取Version
	printf("Version=%d\n", header.Version);
	fread(&header.ShapeType, sizeof(int), 1, ShpFile_fp);//读取ShapeType
	printf("ShapeType=%d\n", header.ShapeType);
	//文件头格式依次读取
	fread(&header.Xmin, sizeof(double), 1, ShpFile_fp);
	fread(&header.Ymin, sizeof(double), 1, ShpFile_fp);
	fread(&header.Xmax, sizeof(double), 1, ShpFile_fp);
	fread(&header.Ymax, sizeof(double), 1, ShpFile_fp);
	fread(&header.Zmin, sizeof(double), 1, ShpFile_fp);
	fread(&header.Zmax, sizeof(double), 1, ShpFile_fp);
	fread(&header.Mmin, sizeof(double), 1, ShpFile_fp);
	fread(&header.Mmax, sizeof(double), 1, ShpFile_fp);
	//打印
	printf("Xmin=%lf\n", header.Xmin);
	printf("Ymin=%lf\n", header.Ymin);
	printf("Xmax=%lf\n", header.Xmax);
	printf("Ymax=%lf\n", header.Ymax);
	printf("Zmin=%lf\n", header.Zmin);
	printf("Zmin=%lf\n", header.Zmax);
	printf("Mmax=%lf\n", header.Mmin);
	printf("Mmax=%lf\n", header.Mmax);
}
//定义一个读取记录的函数
void  OnReadPolygonShp(FILE* ShpFile)
{	Point point;//先定义一个 Point类型的实例用于保存点
	int i, j;
	int RecordNumber;
	int ContentLength;
	int shapeType;
	double Box[4];
	int NumParts;
	int NumPoints;
	int *Parts;
	while ((fread(&RecordNumber, sizeof(int), 1, ShpFile) != 0))
	{	RecordNumber = BT(RecordNumber);//RecordNumber为大端需要BT转换
		abc.set_RecordNumber(RecordNumber);//存入实例中
		fread(&ContentLength, sizeof(int), 1, ShpFile);//按序读取
		ContentLength = BT(ContentLength);
		abc.set_ContentLength(ContentLength);
		fread(&shapeType, sizeof(int), 1, ShpFile);
		abc.set_ShapeType(shapeType);
		for (i = 0;i < 4;i++)
		{fread(Box + i, sizeof(double), 1, ShpFile);//范围
		}
		abc.set_Box(Box);
		fread(&NumParts, sizeof(int), 1, ShpFile);
		abc.set_NumParts(NumParts);
		Parts = new int[abc.NumParts];
		fread(&NumPoints, sizeof(int), 1, ShpFile);
		abc.set_NumPoints(NumPoints);
		for (i = 0;i < abc.NumParts;i++)//根据Part的个数记录
		{fread(&Parts[i], sizeof(int), 1, ShpFile);//部分的 开始点的索引
		}
		abc.set_Parts(Parts);
		int pointNum;//用来存储计算点个数
		for (i = 0;i < NumParts;i++)
		{   if (i != NumParts - 1)//如果不是倒数第二个
			pointNum = Parts[i + 1] - Parts[i];//用下一个Parts的地址 减去上一个地址 得出的就是点的地址个数
			else
				pointNum = NumPoints - Parts[i];
			double PointsX;
			double PointsY;
			for (j = 0;j < pointNum;j++)
			{	fread(&PointsX, sizeof(double), 1, ShpFile);
				fread(&PointsY, sizeof(double), 1, ShpFile);
				point.set_Point(PointsX, PointsY);//point属性赋值
				abc.set_Points(point);//对polygon属性赋值
			}
		}
		//一端段记录读取结束将添加到polygon容器中
			polygon.push_back(abc);
		//对polygon属性中的PO
			abc.vectorclose();
			}
}
//读取的值写入txt文本
void write(string filepath) {
	ofstream file;
	file.open(filepath, ios::out);
	file << "FileCode" ;
	file <<std::to_string(header.FileCode);//转换成字符串写入
	file<<"\n";
	file << "FileLength:";
	file << std::to_string(header.FileLength);
	file << "\n";
	file << "Version:";
	file << std::to_string(header.Version);
	file << "\n";
	file << "ShapeType:";
	file << std::to_string(header.ShapeType);
	file << "\n";
	file << "Xmin:";
	file << std::to_string(header.Xmin);
	file << "\n";
	file << "Ymin:";
	file << std::to_string(header.Ymin);
	file << "\n";
	file << "Xmax:";
	file << std::to_string(header.Xmax);
	file << "\n";
	file << "Ymax:";
	file << std::to_string(header.Ymax);
	file << "\n";
	file << "Zmin:";
	file << std::to_string(header.Zmin);
	file << "\n";
	file << "Zmax:";
	file << std::to_string(header.Zmax);
	file << "\n";
	file << "Mmin:";
	file << std::to_string(header.Mmin);
	file << "\n";
    file << "Mmax:";
	file << std::to_string(header.Mmax);
	file << "\n";
	//遍历polygon容器vector
	for (int i = 0;i < polygon.size();i++)
	{   file << "RecordNumber:";
		file << std::to_string(polygon[i].RecordNumber);
		file << "\n";
		file << "ContentLength:";
		file << std::to_string(polygon[i].ContentLength);
		file << "\n";
		file << "ShapeType:";
		file << std::to_string(polygon[i].ShapeType);
		file << "\n";
    	file << "NumParts:";
		file << std::to_string(polygon[i].NumParts);
		file << "\n";
		file << "NumPoints:";
		file << std::to_string(polygon[i].NumPoints);
		file << "\n";
		//遍历第i个ploygon的Point点 也可以 j<polygon.NumPoints
		for (int j=0;j < polygon[i].Points.size();j++)
		{	file<< "X:";
			cout << polygon[i].Points[j].X  ;
			std::to_string(polygon[i].Points[j].X);
			file << std::to_string(polygon[i].Points[j].X);
			file << "   Y:";
			cout << polygon[i].Points[j].Y << "\n";
			file << std::to_string(polygon[i].Points[j].Y);
			file << '\n';
		}
	}
}
 //将读取的数据存入新的.shp
void  writetoshp(string filepathh) {
    int zero =0;
	ofstream file;
	file.open(filepathh, ios::binary | ios::out);
	//将头文件的参数定义出来,并对大小端转换
	int code = BT(header.FileCode);
	int length = BT(header.FileLength);
	int version = BT(header.Version);
	int recordnumber;
	int contentlength;
	int shapetype;
	file.write((const char*)& code, sizeof(int));
	//5个unused
	for (int i = 0;i < 5;i++) {
		file.write((const char*)& zero, sizeof(int));
	}
	file.write((const char*)& length, sizeof(int));
	file.write((const char*)& header.Version, sizeof(int));
	file.write((const char*)& header.ShapeType, sizeof(int));
	file.write((const char*)& header.Xmin, sizeof(double));
	file.write((const char*)& header.Ymin, sizeof(double));
	file.write((const char*)& header.Xmax, sizeof(double));
	file.write((const char*)& header.Ymax, sizeof(double));
	file.write((const char*)& header.Zmin, sizeof(double));
	file.write((const char*)& header.Zmax, sizeof(double));
	file.write((const char*)& header.Mmin, sizeof(double));
	file.write((const char*)& header.Mmax, sizeof(double));
	//和写入txt步骤相同
	for (int i = 0;i < polygon.size();i++)
	{   recordnumber = BT(polygon[i].RecordNumber);
		contentlength = BT(polygon[i].ContentLength);
		file.write((const char*)& recordnumber, sizeof(int));
		file.write((const char*)& contentlength, sizeof(int));
		file.write((const char*)& polygon[i].ShapeType, sizeof(int));
		for (int j = 0;j < 4;j++)
		{
			file.write((const char*)& polygon[i].Box[j], sizeof(double));
		}
		file.write((const char*)& polygon[i].NumParts, sizeof(int));
		file.write((const char*)& polygon[i].NumPoints, sizeof(int));
		for (int j = 0;j < polygon[i].NumParts;j++)
		{	file.write((const char*)& polygon[i].Parts[j], sizeof(int));
		}
		for (int j = 0;j < polygon[i].NumPoints;j++)
		{	file.write((const char*)& polygon[i].Points[j].X, sizeof(double));
			file.write((const char*)& polygon[i].Points[j].Y, sizeof(double));
		}
	}
}

void main() {
	FILE* ShpFile_fp;
	fopen_s(&ShpFile_fp, "C:\\Users\\shitk\\Desktop\\ExtBkArea.shp", "rb");
    string file2path = "C:\\Users\\shitk\\Desktop\\new.shp";
	string filepath = "C:\\Users\\shitk\\Desktop\\polygon.txt";
	ReadFileHeard(ShpFile_fp);
	OnReadLineShp(ShpFile_fp);
	write(filepath);
	writetoshp(file2path);
	ConnectDatabase();
	create_table();
		//insert_header_data(header.FileCode, header.FileLength, header.Version,  header.ShapeType,header.Xmin,header.Ymin,header.Xmax,header.Ymax);
		//QueryDatabase();
	
	insert_header_data(header.FileCode, header.FileLength, header.Version, header.ShapeType, header.Xmin, header.Ymin, header.Xmax, header.Ymax);
	for (int i = 0;i < polygon.size();i++)
		{	insert_recordheader_data(polygon[i].RecordNumber, polygon[i].ContentLength, polygon[i].ShapeType, polygon[i].NumParts, polygon[i].NumPoints);

			for (int j = 0;j < polygon[i].Points.size();j++)
			{
				insert_pointrecord_data(polygon[i].Points[j].X, polygon[i].Points[j].Y, polygon[i].RecordNumber);
			}
	}
}
}


我看到你说没有提供从几何生成网格的代码以及pPreMdlParams结构体的具体格式,所以我接下来开始补充相关内容:从几何生成网格的代码如下:“日boo1 xdMesher2DHand::SurfMesh(constUintVec &srcIdxs,xdMeshParameter&mshParams,UintVec &trtMshIdxs)const try if(xdMeshTools::CheckMeshAbort ()) return false; if(m srcIdxs.empty() m srcEntLst.empty()) return true; xdmgShapeManager* pMngr = xdmgShape::Manager():xdmgAttributeManager *pAttriMngr = xdmgAttribute::Manager();if(nullptr == pMngr nullptr == pAttriMngr) return false: auto theCurModl = XdpActiveModel: auto pCsMngr = GeometryPart::Manager(theCurModl)auto pGeomApi = pCsMngr->GetApi(): auto pGeomKern = pCsMngr->GetModeler(): if(nullptr == pCsMngrnullptr == pGeomApi nullptr == pGeomKern) return false : auto bCallFunSuc = false: std::vector<xdmgFace*> srcFacLst: std::vector<std::string> tmpSrcFacUuids; // Revised by IvenLuo at 15:48, 2021/07/13. /for selected faces mesh std::vector<xdmGeomId>selFacUuids; // Revised by IvenLuo at 15:12, 2021/07/28. //temp use HexComponents == 3 means selected part faces mesh auto bSelFacMesh = mshParams.GetMeshSelectedGeometry():GetSelectEntityUuids(selFacUuids, bSelFacMesh):if(!selFacUuids.empty()) std::vector<xdmGeom>selSpltFacs:bCallFunSuc = xdMeshTools::GetPrepareFaces(selFacUuids, selSpltFacs) srcFacLst.reserve(selSpltFacs.size()); for(auto orgFac :selSpltFacs) auto pFac =dynamic cast<xdmgFace*>(pMngr->0bject(orgFac)):srcFacLst.emplace back (pFac): else for(auto bdy :m srcEntLst) auto shp = pMngr->0bject (bdy): if (shp != nullptr) ListFace bdyFaces. shp->Faces(bdyFaces):if(!bdyFaces.empty()) srcFacLst.insert(srcFacLst.end(),bdyFaces.begin(), bdyFaces. end()) Revised by IvenLuo at 22:27, 2024/05/26. do not use 0CCMODEL mac 1发 (pGeomKern->GetNativeKernel()== BaseModeler::0ccKernel){... } 1 (m_meshParams.GetVerboseType()>= XDM VERBOSE _DEBUG) if(m meshParams.GetProcessldx():-1mmeshParams.GetProcessIdx()== 0) std::string wirInfo = "Total input surface number of prepared model = "+ to_string(srcFacLst. size()+ "\n" ListEdge facEdgs: ListVertex facVtxs.//for(auto fac : srcFacLst) ML I#if A fac->Vertices(facVtxs) fac->Edges(facEdgs): #endif for(auto bdy :m srcEntLst) auto shp = pMngr->0bject(bdy):if(shp != nullptr) shp->Edges(facEdgs):shp->Vertices (facVtxs) std::unordered set<xdmgEdge*> allEdgs: std::unordered set<xdm gVertex*> allVtxs (auto pFac srcfaclst facEdgs. clear();pFac->Edges(facEdgs):allEdgs.insert(facEdgs.begin(), facEdgs. end()): for (auto pEdg : facEdgs) allVtxs.insert(pEdg->GetStartVertex())allVtxs.insert(pEdg->GetEndVertex()): //facEdgs. sort(): //facEdgs. unique () . /facVtxs.sort(): /facVtxs. unique() wirInfo += "Total input edge number of prepared model ="+ to_string(allEdgs. size())+ “\n".wirInfo += "Total input vertex number of prepared model = "+ to_string(allVtxs.size())+ "\n” if(m meshParams.GetProcessNum()>0) xdMeshTools::PrintMessage2Log(wirInfo): else xdMeshTools::PrintMessage(wirInfo): //#endif if(!m srcEntLst.empty()) // Revised by IvenLuo at 10:14,2021/04/15.// bug #1082, get default box with filtering wire body//auto bCallFunSuc = XDMGeomAPI_GetBox(m_srcEntLst.first(), nullptr, m_srcBox)m srcBox= GetDefaultMeshBox(srcIdxs, m srcEntLst[0]/*,m_srcBdyTypes*/); /int cnt =-1. //std::set<int>fltTrtFacPosSet = { 0 }: //if(m_meshParams.GetVerboseType()< XDM_VERBOSE_DEBUG) M fltTrtFacPosSet.clear():TT IA double plnTol = TOL PO2: bool bIsPln = false:std::vector<xdmGeom>srcFacs: srcFacs.reserve(srcFacLst.size());for(auto face : srcFacLst) //++cnt ; // Revised by IvenLuo at 16:21, 2020/12/02. support portion or multi-mesh if(m meshParams.GetRefinelterationNum()== 0 && XDML CLEAR NO MESH GEOMETRY TYPE == m meshParams. GetclearDBrype()) // temp use this option meaning no clean original mesh auto facMsh = dynamic cast<xdmgAttrMesh*>(pAttrilngr->pindttribute(face, xdmgAttrlesh:Name(0)/*, true*/): // need to load from geometry?? bool needMesh = false if 0 if (facMsh != nullptr)// had been meshed ahead, skip this face std::vector<UINT> elms;facMsh->GetBlements(elms) for (auto elm :elms) if(femElement::Manager()-)UsageFlag(elm)== xdp::objectDeleted) needMesh = true; break: if(!needMesh) continue. //// for testing//if(m meshParams.GetVerboseType () == XDM VERBOSE DEBUG)1E if(!fltTrtFacPosSet.empty()&& fltTrtFacPosSet,find(cnt)== fltTrtFacPosSet.end()) continue ; IA //// end testing endif /Revised by Ivenluo at 14:55, 2022/06/15. check plane and cached its normal if face is planeauto bIsPln=face->IsSimilarPlane(plnTol): srcFacs.emplace back(face->GetSourceGeom())m_srcFacs.insert(face): if(m meshParams.GetVerboseType()>= XDM _VERBOSE DEBUG){... xdmSurfMeshParameter surfOpts:bCallFunSuc =SetMeshParameters(mshParams,surfOpts) xdMeshLocalSizeMapfacToLocSizMap xdMeshLocalSizeMapedgToLocSizMap xdMeshLocalSizeMap vrtToLocSizMap:std::map<xdmGeom, xdmPointVec>edgToFixPtsMap: /Revised by Ivenluo at 11:47,2023/08/24.//set local mesh size or uniformly mesh for large face with single loop 1.± (xdMeshParameter::GetAppMeshField()== XDM CEM MESH FIELD1年 &&mshParams.GetFrequency()>0) bCallFunSuc =SetUniformLocalMeshForCEM(srcFacs,facToLocSizMap,mshParams): endif bCallFunSuc =GetMeshLocalSize(srcFacs,facToLocSizMap,edgToLocSizMapvrtToLocSigMap)bCallFunSuc = GetSplitEdgeFixPoints(srcFacs, edgToFixPtsMap): xdMeshLocalSizeMap edgToLocSizMap2 ;xdMeshLooplayerMap edgToLooplayerMap;std::vector<void*〉 allFreeEdges: auto GetAllFreeEdges =[&](std::vector<void*>&tmpAllFreeEdges)-> bool std::set<void*> allEntEgds.std::set<void*> allFacEdgs : for (auto ent :m srcEntLst) auto pBdyPtr =pGeomKern->GetEntityWrapper(ent):if(nullptr == pBdyPtr) continue; std::vector<IEdgePtr> entEdgs.pBdyPtr->GetAllEdges(entEdgs)allEntEgds.insert(entEdgs.begin(),entEdgs.end()) for (auto pEdgPtr : entEdgs) allEntEgds.insert (pEdgPtr->GetEntityPointer()): std::vector<IFacePtr> entFacs:pBdyPtr->GetAllFaces(entFacs)for(auto afac : entFacs) entEdgs.clear():afac->GetAllEdges(entEdgs):for(auto pEdgPtr : entEdgs) allFacEdgs.insert(pEdgPtr->GetEntityPointer()). std:set difference(allEntEgds. begin(0), allEntEgds. end0, allFacEdgs, begin0, allFacEdgs, end(), std::back inserter(tmpAllreeEdges)):return true; GetAllFreeBdges(allFreeEdges):if(surfOpts.GetTriQuadType()== 1) bCallFunSuc = GetLoopMeshData(srcFacs, edgToLocSizMap2, edgToLoopLayerMap): auto AddlooplayerSizeToLocalMeshSizeMap = [&] (xdeshlocalSizeap& edgeToLocalMeshap, const xdMeshlocalSizeMap& edgeToLoopLayerMap)->void auto pMngr =(xdmgShapeManager*)xdmgShape::Manager(): if(pMngr == NULL) return; for (auto currGeom : edgeToLoopLayerMap) if (std: :find(edgeToLocalMeshMap. begin(), edgeToLocalMeshMap.end(), currGeom)!= edgeToLocalMeshMap. end())continue: xdmgEdge* aEdge =(xdmgEdge*)pMngr->0bject(currGeom.first) double edgeLenaEdge->Length() currGeom.second +0.5)int segNumint(edgeLen if(segNum< 1)segNum=1. if(segNum %2 != 0) ++segNum: edgeToLocalMeshMap,insert(std::make pair(currGeom. first, double(segNum))): AddLoopLayerSizeToLocalMeshSizeMap(edgToLocSizMap,edgToLocSizMap2): xdMeshLocalSizeMap faceToAngMapxdMeshLocalSizeMap edgeToAnMap :bCallFunSuc = GetMeshLocalGeometricApproximateAngle(srcFacs, faceToAngMap, edgeToAnMap). /added by hyh at 2022/03/31 for PEc facesstd::vector<xdmGeom>pecFaces. if(!surfOpts.GetGeomConvertMesh ()) if(surfOpts. GetUseEdgingMesh()) bCallFunSuc =GetPECFaces(pecFaces): if(facToLocSizMap.empty()&& edgToLocSizMap. empty()&& vrtToLocSizMap. empty()&& faceToAngMap.empty()&& edgeToAnMap. empty() && pecFaces.empty() && edgToFixPtsMap. empty()) bCallFunSuc=SurfaceMeshAPI(srcFacs, surfOpts): else std::vector<double> faceSizeVect :faceSizeVect.reserve(srcFacs.size())const double noSetFacLocSiz = 0.0:for(auto srcFac :srcFacs) auto itrFnd = facTolocSizMap.find(srcFac)if(itrFnd != facToLocSizMap. end()) faceSizeVect.emplace back(itrFnd->second) else faceSizeVect.emplace back(noSetFacLocSiz) bCallPunSuc = SurfaceMeshWithDiffSizeAPI(srcFacs, faceSizeVect, edgToLocSizMap, vrtToLocSizMap,edgToLoopLayerMap, faceToAngMap, edgeToAnMap, pecFaces, edgToFixPtsMap, surfOpts): if(!bCallFunSuc) DEBUG #ifdef xdMeshTools::PrintMessage("Call SurfaceMeshAPI () failed! \n”)// ifdef DEBuG #endif return false; void* PyObject= TheApp.RunStringArg(xfmApp::False,cem. GetWireUuidList()”)void* PyObject = nullptr:if(xdMeshParameter::GetAppMeshField()== XDM CEM MESH FIELD) PyObject = xdMeshTools::RunStringArg("cem, GetWireUuidlist()", false, true) bool doWireMesh = false. if(Pyobject) doWireMesh = xfmPyTool::Parser<bool>()(PyObject): xdmGeomVector toBdyMeshEdges(allFreeEdges.begin(), allFreeEdges. end ()):if(dowireMesh) xdmGeomVector srcAllEdges: xdmGeomVector srcEdgeToMeshList ;std::vector<xdmGeomId>edgToMeshLst : std::vector<double> tmpParamLst: int intbuffer =0: xfmUiDataBuffer *curbuffer = xdMeshTools::GetCurrentBufferData(): std::vector<std::string> vPosLst: curbuffer->GetVecotr("GeometryPos", vPosLst): curbuffer->GetIntVector("GeometryID",edgToMeshLst) assert(vPosLst.size()== edgToMeshLst.size()): //curbuffer->GetInt( EdgeCount", &intbuffer):curbuffer->Pop(): intbuffer = edgToMeshLst.size(): if(intbuffer >0) for(int i=0:i< intbuffer: ++i) tmpParamLst.push back(stof(vPosLst[i])) std::unordered map<xdmGeomId,double> tmpWirPortParamMap:tmpWirPortParamMap,reserve(edgToMeshLst,size()).for(int i=0:i< edgToMeshLst.size(): i++) tmpWirPortParamMap, insert(std::pair<xdmGeomId, double>(edgToMeshlst[i], tmpParamLst [i])): std::sort(edgToMeshlst.begin(), edgToMeshLst.end () ):auto tmpItr = std::unique(edgToMeshLst.begin(), edgToMeshLst. end())edgToMeshLst.erase(tmpItr, edgToMeshLst.end()): std::vector<double> newTmpParamLst : newTmpParamLst.reserve(edgToMeshLst. size ()):for (int i=0:i<edgToMeshLst,size(:i++ newTmpParamLst. push back(tmpWirPortParamMap[edgToMeshLst[i]]) std::set<void*> edgObjToMeshLstfor (auto uuid : edgToMeshlst) edgObjToMeshLst.insert(pGeomApi->GetEntity(uuid)->GetEntityPointer ()): std::vector<xdmgEdge*> srcEdgListfor (auto bdy :m srcEntLst) auto shp = pMngr->0bject (bdy):if (shp != nullptr) ListEdge bdyEdges: shp->Edges (bdyEdges)srcEdgList.insert(srcEdgList.end(),bdyEdges.begin(), bdyEdges. end()). for (auto tmpEdg : srcEdgList)std::vector<xdmGeomId>tmpSrcNames:bool tSuc = xdMeshTools::GetEntityAllTraceNames(tmpEdg->GetSourceGeom(), false, tmpSrcNames)if(tSuc) std::set<void*> tmpSrcObjectsLst;for(auto uuid : tmpSrcNames) tmpSrcObjectsLst.insert(pGeomApi->GetEntity(uuid)->GetEntityPointer()):std::vector<void*> tmpCmnStrLst;std::set<std::string> tmpSelecteddgUuidSet(edgToMeshlst.begin(), edgToMeshlst. end()):std::set<std::string》tmpSrcNamesSet(tmpSrcNames,begin(), tmpSrcNames.end()).std:: set_intersection(edgOb jToMeshlst. begin(), edg0b jToMeshlst. end(), tmpSrc0b jectsLst. begin(), tmpSrc0b jectsLst. end(),std::back inserter(tmpCmnStrLst))if(!tmpCmnStrLst.empty()) srcEdgeToMeshList.push back(tmpEdg->GetSourceGeom()): /std::vector<std::string >allNames cmtBox partBox:pGeomApi->GetModelBoundingBox0fCurrentSln(nullptr, partBox, false)auto siz= partBox,Corner(0).DistTo(partBox, Corner(7)); double tollerance = 1.0B-6 * siz; //merge from main branch of SvN 9212 - endauto myEdgeListSort =[pGeomKern, pGeomApi](void* edgl, void* edg2)->bool auto pLftGeomPtr = pGeomKern->GetEntityWrapper(edg1)auto pRghGeomPtr= pGeomKern->GetEntityWrapper(edg2): if(nullptr == pLftGeomPtrnullptr == pRghGeomPtr) return false; xdmGeomId lftUuid, rghuuid:pGeomApi->GetEntityID(pLftGeomPtr, lftUuid)pGeomApi->GetEntityID(pRghGeomPtr, rghUuid)return lftUuid< rghUuid; std::sort(srcEdgeToMeshlist.begin(),srcEdgeToMeshlist.end(), myEdgeListSort). merge from main branch of SN 9212-endstd::vector<double>hardPntParamLst: if(edgToMeshlst.size()>0) std::vector<xdmGeom>srcWireGeomListfor(auto tmpEdg : srcEdgeToMeshlist) auto tmpEdgPtr=pGeomKern->GetEdgeWrapper(tmpEdg)std::vector<xdmGeomId>tmpSrcNames:xdMeshTools::GetEntityAllTraceNames(tmpEdg, false, tmpSrcNames):// check if there are intersection between tmpSrcNames and edgToMeshLst std::list<xdmGeomId> tmpLst1:std::list<xdmGeomId>tmpLst2 for (autosrcNamtmpSrcNames) auto srcEdg= pGeomApi->GetEdge(srcNam):for(int i=0:i<edgToMeshLst.size():++i) auto srcEdgObj= pGeomApi->GetEdge(edgToMeshLst[i])://1. check if there is middle hard point //if(srcEde == srcEdeob i)if(srcEdg->IsSameAs(srcEdg0bj)) srcWireGeomlist.push back(tmpEdg): //calculate position on original edge and project on split edge/then, calculate the param value of the project pnt on split edgedouble srcUMin, srcUMax:srcEdg->GetParamBound(srcUMin,srcUMax)double realParam= srcUMin + newTmpParamlst[i]*(srcUMax- srcUMin)cmtPoint tPt: srcEdg->GetPositionByParam(realParam, tPt): cmtPoint prjPnt.double prjParam :tmpEdgPtr->GetParam(tPt, prjParam, /*tollerance,*/prjPnt)double uMin, uMax:tmpEdgPtr->GetParamBound(uMin,uMax):double prjUnitParam =(prjParam -uMin)/(uMax - uMin): if (prjUnitParam >= 1.08-3 && prjUnitParam<=1.0- 1.0E-3 /*&& tPt.DistTo(prjPnt)<= tollerance*/)hardPntParamLst.push back (prjUnitParam) :else if(prjunitParam< 1.0E-3) hardPntParamLst.push back(0.0): else hardPntParamLst. push back(1.0) ifdef DEBuG endif if(m meshParams.GetVerboseType()>= XDM VERBOSE DETAIL) std::string wirInfo = "wire edges count to be meshed: " + to string(srcWireGeomlist.size())+ "\n"xdMeshTools::PrintMessage(wirInfo): std::set<void*》toMeshEdgeSet(srcWireGeomlist.begin(), srcWireGeomList.end())std::set<void*>allFreeEdgeSet(allFreeEdges.begin(), allFreeEdges.end()):toBdyMeshEdges.clear():std:;set difference(allFreeEdgeset.begin(), alFreedgeSet. end(), toMeshedgeset.begin0, toMeshedgeet. end0, std:back inserter(toBdyleshdges)bCallFunSuc = WireMesh(srcWireGeomlist, hardPntParamLst, true)if(!bCallFunSuc) ifdef DEBUG xdMeshTools::PrintMessage( Call SurfaceMeshAPI() failed!\n”)endif // ifdefDEBUG return false; // Revised by IvenLuo at 11:10, 2022/06/19./currently, ignore free edge mesh for FEM#if 0 xdMeshParameter orgMshOpts:assert(m pCurMshLog != nullptr):if(m pCurMshlog != nullptr) m pCurMshLog->GetMeshParameter(orgMshOpts) if(orgMshOpts.GetMeshType()!= XDM SOLID_TET MESH TYPE) if(!toBdyMeshEdges. empty()) if(selFacUuids. empty()) // if there are free edges and they are not wire mesh objects, discrete them with bdy mesherbCallFunSuc=WireMesh(toBdyMeshEdges, std::vector<double>(), false): /#endif UintVec trtBlmIdxs: xdmTypeToElementsMap typToElmsMap:bCallFunSuc =RealCreateBlments(mgFacMsh, typToElmsMap, trtElmIdxs)if(!bCallFunSuc) //#ifdef DEBUG xdMeshTools::PrintMessage("Call RealCreateElments()failed! \n”)//#endif // ifdef DEBuG return false; '/ Revised by IvenLuo at 15:01, 2021/10/07. // delete nodes in SurfaceMeshAPI()may include free nodes of wire mesh//such as quad mesh without inner wire nodes constrain(bug #2241) // delete free nodes (occ bug #2155)auto PNums =mshParams.GetProcessNum(): if(PNums ==-1|m meshParams. GetProcessIdx()==0) auto freNdNum = theFemlib.DeleteUnRefNodes (): #ifdefDEBUGif(freNdNum >0) /xdMeshParameter newMshOpts//if(m_pCurMshLog != nullptr) IL mpCurMshLog->GetMeshParameter(newMshOpts) IA //if(newMshOpts.GetVerboseType()>= XDM_VERBOSE DEBUG) std::string strDebugMsg = "Warning: There are " + to_ string(freNdNum) + " free nodes that have been deleted!\n"xdMeshTools::PrintMessage(strDebugMsg): /assert (false): endif /Progress Status:80% for surface apixdMeshTools::SetProgValue(80); build mesh element<--> surface map tifdefDEBUG I号(m meshParams.GetVerboseType()>= XDM VERBOSE DETAIL) xdMeshTools::PrintMessage("Building Wire Mesh Relation!\n”): tendif bCallFunSuc = BuildSurfElmentRelation(trtMshIdxs): auto bMshBoolPre = mshParams.IsMeshBooleanPrepare()//revised by hyh at 2023/09/20 if(!bMshBoolPre &&mshParams.GetMeshType ()== XDM SURF TRI MESH TYPE // skip clean for quad mesh && mshParams.GetSurfIntersectCorrect()) XdMeshCleanUpAPI RepairMesh (): //Revised by IvenLuo at 11:40,2023/02/22. /mesh boolean without geometry non-regular boolean prepare if(bMshBoolPre){... /Progress Status:95% for surface api xdMeshTools::SetProgValue(95): //Revised by IvenLuo at 21:56,2021/03/29. //UintVec edgVtxMshIdxs ; //bCallFunSuc =BuildEdgeElementRelation(edgVtxMshIdxs) //bCallFunSuc=BuildVertexElementRelation(edgVtxMshIdxs): return bCallFunSuc : catch(...) std::string strExceptMsg("XD surface mesh failed with unhandled exception!\n”)xdMeshTools::PrintMessage(strExceptMsg): return false: ”,pPreMdlParams结构体的格式如下:“struct LayoutPrepMdlLayerParams { int id; // 压片层ID double dEvalLower; // 层高度 double dThickness; // 层厚度 std::vector<int> lstShapesIds; // 该层包含的形状ID列表 }; using LayoutPath = std::vector<cmtPoint2D>; // 2D点(x,y)组成的路径 struct LayoutPolygon { LayoutPath path; // 多边形边界路径 std::vector<LayoutPath> holes; // 多边形内部的孔洞 std::vector<int> owner_shape_ids; // 所属形状ID }; struct LayoutPrepMdlParams { std::vector<LayoutPolygon> Bodies; // 多边形集合 std::vector<LayoutPrepMdlLayerParams> Layers; // 层参数集合 }; ”
10-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值