You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用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上存在类似问题。


解决方法

  1. 统一表面元素的顶点顺序
    NetGen要求构成封闭几何体的所有三角形面的法向必须一致(全部指向体外或体内),否则无法正确识别封闭区域。检查所有三角形的顶点顺序,遵循右手定则统一法向:比如底部两个三角形法向向上,顶部两个法向向下,侧面法向全部向外。

  2. 为表面元素分配表面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,确保每个闭合面有对应标识
  1. 提前验证表面网格合法性
    在生成体网格前调用Ng_CheckMesh检查表面网格是否存在未封闭、顶点错误等问题:
Ng_CheckMesh(mesh);
  1. 完善资源清理流程
    使用完Ng_Mesh对象后调用Ng_DeleteMesh(mesh)释放内存,避免潜在的资源泄漏问题。

内容的提问来源于stack exchange,提问作者stenio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:53:25