调用Ng_GenerateVolumeMesh触发访问违例,NetGen手动网格创建求助
NetGen手动创建网格时调用
Ng_GenerateVolumeMesh触发访问违例异常 问题重现代码
namespace nglib { #include <nglib.h> } int main() { using namespace nglib; // NetGen初始化 Ng_Init(); // 创建Ng_Mesh对象 Ng_Mesh* mesh = Ng_NewMesh(); // 向网格添加顶点 double v0[] = { 0, 0, 0 }; double v1[] = { 1, 0, 0 }; double v2[] = { 1, 1, 0 }; double v3[] = { 0, 1, 0 }; double v00[] = { 0, 0, 1 }; double v10[] = { 1, 0, 1 }; double v20[] = { 1, 1, 1 }; double v30[] = { 0, 1, 1 }; Ng_AddPoint(mesh, v0); Ng_AddPoint(mesh, v1); Ng_AddPoint(mesh, v2); Ng_AddPoint(mesh, v3); Ng_AddPoint(mesh, v00); Ng_AddPoint(mesh, v10); Ng_AddPoint(mesh, v20); Ng_AddPoint(mesh, v30); // 创建面(三角形) int trig0[] = { 0, 3, 2}; Ng_AddSurfaceElement(mesh, NG_TRIG, trig0); int trig1[] = { 0, 2, 1 }; Ng_AddSurfaceElement(mesh, NG_TRIG, trig1); int trig2[] = { 0, 5, 4 }; Ng_AddSurfaceElement(mesh, NG_TRIG, trig2); int trig3[] = { 0, 1, 5 }; Ng_AddSurfaceElement(mesh, NG_TRIG, trig3); int trig4[] = { 1, 6, 5 }; Ng_AddSurfaceElement(mesh, NG_TRIG, trig4); int trig5[] = { 1, 2, 6 }; Ng_AddSurfaceElement(mesh, NG_TRIG, trig5); int trig6[] = { 2, 7, 6 }; Ng_AddSurfaceElement(mesh, NG_TRIG, trig6); int trig7[] = { 2, 3, 7 }; Ng_AddSurfaceElement(mesh, NG_TRIG, trig7); int trig8[] = { 3, 4, 7 }; Ng_AddSurfaceElement(mesh, NG_TRIG, trig8); int trig9[] = { 3, 0, 4 }; Ng_AddSurfaceElement(mesh, NG_TRIG, trig9); int trig10[] = { 4, 6, 7 }; Ng_AddSurfaceElement(mesh, NG_TRIG, trig10); int trig11[] = { 4, 5, 6 }; Ng_AddSurfaceElement(mesh, NG_TRIG, trig11); // 网格划分参数 Ng_Meshing_Parameters mp; mp.maxh = .1; mp.second_order = 1; // 生成体网格 Ng_Result res = Ng_GenerateVolumeMesh(mesh, &mp); // 关闭NetGen Ng_Exit(); return 0; }
环境信息
从源码构建NetGen库,仓库为NGSolve/ngsolve,提交日期为2024年4月3日09:16:29。
异常信息
在TestNetGen.exe中的nglib.dll(0x00007FFE894DEB45)处触发异常:0xC0000005: 读取地址0x000001803583E410时发生访问违例。
堆栈跟踪
[Frame inline] nglib.dll!netgen::TABLE<int,1>::operator[](int) 第252行 C++ nglib.dll!netgen::Mesh::CalcSurfacesOfNode() 第2250行 C++ nglib.dll!netgen::Mesh::Compress() 第4172行 C++ nglib.dll!netgen::MeshVolume(const netgen::MeshingParameters & mp, netgen::Mesh & mesh3d) 第590行 C++ nglib.dll!nglib::Ng_GenerateVolumeMesh(void * * mesh, nglib::Ng_Meshing_Parameters * mp) 第373行 C++ TestNetGen.exe!main() 第73行 C++
补充说明
发现StackOverflow上存在类似问题。
解决方法
统一表面元素的顶点顺序
NetGen要求构成封闭几何体的所有三角形面的法向必须一致(全部指向体外或体内),否则无法正确识别封闭区域。检查所有三角形的顶点顺序,遵循右手定则统一法向:比如底部两个三角形法向向上,顶部两个法向向下,侧面法向全部向外。为表面元素分配表面ID
每个表面元素需要指定表面ID,NetGen依赖这些ID区分不同面以确保几何体封闭性。修改Ng_AddSurfaceElement调用,添加表面ID参数:
// 底部面统一用ID=1 Ng_AddSurfaceElement(mesh, NG_TRIG, trig0, 1); Ng_AddSurfaceElement(mesh, NG_TRIG, trig1, 1); // 顶部面统一用ID=2 Ng_AddSurfaceElement(mesh, NG_TRIG, trig10, 2); Ng_AddSurfaceElement(mesh, NG_TRIG, trig11, 2); // 侧面依次分配不同ID或统一ID,确保每个闭合面有对应标识
- 提前验证表面网格合法性
在生成体网格前调用Ng_CheckMesh检查表面网格是否存在未封闭、顶点错误等问题:
Ng_CheckMesh(mesh);
- 完善资源清理流程
使用完Ng_Mesh对象后调用Ng_DeleteMesh(mesh)释放内存,避免潜在的资源泄漏问题。
内容的提问来源于stack exchange,提问作者stenio
相关产品推荐
相关产品推荐

