Solved How to use c4d.utils.PolygonReduction

Hi all,

I'm struggling to understand how does the polygon reduction works. The manual provides a sample code:
https://developers.maxon.net/docs/Cinema4DPythonSDK/html/manuals/manual_polygonreduction.html

I tried to run this one, but I get the following error:
StandardError: The dictionary must contain a valid polygonal BaseObject (_op dictionary entry)

I understand this error: I'm providing the wrong object type (https://developers.maxon.net/docs/Cinema4DPythonSDK/html/types/objects.html). I think I have to convert the object to PolygonObject, am I right? If so, how do I do that?

Hi,

A BaseObject is the base type of every object in a document. A PointObject is an object that holds points. Then an object can be a PolygonObject if it has polygons.
For instance if a generator object is made editable then it's transformed into a PolygonObject which is also a PointObject.
The (reduced) object classes inheritance tree is as follows:

  • BaseObject
    • PointObject
      • SplineObject
      • PolygonObject

Former MAXON SDK Engineer

Hi,

That's right, the error you're getting is related to the type of the passed object to be processed by the PolygonReduction.
The sample code shouldn't try to process an object that isn't a PolygonObject because there's this check at the beginning:

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

To convert a BaseObject to a PolygonObject the Current State to Object modeling command can be used.
The utility function below invokes the MCOMMAND_CURRENTSTATETOOBJECT:

def CSTO(obj, doc, inheritance, keepAnimation, noGenerate):
    bc = c4d.BaseContainer()
    bc.SetBool(c4d.MDATA_CURRENTSTATETOOBJECT_INHERITANCE, inheritance)
    bc.SetBool(c4d.MDATA_CURRENTSTATETOOBJECT_KEEPANIMATION, keepAnimation)
    bc.SetBool(c4d.MDATA_CURRENTSTATETOOBJECT_NOGENERATE, noGenerate)

    res = c4d.utils.SendModelingCommand(c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[obj.GetClone()], bc=bc, doc=doc)
    if isinstance(res, list):
        return res[0]
    else:
        return None

The CSTO() function can then be invoked like this:

if not polyObject.IsInstanceOf(c4d.Opolygon):
    polyObject = CSTO(polyObject, doc, True, True, False)
    if polyObject is None:
        return

I moved the topic to "CINEMA 4D DEVELOPMENT" category and I turned it into a question and answer (you can do this by yourself, see Q&A New Functionality).

Former MAXON SDK Engineer

Thank you y_puech

Would you be so kindly to explain me the difference between a BaseObject, a PolygonObject and a PointObject? Honestly I don't think the python documentation is really clear

Consider that I'm new to cinema4d (I'm from the blender's world)

Hi,

A BaseObject is the base type of every object in a document. A PointObject is an object that holds points. Then an object can be a PolygonObject if it has polygons.
For instance if a generator object is made editable then it's transformed into a PolygonObject which is also a PointObject.
The (reduced) object classes inheritance tree is as follows:

  • BaseObject
    • PointObject
      • SplineObject
      • PolygonObject

Former MAXON SDK Engineer

Thank you! This is so much clear now