volume_mix_meshes¶
Converts a Polygon Object to a FOG Volume. Does a mix operation over two FOG Volume objects. Converts the resulting FOG volume into a Polygon Object.
volume_mix_meshes.py¶
"""Converts a Polygon Object to a FOG Volume. Does a mix operation over two FOG Volume objects. Converts the resulting FOG volume into a Polygon Object.
Topics:
* maxon.Vector
* maxon.BaseArray
* maxon.VolumeRef
* maxon.VolumeConversionPolygon
* maxon.VolumeToolsInterface.MeshToVolume()
* maxon.VolumeToolsInterface.ConvertSDFToFog()
* maxon.VolumeToolsInterface.MixVolumes()
* maxon.VolumeToolsInterface.VolumeToMesh()
"""
__author__ = "Maxime Adam"
__copyright__ = "Copyright (C) 2026 MAXON Computer GmbH"
__license__ = "Apache-2.0 License"
__version__ = "R20"
import c4d
import maxon
def polygonToVolume(obj):
# Checks if the input obj is a PolygonObject
if not obj.IsInstanceOf(c4d.Opolygon):
raise TypeError("obj is not a c4d.Opolygon.")
# Retrieves the world matrices of the object
matrix = obj.GetMg()
# Creates a BaseArray (list) of all points position in world space
vertices = maxon.BaseArray(maxon.Vector)
vertices.Resize(obj.GetPointCount())
for i, pt in enumerate(obj.GetAllPoints()):
vertices[i] = pt * matrix
# Sets polygons
polygons = maxon.BaseArray(maxon.VolumeConversionPolygon)
polygons.Resize(obj.GetPolygonCount())
for i, poly in enumerate(obj.GetAllPolygons()):
newPoly = maxon.VolumeConversionPolygon()
newPoly.a = poly.a
newPoly.b = poly.b
newPoly.c = poly.c
if poly.IsTriangle():
newPoly.SetTriangle()
else:
newPoly.d = poly.d
polygons[i] = newPoly
# Sets the matrice used for local grid translation and rotation
polygonObjectMatrix = maxon.Matrix()
polygonObjectMatrix.off = obj.GetMg().off
polygonObjectMatrix.v1 = obj.GetMg().v1
polygonObjectMatrix.v2 = obj.GetMg().v2
polygonObjectMatrix.v3 = obj.GetMg().v3
gridSize = 1
bandWidthInterior = 1
bandWidthExterior = 1
# Before R21
if c4d.GetC4DVersion() < 21000:
volumeRef = maxon.VolumeToolsInterface.MeshToVolume(vertices,
polygons, polygonObjectMatrix,
gridSize,
bandWidthInterior, bandWidthExterior,
maxon.ThreadRef(), None)
else:
volumeRef = maxon.VolumeToolsInterface.MeshToVolume(vertices,
polygons, polygonObjectMatrix,
gridSize,
bandWidthInterior, bandWidthExterior,
maxon.ThreadRef(),
maxon.POLYGONCONVERSIONFLAGS.NONE, None)
FogVolumeRef = maxon.VolumeToolsInterface.ConvertSDFToFog(volumeRef, 0.1)
return FogVolumeRef
def main():
# Get the two objects selected and hide them
objList = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0)
if not objList:
raise RuntimeError("Failed to retrieve selected objects, please select two objects.")
if len(objList) != 2:
raise RuntimeError("You should select only 2 objects.")
obj1 = objList[0]
obj2 = objList[1]
obj1[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 1
obj2[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 1
# Checks if the first selected object is a PolygonObject
if not obj1.IsInstanceOf(c4d.Opolygon):
raise TypeError("obj1 is not a c4d.Opolygon.")
# Checks if the second selected object is a PolygonObject
if not obj2.IsInstanceOf(c4d.Opolygon):
raise TypeError("obj2 is not a c4d.Opolygon.")
# Gets a VolumeRef
vol1 = polygonToVolume(obj1)
if vol1 is None:
raise RuntimeError("Failed to convert first obj to volume.")
vol2 = polygonToVolume(obj2)
if vol2 is None:
raise RuntimeError("Failed to convert second obj to volume.")
# Does the boolean operation on the volume
finalVolume = maxon.VolumeToolsInterface.MixVolumes(vol1, vol2, c4d.MIXTYPE_MULTIPLY)
# Converts the volume to object and insert it in the scene
obj = maxon.VolumeToolsInterface.VolumeToMesh(finalVolume, 0, 0.05)
doc.InsertObject(obj)
# Pushes an update event to Cinema 4D
c4d.EventAdd()
if __name__ == '__main__':
main()