MeshLib icon indicating copy to clipboard operation
MeshLib copied to clipboard

How to create a mesh by my data.(VTK to meshlib)

Open yangyang117 opened this issue 1 year ago • 3 comments

How can I create a new mesh using MeshLib when I know the point coordinates of a polydata and the point IDs of each triangular face? Additionally, this project is very efficient, but not very beginner-friendly. I can find only a few examples, and the API documentation is relatively simple. Are there any forums with more examples, or have you considered opening a forum to allow users to upload examples?

yangyang117 avatar Jul 12 '24 07:07 yangyang117

How can I create a new mesh using MeshLib when I know the point coordinates of a polydata and the point IDs of each triangular face?

Please try to use Mesh::fromTriangles static function to create new mesh from triangles:

    /// construct mesh from vertex coordinates and a set of triangles with given ids
    [[nodiscard]] MRMESH_API static Mesh fromTriangles(
        VertCoords vertexCoordinates,
        const Triangulation& t, const MeshBuilder::BuildSettings& settings = {}, ProgressCallback cb = {} );

vertexCoordinates here are coordinates of each mesh vertex, and Triangulation = Vector<ThreeVertIds, FaceId> is array of tiples of vertex IDs (one triple per mesh triangle).

Here is a full example how to use it:

Mesh makeCylinder( float radius, float length, int resolution )
{
    std::vector<Vector3f> points(2 * resolution + 2);
    auto step = 2.0f * PI_F / float(resolution);

    for (int h = 0; h < 2; ++h)
    {
        points[h] = Vector3f(0.0f, 0.0f, float(h)*length);
        for (int anglei = 0; anglei < resolution; ++anglei)
        {
            float angle = anglei * step;
            auto ind = anglei + resolution * h + 2;
            points[ind].x = radius * cosf(angle);
            points[ind].y = radius * sinf(angle);
            points[ind].z = h * length;
        }
    }

    Triangulation t;
    t.reserve( 4 * resolution );
    for ( int i = 0; i < resolution; ++i )
    {
        t.push_back( { 0_v, VertId(((i + 1) % resolution) + 2), VertId(i + 2) } );
        t.push_back( { 1_v, VertId(i + 2 + resolution), VertId(((i + 1) % resolution) + 2 + resolution) } );
        t.push_back( { VertId(i + 2), VertId(((i + 1) % resolution) + 2), VertId(i + 2 + resolution) } );
        t.push_back( { VertId(((i + 1) % resolution) + 2), VertId(((i + 1) % resolution) + 2 + resolution),
            VertId(i + 2 + resolution) } );
    }

    return Mesh::fromTriangles( std::move( points ), t );
}

Additionally, this project is very efficient, but not very beginner-friendly. I can find only a few examples, and the API documentation is relatively simple. Are there any forums with more examples, or have you considered opening a forum to allow users to upload examples?

Thanks for the feedback. Indeed we need to improve our documentation and examples, but unfortunately there are so many other tasks. Please feel free to open new Issue or new Discussion here, and we will be happy to answer it.

Fedr avatar Jul 12 '24 09:07 Fedr

MR::Mesh TranslatteVTKTOMesh(vtkSmartPointer<vtkPolyData> polyData)
{
    MR::VertCoords points;
    MR::Triangulation t;

    //输入点坐标
    vtkSmartPointer<vtkPoints> vtkpoints = polyData->GetPoints();
    for (vtkIdType i = 0; i < vtkpoints->GetNumberOfPoints(); ++i)
    {
        double p[3];
        vtkpoints->GetPoint(i, p);

        MR::Vector3f point;

        double x, y, z;

        x = p[0];
        y = p[1];
        z = p[2];

        point = MR::Vector3f{ MR::Vector3d{ x, y, z } };
        points.push_back(point);

    }

    //输入cell信息
    vtkSmartPointer<vtkCellArray> cells = polyData->GetPolys();

    cells->InitTraversal();

    vtkIdType npts; // 顶点数量
    vtkIdType const* ptIds; // 顶点ID数组

    // 遍历cellArray中的每个单元
    cells->InitTraversal();
    while (cells->GetNextCell(npts, ptIds)) {
        if (npts == 3) { // 确保是三角形

            MR::ThreeVertIds currTri;
            MR::VertId id;

            int id1 = static_cast<int>(ptIds[0]);
            int id2 = static_cast<int>(ptIds[1]);
            int id3 = static_cast<int>(ptIds[2]);
            currTri[0] = MR::VertId(id1);
            currTri[1] = MR::VertId(id2);
            currTri[2] = MR::VertId(id3);
            t.push_back(currTri);
        }
    }

    std::vector<MR::MeshBuilder::VertDuplication>* dupsPtr = nullptr;

    MR::MeshBuilder::BuildSettings buildSettings;

    MR::Mesh res = MR::Mesh::fromTrianglesDuplicatingNonManifoldVertices(std::move(points), t, dupsPtr, buildSettings);

    return res;
    }




vtkSmartPointer<vtkPolyData>TranslatteMeshTOVTK(MR::Mesh mesh)
{
    vtkSmartPointer<vtkPoints> vtkpoints = vtkSmartPointer<vtkPoints>::New();
    // 创建三角形
    vtkSmartPointer<vtkTriangle> vtktriangle = vtkSmartPointer<vtkTriangle>::New();

    // 创建单元数组并添加三角形
    vtkSmartPointer<vtkCellArray> vtktriangles = vtkSmartPointer<vtkCellArray>::New();


    const std::vector<std::array<MR::VertId, 3>> triangles = mesh.topology.getAllTriVerts();

    // all point coordinates
    const std::vector<MR::Vector3f>& points = mesh.points.vec_;
    // triangle vertices as tripples of ints (pointing to elements in points vector)
    const int* vertexTripples = reinterpret_cast<const int*>(triangles.data());

    // 打印顶点坐标
    for (const auto& point : points)
    {   
        vtkpoints->InsertNextPoint(point.x, point.y, point.z);

    }

    // 打印三角形顶点ID
 
    for (const auto& tri : triangles)
    {   // 创建三角形
        vtkSmartPointer<vtkTriangle> vtktriangle = vtkSmartPointer<vtkTriangle>::New();
        vtktriangle->GetPointIds()->SetId(0, tri[0]);
        vtktriangle->GetPointIds()->SetId(1, tri[1]);
        vtktriangle->GetPointIds()->SetId(2, tri[2]);

        vtktriangles->InsertNextCell(vtktriangle);
    }




    // 创建PolyData对象并设置点和单元
    vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
    polyData->SetPoints(vtkpoints);
    polyData->SetPolys(vtktriangles);

    return polyData;

}

yangyang117 avatar Jul 13 '24 06:07 yangyang117

How can I create a new mesh using MeshLib when I know the point coordinates of a polydata and the point IDs of each triangular face?

Please try to use Mesh::fromTriangles static function to create new mesh from triangles:

    /// construct mesh from vertex coordinates and a set of triangles with given ids
    [[nodiscard]] MRMESH_API static Mesh fromTriangles(
        VertCoords vertexCoordinates,
        const Triangulation& t, const MeshBuilder::BuildSettings& settings = {}, ProgressCallback cb = {} );

vertexCoordinates here are coordinates of each mesh vertex, and Triangulation = Vector<ThreeVertIds, FaceId> is array of tiples of vertex IDs (one triple per mesh triangle).

Here is a full example how to use it:

Mesh makeCylinder( float radius, float length, int resolution )
{
    std::vector<Vector3f> points(2 * resolution + 2);
    auto step = 2.0f * PI_F / float(resolution);

    for (int h = 0; h < 2; ++h)
    {
        points[h] = Vector3f(0.0f, 0.0f, float(h)*length);
        for (int anglei = 0; anglei < resolution; ++anglei)
        {
            float angle = anglei * step;
            auto ind = anglei + resolution * h + 2;
            points[ind].x = radius * cosf(angle);
            points[ind].y = radius * sinf(angle);
            points[ind].z = h * length;
        }
    }

    Triangulation t;
    t.reserve( 4 * resolution );
    for ( int i = 0; i < resolution; ++i )
    {
        t.push_back( { 0_v, VertId(((i + 1) % resolution) + 2), VertId(i + 2) } );
        t.push_back( { 1_v, VertId(i + 2 + resolution), VertId(((i + 1) % resolution) + 2 + resolution) } );
        t.push_back( { VertId(i + 2), VertId(((i + 1) % resolution) + 2), VertId(i + 2 + resolution) } );
        t.push_back( { VertId(((i + 1) % resolution) + 2), VertId(((i + 1) % resolution) + 2 + resolution),
            VertId(i + 2 + resolution) } );
    }

    return Mesh::fromTriangles( std::move( points ), t );
}

Additionally, this project is very efficient, but not very beginner-friendly. I can find only a few examples, and the API documentation is relatively simple. Are there any forums with more examples, or have you considered opening a forum to allow users to upload examples?

Thanks for the feedback. Indeed we need to improve our documentation and examples, but unfortunately there are so many other tasks. Please feel free to open new Issue or new Discussion here, and we will be happy to answer it.

Thank you very much for the information. I have read the mr loadbinarystl function make it comes out. just for anyone who need this.

yangyang117 avatar Jul 13 '24 06:07 yangyang117