Subdivision filter

Hello dear users / developers,

As input i have a polygon like following image :

I used vtkLinearSubdivisionFilter to subdivide these triangles so i got this result :

I want to have equilateral triangles as result, could you propose a solution for this, please ?

Thanks in advance

Hello, Danial,

VTK is great library but for advanced mesh generation out of some boundary lines (I suppose you’d like a mesh to run some finite element method) I recommend using CGAL: https://doc.cgal.org/latest/Mesh_2/index.html .

kind regards,

Paulo

To generate a uniform mesh, do not subdivide a large polygon but use the appropriate source, such as vtkPlaneSource and then triangulate it if needed.

For remeshing an arbitrary polygon, you can use vtkAdaptiveSubdivisionFilter and there are a few other subdivision filters in VTK. If you need more sophisticated solutions then there are other free mesh remeshing libraries, such as OpenSubdiv.

CGAL’s mesh refinement filters do not seem to be much better than VTK’s and the package (as most of CGAL) comes with commercial/GPL license, so you must pay if you want to use it in non-open-source products.

1 Like

Sorry for nit-picking, but what I suggested was not mesh refinement, but mesh generation, which is an etirely different game, you know. With it, one can generate all the vertexes and edges given only the four corners in the case of the original post.

1 Like

Hello Paulo,

Thank you for your answer and for proposing CGAL.

Actually my project is totally based on VTK library and i think it’s a really powerful library. I also want to use open source libraries, so i think using CGAL could not be a good solution for me.

Best regards,

Danial

Hello Andras,

Thank you for your answer.

Is it possible to use vtkPlaneSource to generate non-rectangular polygons or non-convex polygons ?

Actually i tried vtkAdaptiveSubdivisionFilter but it was not worked. i did not find an example to find out how use it properly so i did it as follow :

        vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();

        // Create the polygon
        auto boundaries = vtkSmartPointer<vtkPolygon>::New();
        boundaries->GetPointIds()->SetNumberOfIds(4);

        points->InsertNextPoint(5000.0, 1500.0, 0.0);
        elevationArray->InsertNextValue(0.0);
        boundaries->GetPointIds()->SetId(0, 0);

        points->InsertNextPoint(-5000.0, 1500.0, 0.0);
        elevationArray->InsertNextValue(0.0);
        boundaries->GetPointIds()->SetId(1, 1);

        points->InsertNextPoint(-5000.0, -1500.0, 0.0);
        elevationArray->InsertNextValue(0.0);
        boundaries->GetPointIds()->SetId(2, 2);

        points->InsertNextPoint(5000.0, -1500.0, 0.0);
        elevationArray->InsertNextValue(0.0);
        boundaries->GetPointIds()->SetId(3, 3);

        // Add the polygon to a list of polygons
        vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New();
        polygons->InsertNextCell(boundaries);

        // Field exterior boundary
        auto boundary = vtkSmartPointer<vtkPolyData>::New();
        boundary->SetPoints(points);
        boundary->SetPolys(polygons);

        auto aPolygon = vtkSmartPointer<vtkPolyData>::New();
        aPolygon->SetPoints(points);

        auto triangles = vtkSmartPointer<vtkDelaunay2D>::New();
        triangles->SetInputData(aPolygon);
        triangles->SetSourceData(boundary);
        triangles->Update();

        polyData2D = vtkSmartPointer<vtkPolyData>::New();
        polyData2D->DeepCopy(triangles->GetOutput());

       auto subdivision = vtkSmartPointer<vtkAdaptiveSubdivisionFilter>::New();
       subdivision->SetInputData(polyData2D);
       subdivision->SetMaximumEdgeLength(300.0);
       subdivision->Update();

It took so long with no return and no error. Is this code correct ?

Best regards,

Danial

I just found my solution. i did it as follow :

    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();

    // Create the polygon
    auto boundaries = vtkSmartPointer<vtkPolygon>::New();
    boundaries->GetPointIds()->SetNumberOfIds(4);

    points->InsertNextPoint(5000.0, 1500.0, 0.0);
    elevationArray->InsertNextValue(0.0);
    boundaries->GetPointIds()->SetId(0, 0);

    points->InsertNextPoint(-5000.0, 1500.0, 0.0);
    elevationArray->InsertNextValue(0.0);
    boundaries->GetPointIds()->SetId(1, 1);

    points->InsertNextPoint(-5000.0, -1500.0, 0.0);
    elevationArray->InsertNextValue(0.0);
    boundaries->GetPointIds()->SetId(2, 2);

    points->InsertNextPoint(5000.0, -1500.0, 0.0);
    elevationArray->InsertNextValue(0.0);
    boundaries->GetPointIds()->SetId(3, 3);

    // Add the polygon to a list of polygons
    vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New();
    polygons->InsertNextCell(boundaries);

    auto polyData2D = vtkSmartPointer<vtkPolyData>::New();
    boundary->SetPoints(points);
    boundary->SetPolys(polygons);

    auto sample = vtkSmartPointer<vtkPolyDataPointSampler>::New();
    sample->SetInputData(polyData2D);
    sample->SetDistance(100.0);
    sample->Update();

    auto triangles = vtkSmartPointer<vtkDelaunay2D>::New();
    triangles->SetInputData(sample->GetOutput());
    triangles->Update();

And i got this result :