我看到你说没有提供从几何生成网格的代码以及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; // 层参数集合
};
”