OCC triangulation methods

Hi. I create TopoDS_Shape triangulation using BRepMesh_IncrementalMesh tools. This class create optimal mesh for visualization goals. For instance on 'example_1.png' in attachments i shown a cylinder surface triangulation created by BRepMesh_IncrementalMesh. How can i get more regular triangulation for cylinder surface (as example i took a cylinder, there may also be other surfaces types) like on 'example_2.png' picture in OCC? Does it have another triangulation methods?

jelle's picture

the tesselation looks course indeed.

how closely a shape is approximated is controlled by the DeviationAngle / DeviationCoefficient methods, of the AIS_InteractiveactiveContext class see here

-jelle

Alexander Trotsenko's picture

So i can change only a precision of the shape approximation. Does that mean that i can't change the triangulation type?

Benjamin Bihler's picture

Hi Alexander,

as far as I know there is a commercial OCC meshing module which probably offers high quality mesh generation. We had also integrated Netgen (http://sourceforge.net/projects/netgen-mesher/) into our application to get higher quality meshes and it worked quite well.

Benjamin

Alexander Trotsenko's picture

Thank you for your reply, Benjamin. But Netgen creates a volumic mesh. Or it can create a surfaces mesh yet? Just i need a mesh of surfaces only.

Benjamin Bihler's picture

It creates also surface meshes. I have a snipped of some old code here that might help you:

void Mesh::createMesh(const TopoDS_Shape& shape, Mesh& mesh,
        const MeshOptions& meshOptions)
{
    nglib::Ng_Init();

    nglib::Ng_OCC_Geometry *geometry = nglib::Ng_UseOCCGeometry(
            (nglib::Ng_OCC_Shape) &shape);

    TopTools_IndexedMapOfShape FMap;
    nglib::Ng_OCC_TopTools_IndexedMapOfShape *occ_fmap =
            (nglib::Ng_OCC_TopTools_IndexedMapOfShape*) &FMap;
    nglib::Ng_Result ng_res = nglib::Ng_OCC_GetFMap(geometry, occ_fmap);
    if (!FMap.Extent())
        std::cout << "unable to evaluate the indexed map of shape faces"
                << std::endl;

    double x_min = 0.0;
    double x_max = 0.0;
    double y_min = 0.0;
    double y_max = 0.0;
    double z_min = 0.0;
    double z_max = 0.0;

    for (int i = 1; i <= FMap.Extent(); i++)
    {
        TopoDS_Face OCCface;
        OCCface = TopoDS::Face(FMap.FindKey(i));
        Bnd_Box B;
        BRepBndLib::Add(shape, B);
        Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
        B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
        if (i == 1)
        {
            x_min = aXmin;
            x_max = aXmax;
            y_min = aYmin;
            y_max = aYmax;
            z_min = aZmin;
            z_max = aZmax;
        }
        else
        {
            x_min = std::min(aXmin, x_min);
            x_max = std::max(aXmax, x_max);
            y_min = std::min(aYmin, y_min);
            y_max = std::max(aYmax, y_max);
            z_min = std::min(aZmin, z_min);
            z_max = std::max(aZmax, z_max);
        }
    }

    Bnd_Box bbox;

    bbox.Update(x_min, y_min, z_min, x_max, y_max, z_max);

    nglib::Ng_Mesh *netgenMesh = nglib::Ng_NewMesh();
    nglib::Ng_Meshing_Parameters mp;
    //mp.maxh =1;  //
    mp.minh = meshOptions.minh; // Should be set to a positive value to prevent infinite loops
    nglib::Ng_RestrictMeshSizeGlobal(netgenMesh, mp.maxh);
    mp.fineness = meshOptions.fineness;
    mp.grading = meshOptions.grading;
    mp.elementspercurve = meshOptions.elementsPerCurve; // interesting for dynamical refinement
    //mp.elementsperedge = 2.0; // default is 2.0
    //mp.closeedgeenable = 1;
    //mp.closeedgefact = 2.0;
    //mp.optsurfmeshenable = 0;
    //mp.closeedgefact = 6.0;
    //mp.uselocalh = 1;  // Should be set FALSE (will slow down computation)
    //mp.second_order = 1;

    nglib::Ng_OCC_SetLocalMeshSize(geometry, netgenMesh, &mp);

    ng_res = nglib::Ng_OCC_GenerateEdgeMesh(geometry, netgenMesh, &mp);
    if (ng_res != nglib::NG_OK)
    {
        nglib::Ng_DeleteMesh(netgenMesh);
        throw new Exception("cannot generate edge mesh\n", __TRACE__);
    }

    ng_res = nglib::Ng_OCC_GenerateSurfaceMesh(geometry, netgenMesh, &mp);
    if (ng_res != nglib::NG_OK)
    {
        nglib::Ng_DeleteMesh(netgenMesh);
        throw new Exception("cannot generate surface mesh\n", __TRACE__);
    }

    if (meshOptions.optimize)
        nglib::Ng_OCC_Uniform_Refinement(geometry, netgenMesh);

    int nodeNumber = nglib::Ng_GetNP(netgenMesh);

    for (int nodeIndex = 1; nodeIndex <= nodeNumber; ++nodeIndex)
    {
        // We have to use an array here since the library requires it!
        double coords[3];

        nglib::Ng_GetPoint(netgenMesh, nodeIndex, coords);
        mesh.addNode(nodeIndex, gp_Pnt(coords[0], coords[1], coords[2]));
    }

    int triangleNumber = nglib::Ng_GetNSE(netgenMesh);

    for (int triangleIndex = 1; triangleIndex <= triangleNumber; ++triangleIndex)
    {
        // We have to use an array here since the library requires it!
        int nodeIndices[3];

        nglib::Ng_GetSurfaceElement(netgenMesh, triangleIndex, nodeIndices);

        mesh.addTriangle(triangleIndex, nodeIndices[0], nodeIndices[1],
                nodeIndices[2]);
    }

    // Clean up netgen
    nglib::Ng_DeleteMesh((nglib::Ng_Mesh*) netgenMesh);
    nglib::Ng_Exit();
}

Alexander Trotsenko's picture

Ok. Thank you. Although i hoped to avoid a new dependency in my project i will try to use this solution. It looks like the way of resolution my problem.

sf fan's picture

I tried NetGen to generate the mesh. It looks it can do a much better job than OCC version. But it is too slow. I have to wait a while to get the mesh.

Does anybody have the same feel?

Thanks

-Fan

Benjamin Bihler's picture

I fear that this is normal. Computing high quality meshes takes time. If I remember correctly, computing a mesh took sometimes several minutes, when I played with Netgen - even if the surface has not been that large!