How to decimate a 3D box mesh generated by GMSH?

Hi everyone

I am new to VTK.
I want to decimate a box meshed with tetrahedra and generated by GMSH. I follow the example for Python here.
However, my decimated mesh only contain boundaries of the box and 2D triangle meshes.

Could you please help me to point out what is wrong in my code?

Thank you very much

from vtk import *

def unstructured_grid_to_polydata(unstructured_grid):
   # Convert unstructured grid to polydata
   geo_filter = vtk.vtkGeometryFilter()
   geo_filter.SetInputData(unstructured_grid)
   geo_filter.Update()
   polydata = geo_filter.GetOutput()
   return polydata 



def decimate_mesh(mesh_name):
    print('=== decimate ===')
    print('mesh_name:', mesh_name)
    head_name, tail_name = mesh_name.split('.')

    # Reader reads mesh file
    reader = vtkUnstructuredGridReader()
    reader.SetFileName(mesh_name)
    reader.Update()

    # convert unstructured grid to polydata
    inputPoly = unstructured_grid_to_polydata(reader.GetOutput())


    print("Before decimation\n"
          "-----------------\n"
          "There are " + str(inputPoly.GetNumberOfPoints()) + " points.\n"
          "There are " + str(inputPoly.GetNumberOfPolys()) + " polygons.\n")

    # decimate
    decimate = vtkDecimatePro()
    decimate.SetInputData(inputPoly)
    decimate.SetTargetReduction(.10)
    decimate.Update()

    # decimate Polydata
    decimatedPoly = vtkPolyData()
    decimatedPoly.ShallowCopy(decimate.GetOutput())

    print("After decimation \n"
          "-----------------\n"
          "There are " + str(decimatedPoly.GetNumberOfPoints()) + " points.\n"
          "There are " + str(decimatedPoly.GetNumberOfPolys()) + " polygons.\n")



    # export decimated mesh (does not work)
    #writer = vtkUnstructuredGridWriter()
    #writer.SetInputData(decimate.GetOutput())
    #writer.SetFileName("{}_decimated.vtk".format(head_name))
    #writer.Write()

    #save .vtk polydata
    writer = vtk.vtkPolyDataWriter()
    writer.SetFileTypeToASCII()
    writer.SetInputData(decimate.GetOutput()) 
    writer.SetFileName("{}_decimated.vtk".format(head_name))
    writer.Write()

    #STL writer
    stlWriter = vtkSTLWriter()
    stlWriter.SetFileName("{}_decimated.stl".format(head_name))
    stlWriter.SetFileTypeToBinary()
    stlWriter.SetInputConnection(decimate.GetOutputPort())
    stlWriter.Write()

    return




if __name__ == "__main__":
    load_path = 'Geometry/'
    mesh_name = 'box.vtk'
    decimate_mesh(load_path + mesh_name)

The decimation algorithms (e.g. vtkDecimatePro) only work on vtkPolyData meshes (2D surface geometries - so the bounding surface of your volumetric mesh).

As far as I am aware, there aren’t any decimation algorithms for 3D geometries in VTK (to my knowledge).

@akaszynski might have a 3D version of the ACVD algorithm that he might be willing (:grinning:) to upload in PyACVD which works with PyVsita (a Python wrapper for VTK). So maybe keep an eye on PyACVD…

If you open an issue in PyACVD then you might be likely to see that 3D algorthm added :wink:

It’s a 3D clustering algorithm that works fairly well, but I’ve only used it internally. If there’s interest on GitHub I’ll add it.

2 Likes