objects¶
Demonstrates basic operations on objects.
objects.py¶
"""Demonstrates basic operations on objects.
Topics:
- Instantiating and inserting objects into the document
- Setting and getting local and global transforms
- Accessing bounding boxes
- Modifying editor and render visibility
- Working with object caches
Related:
- modeling/geometry_cache.py
- modeling/geometry_polygon_object.py
- modeling/geometry_spline_object.py
"""
__author__ = "Ferdinand Hoppe"
__copyright__ = "Copyright (C) 2026 MAXON Computer GmbH"
__license__ = "Apache-2.0 License"
__version__ = "2027.0.0"
__date__ = "07/09/2026"
import c4d
import mxutils
doc: c4d.documents.BaseDocument # The active Cinema 4D document.
op: c4d.BaseObject | None # The currently selected object, can be None.
def main() -> None:
"""Runs the example.
"""
print("\n--- Instantiation -------------------------------------------------------------------")
# Create a new SDS and cube object and insert them as a hierarchy into the document.
sds: c4d.BaseObject = mxutils.CheckType(c4d.BaseObject(c4d.Osds))
cube: c4d.BaseObject = mxutils.CheckType(c4d.BaseObject(c4d.Ocube))
doc.InsertObject(sds)
cube.InsertUnderLast(sds)
# Add another null object as a child of the cube and directly remove it again.
null: c4d.BaseObject = mxutils.CheckType(c4d.BaseObject(c4d.Onull))
cube.InsertUnderLast(null)
null.Remove()
print("\n--- Transforms ----------------------------------------------------------------------")
# Set the local transform of the cube object (in relation to its parent).
cube.SetMl(c4d.utils.MatrixMove(c4d.Vector(100, 0, 0)))
# Set the global transform of the cube object (in world space). This operation is more
# expensive than setting the local transform and should be avoided when possible. The
# same applies to getting the transform.
cube.SetMg(c4d.utils.MatrixMove(c4d.Vector(200, 0, 0)))
print(f"{cube.GetMl() = }")
print(f"{cube.GetMg() = }")
# There also exists a lot of other transform-related functions, but I would recommend to ignore
# them unless you have to specifically deal with frozen transformations.
print("\n--- Bounding Box --------------------------------------------------------------------")
# Get the computed bounding box for the object.
center: c4d.Vector = cube.GetMp()
radius: c4d.Vector = cube.GetRad()
print(f"{center = }")
print(f"{radius = }")
print("\n--- Editor/Render Mode --------------------------------------------------------------")
# Get/Set the Editor/Render mode of the object. I.e., if the object is visible in the editor or render.
print(f"{cube.GetEditorMode() = }")
print(f"{cube.GetRenderMode() = }")
cube.SetEditorMode(c4d.MODE_ON)
cube.SetRenderMode(c4d.MODE_OFF)
# The same can also be done via parameter access with the symbols
# c4d.ID_BASEOBJECT_VISIBILITY_EDITOR and c4d.ID_BASEOBJECT_VISIBILITY_RENDER.
cube[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = c4d.MODE_ON
cube[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = c4d.MODE_OFF
print("\n--- Caches --------------------------------------------------------------------------")
# Parametric objects such as the SDS or cube have internal caches that store their polygonal
# state (the same also applies for splines which have an internal line object cache). But in
# order to access caches, the cache must exist. Which is not the case for a newly instantiated
# object as ours.
# Execute the passes on the document, so that caches are generated.
doc.ExecutePasses(bt=None, animation=False, expression=False, caches=True)
# Now we can access the cache of the objects. Caches must be treated as read only.
cubeCache: c4d.BaseObject = cube.GetCache()
sdsCache: c4d.BaseObject = sds.GetCache()
print(f"{cubeCache = }")
print(f"{sdsCache = }")
# To lean more about caches, see modeling/geometry_cache.py. In the modelling section you can
# also learn more about sub-types of BaseObject such as PolygonObject and SplineObject.
c4d.EventAdd()
if __name__ == "__main__":
c4d.ClearPythonConsole()
main()