4

I have a high resolution triangular mesh with about 2 million triangles. I want to reduce the number of triangles and vertices to about ~10000 each, while preserving its general shape as much as possible.

I know this can be done in Matlab using reducepatch. Another alternative is qslim package. Also there is decimation functionality in VTK which has python interface, so technically it is possible in python as well. Meshlab is probably available in python as well (?).

How can I do this kind of mesh decimation in python? Examples would be greatly appreciated.

AnandJ
  • 346
  • 4
  • 15
  • 2
    maybe with this example? it is not in python but it is easy to translate it http://www.vtk.org/Wiki/VTK/Examples/Cxx/Meshes/Decimation – MrPedru22 Jul 05 '16 at 07:44
  • yep, i saw that, but it is not easy to translate for me since I am only a beginner. Any help would be greatly appreciated. – AnandJ Jul 05 '16 at 07:53
  • Recent updates to VTK python version has this: https://lorensen.github.io/VTKExamples/site/Python/VisualizationAlgorithms/DecimateFran/ – AnandJ May 10 '19 at 20:29

4 Answers4

5

Here is a minimal python prototype translated from its c++ equivalent vtk example (http://www.vtk.org/Wiki/VTK/Examples/Cxx/Meshes/Decimation), as MrPedru22 well suggested.

from vtk import (vtkSphereSource, vtkPolyData, vtkDecimatePro)


def decimation():
    sphereS = vtkSphereSource()
    sphereS.Update()

    inputPoly = vtkPolyData()
    inputPoly.ShallowCopy(sphereS.GetOutput())

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

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

    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")


if __name__ == "__main__":
    decimation()
Community
  • 1
  • 1
GioR
  • 596
  • 2
  • 8
  • 19
  • To note: The points in the original polydata must be unique. If there are duplicate points in `polydata.GetPoints()` then gaps appear in the new mesh. The `vtkSTLReader` by default cleans duplicity and `vtkXXXSource`s are designed to be duplicity free. But if you've made this polydata from scratch or read a mesh using a non-VTK reader you may need to use a [vtkCleanPolyData](https://lorensen.github.io/VTKExamples/site/Cxx/PolyData/CleanPolyData/) first. – pullmyteeth Jan 15 '20 at 18:20
4

I would recommend you to use vtkQuadricDecimation, the quality of the output model is visually better than using vtkDecimatePro (without proper settings).

decimate = vtkQuadricDecimation()
decimate.SetInputData(inputPoly)
decimate.SetTargetReduction(0.9)

One of the most important things is to use Binary representation when saving STL:

stlWriter = vtkSTLWriter()
stlWriter.SetFileName(filename)
stlWriter.SetFileTypeToBinary()
stlWriter.SetInputConnection(decimate.GetOutputPort())
stlWriter.Write()
1

Another option is to apply open-source library MeshLib, which can be called both from C++ and Python code (where it is installed by pip).

And the decimating code will look like

import meshlib.mrmeshpy as mr

# load high-resolution mesh:
mesh = mr.loadMesh(mr.Path("busto.stl"))

# decimate it with max possible deviation 0.5:
settings = mr.DecimateSettings()
settings.maxError = 0.5
result = mr.decimateMesh(mesh, settings)
print(result.facesDeleted)
# 708298
print(result.vertsDeleted)
# 354149

# save low-resolution mesh:
mr.saveMesh(mesh, mr.Path("simplified-busto.stl"))

Visually both meshes look as follows: enter image description here

Fedor
  • 17,146
  • 13
  • 40
  • 131
0

Best elegant and most beautiful Python decimation tool using meshlab (mainly MeshlabXML Library) can be found in this Dr. Hussein Bakri's repository https://github.com/HusseinBakri/3DMeshBulkSimplification

I use it all the time. Have a look at the code

HB87
  • 413
  • 7
  • 16