PolygonReduction Manual

About

The c4d.utils.PolygonReduction class allows to reduce the polygon count of a given c4d.PolygonObject while retaining its overall shape. The class gives access to the functionality used within the “Polygon Reduction” generator.

Create

c4d.utils.PolygonReduction objects are created with PolygonReduction.__init__() / ().

 # This example creates a new PolygonReduction object.

import c4d
from c4d import utils

polyReduction = utils.PolygonReduction()

Init

A c4d.utils.PolygonReduction object has to be initialized. It will pre-process the given c4d.PolygonObject.

The data dictionary argument has these keys:

Note

If it should be possible to abort the reduction operation and to retain the original mesh, it is advised to operate on a copy of the original c4d.PolygonObject.

 # This example configures the given PolygonReduction object and reduces the given PolygonObject to 25%.

import c4d
from c4d import utils

def main():
    #get polygon object

    polyObject = doc.GetActiveObject()
    if polyObject is None:
        return

    if not polyObject.IsInstanceOf(c4d.Opolygon):
        return

    # settings for PolygonReduction.PreProcess()
    settings = c4d.BaseContainer()
    settings[c4d.POLYREDUXOBJECT_PRESERVE_3D_BOUNDARY] = True
    settings[c4d.POLYREDUXOBJECT_PRESERVE_UV_BOUNDARY] = True

    # data for PolygonReduction.PreProcess()
    data = {}
    data['_op'] = polyObject
    data['_doc'] = doc
    data['_settings'] = settings
    data['_thread'] = None # synchronous pre-processing and reduction

    # create PolygonReduction object
    polyReduction = utils.PolygonReduction()
    if polyReduction is None:
        return

    # pre process
    if not polyReduction.PreProcess(data):
      return

    # reduce
    polyReduction.SetReductionStrengthLevel(0.75)

    # update original PolygonObject
    polyObject.Message(c4d.MSG_UPDATE)
    c4d.EventAdd()

if __name__=='__main__':
    main()

If the _thread key is set the pre-process is running asynchronously in a background thread.

Note

This asynchronous mode may be used e.g. in a generator object.

After the pre-process the c4d.utils.PolygonReduction object is ready:

Reduce

The linked c4d.PolygonObject can be reduced by defining the overall reduction strength or the target triangle, vertex or edge count.

The triangle count is defined with:

# This example reduces the active PolygonObject to the given triangle count.

import c4d
from c4d import gui, utils

def main():
    #get polygon object

    polyObject = doc.GetActiveObject()
    if polyObject is None:
        return

    if not polyObject.IsInstanceOf(c4d.Opolygon):
        return

    # settings for PolygonReduction.PreProcess()
    settings = c4d.BaseContainer()
    settings[c4d.POLYREDUXOBJECT_PRESERVE_3D_BOUNDARY] = True
    settings[c4d.POLYREDUXOBJECT_PRESERVE_UV_BOUNDARY] = True

    # data for PolygonReduction.PreProcess()
    data = {}
    data['_op'] = polyObject
    data['_doc'] = doc
    data['_settings'] = settings
    data['_thread'] = None # synchronous pre-processing and reduction

    # create PolygonReduction object
    polyReduction = utils.PolygonReduction()
    if polyReduction is None:
        return

    # pre process
    if not polyReduction.PreProcess(data):
      return

    # ask for number of triangle level
    while True:
        input = gui.InputDialog("Enter number of triangle level:")
        if input == "":
            # operation was cancelled
            polyObject.Message(c4d.MSG_UPDATE)
            c4d.EventAdd()
            return
        # try to convert to integer
        try:
            triangleLevel = int(input)
            break
        except ValueError:
            gui.MessageDialog("Please enter a number.")

    # check entered number of triangle level is valid
    if triangleLevel < polyReduction.GetMinTriangleLevel():
       return
    if triangleLevel > polyReduction.GetMaxTriangleLevel():
       return

    # set triangle level
    polyReduction.SetTriangleLevel(triangleLevel)

    # get number of triangle level after reduction
    realTriangleResult = polyReduction.GetTriangleLevel()
    print "Triangle Result: " + str(realTriangleResult)

    # update original PolygonObject
    polyObject.Message(c4d.MSG_UPDATE)
    c4d.EventAdd()

if __name__=='__main__':
    main()

The vertex count is defined with:

# This example reduces the active PolygonObject to the given vertex count.

import c4d
from c4d import gui, utils

def main():
    #get polygon object

    polyObject = doc.GetActiveObject()
    if polyObject is None:
        return

    if not polyObject.IsInstanceOf(c4d.Opolygon):
        return

    # settings for PolygonReduction.PreProcess()
    settings = c4d.BaseContainer()
    settings[c4d.POLYREDUXOBJECT_PRESERVE_3D_BOUNDARY] = True
    settings[c4d.POLYREDUXOBJECT_PRESERVE_UV_BOUNDARY] = True

    # data for PolygonReduction.PreProcess()
    data = {}
    data['_op'] = polyObject
    data['_doc'] = doc
    data['_settings'] = settings
    data['_thread'] = None # synchronous pre-processing and reduction

    # create PolygonReduction object
    polyReduction = utils.PolygonReduction()
    if polyReduction is None:
        return

    # pre process
    if not polyReduction.PreProcess(data):
      return

    # ask for number of vertex level
    while True:
        input = gui.InputDialog("Enter number of vertex level:")
        if input == "":
            # operation was cancelled
            polyObject.Message(c4d.MSG_UPDATE)
            c4d.EventAdd()
            return
        # try to convert to integer
        try:
            vertexLevel = int(input)
            break
        except ValueError:
            gui.MessageDialog("Please enter a number.")

    # check entered number of vertex level is valid
    if vertexLevel < polyReduction.GetMinVertexLevel():
        return
    if vertexLevel > polyReduction.GetMaxVertexLevel():
       return

    # set vertex level
    polyReduction.SetVertexLevel(vertexLevel)

    # get number of vertex level after reduction
    realVertexResult = polyReduction.GetVertexLevel()
    print "Vertex Result: " + str(realVertexResult)

    # update original PolygonObject
    polyObject.Message(c4d.MSG_UPDATE)
    c4d.EventAdd()

if __name__=='__main__':
    main()

Finally the edge count can be defined with:

# This example reduces the active PolygonObject to the given edge count.

import c4d
from c4d import gui, utils

def main():
    #get polygon object

    polyObject = doc.GetActiveObject()
    if polyObject is None:
        return

    if not polyObject.IsInstanceOf(c4d.Opolygon):
        return

    # settings for PolygonReduction.PreProcess()
    settings = c4d.BaseContainer()
    settings[c4d.POLYREDUXOBJECT_PRESERVE_3D_BOUNDARY] = True
    settings[c4d.POLYREDUXOBJECT_PRESERVE_UV_BOUNDARY] = True

    # data for PolygonReduction.PreProcess()
    data = {}
    data['_op'] = polyObject
    data['_doc'] = doc
    data['_settings'] = settings
    data['_thread'] = None # synchronous pre-processing and reduction

    # create PolygonReduction object
    polyReduction = utils.PolygonReduction()
    if polyReduction is None:
        return

    # pre process
    if not polyReduction.PreProcess(data):
      return

    # ask for number of edges level
    while True:
        input = gui.InputDialog("Enter number of edges level:")
        if input == "":
            # operation was cancelled
            polyObject.Message(c4d.MSG_UPDATE)
            c4d.EventAdd()
            return
        # try to convert to integer
        try:
            edgesLevel = int(input)
            break
        except ValueError:
            gui.MessageDialog("Please enter a number.")

    # check entered number of edges level is less than the maximum edges level
    if edgesLevel > polyReduction.GetMaxRemainingEdgesLevel():
        polyObject.Message(c4d.MSG_UPDATE)
        c4d.EventAdd()
        return

    # set edges level number
    polyReduction.SetRemainingEdgesLevel(edgesLevel)

    # get number of edges level after reduction
    realEdgeResult = polyReduction.GetRemainingEdgesLevel()
    print "Edge Result: " + str(realEdgeResult)

    # update original PolygonObject
    polyObject.Message(c4d.MSG_UPDATE)
    c4d.EventAdd()

if __name__=='__main__':
    main()