Here is a simple Cinema 4D Python Generator script that creates a plane with Front and Back selection tags. (Selection Tags are not shown).
Apply two materials on your object. And write “Front” or “Back” to selection input.
Python
"""
Cinema 4D Python Generator: Plane with non-overlapping Front and Back faces.
Usage:
- Put this code into a Python Generator tag. The generator outputs the plane.
- Drag your materials onto the object that holds the Python tag. Use selection names "Front" and "Back".
"""
import c4d
# Configurable defaults
SEL_NAME_FRONT = "Front"
SEL_NAME_BACK = "Back"
DEFAULT_WIDTH = 400.0
DEFAULT_HEIGHT = 200.0
# Small offset to separate the two faces to avoid overlap/z-fighting
EPSILON = 0.0005
def create_plane_non_overlapping(width=DEFAULT_WIDTH, height=DEFAULT_HEIGHT,
sel_front=SEL_NAME_FRONT, sel_back=SEL_NAME_BACK,
epsilon=EPSILON):
hw = width * 0.5
hh = height * 0.5
# Create 8 points: 4 for front (y = +epsilon), 4 for back (y = -epsilon)
pts = [
# front verts (0..3)
c4d.Vector(-hw, epsilon, -hh), # 0
c4d.Vector( hw, epsilon, -hh), # 1
c4d.Vector( hw, epsilon, hh), # 2
c4d.Vector(-hw, epsilon, hh), # 3
# back verts (4..7)
c4d.Vector(-hw, -epsilon, -hh), # 4
c4d.Vector( hw, -epsilon, -hh), # 5
c4d.Vector( hw, -epsilon, hh), # 6
c4d.Vector(-hw, -epsilon, hh), # 7
]
# Create polygon object with 8 points and 2 polygons
obj = c4d.PolygonObject(len(pts), 2)
obj.SetName("Gen_Plane")
obj.SetAllPoints(pts)
# Front polygon (CCW winding -> normal facing +Y)
poly_front = c4d.CPolygon(0, 1, 2, 3)
# Back polygon (use back vertices, reversed winding -> normal facing -Y)
poly_back = c4d.CPolygon(7, 6, 5, 4)
obj.SetPolygon(0, poly_front)
obj.SetPolygon(1, poly_back)
# Update caches
obj.Message(c4d.MSG_UPDATE)
# Create polygon selection tag for front (polygon index 0)
front_tag = c4d.BaseTag(c4d.Tpolygonselection)
front_tag.SetName(sel_front)
front_tag.GetBaseSelect().Select(0)
obj.InsertTag(front_tag)
# Create polygon selection tag for back (polygon index 1)
back_tag = c4d.BaseTag(c4d.Tpolygonselection)
back_tag.SetName(sel_back)
back_tag.GetBaseSelect().Select(1)
obj.InsertTag(back_tag)
return obj
def main():
"""
Python Generator entry point.
'op' is the Python tag itself. Returning an object causes the tag to output it.
"""
if op is None:
return None
# You can expose these as User Data on the Python tag if you want runtime control.
width = DEFAULT_WIDTH
height = DEFAULT_HEIGHT
plane = create_plane_non_overlapping(width, height,
sel_front=SEL_NAME_FRONT,
sel_back=SEL_NAME_BACK,
epsilon=EPSILON)
return planeAnd with Thickness, now we have Front, Back and Edges as material selections. You can apply three materials on Python Generator Object.
Python
import c4d
# Configurable selection tag names and defaults
SEL_NAME_FRONT = "Front"
SEL_NAME_BACK = "Back"
SEL_NAME_EDGES = "Edges"
DEFAULT_WIDTH = 400.0
DEFAULT_HEIGHT = 200.0
DEFAULT_THICK = 10.0
def create_plane_with_thickness(width=DEFAULT_WIDTH, height=DEFAULT_HEIGHT, thickness=DEFAULT_THICK,
sel_front=SEL_NAME_FRONT, sel_back=SEL_NAME_BACK, sel_edges=SEL_NAME_EDGES):
hw = width * 0.5
hh = height * 0.5
ht = thickness * 0.5
# 8 points, 4 front, 4 back
# We treat Y as the "thickness" axis, so plane is XZ, extruded in Y.
pts = [
# Front face (positive Y)
c4d.Vector(-hw, ht, -hh), # 0: left, up, back
c4d.Vector( hw, ht, -hh), # 1: right, up, back
c4d.Vector( hw, ht, hh), # 2: right, up, front
c4d.Vector(-hw, ht, hh), # 3: left, up, front
# Back face (negative Y)
c4d.Vector(-hw, -ht, -hh), # 4: left, down, back
c4d.Vector( hw, -ht, -hh), # 5: right, down, back
c4d.Vector( hw, -ht, hh), # 6: right, down, front
c4d.Vector(-hw, -ht, hh), # 7: left, down, front
]
# Polygon definitions (order: front, back, edge1, edge2, edge3, edge4)
polys = [
# (a, b, c, d): CCW winding as seen from *outside*
c4d.CPolygon(0, 1, 2, 3), # Front (+Y)
c4d.CPolygon(7, 6, 5, 4), # Back (-Y)
c4d.CPolygon(0, 3, 7, 4), # Left edge
c4d.CPolygon(1, 0, 4, 5), # Top edge
c4d.CPolygon(2, 1, 5, 6), # Right edge
c4d.CPolygon(3, 2, 6, 7), # Bottom edge
]
obj = c4d.PolygonObject(len(pts), len(polys))
obj.SetName("Gen_PlaneSolid")
obj.SetAllPoints(pts)
for i, p in enumerate(polys):
obj.SetPolygon(i, p)
obj.Message(c4d.MSG_UPDATE)
# --- Polygon selections ---
# Front face selection (poly 0)
front_tag = c4d.BaseTag(c4d.Tpolygonselection)
front_tag.SetName(sel_front)
front_sel = front_tag.GetBaseSelect()
front_sel.Select(0)
obj.InsertTag(front_tag)
# Back face selection (poly 1)
back_tag = c4d.BaseTag(c4d.Tpolygonselection)
back_tag.SetName(sel_back)
back_sel = back_tag.GetBaseSelect()
back_sel.Select(1)
obj.InsertTag(back_tag)
# Edge faces selection (polys 2,3,4,5)
edges_tag = c4d.BaseTag(c4d.Tpolygonselection)
edges_tag.SetName(sel_edges)
edges_sel = edges_tag.GetBaseSelect()
for idx in range(2, 6):
edges_sel.Select(idx)
obj.InsertTag(edges_tag)
return obj
def main():
# You can wire these to User Data if you wish
width = DEFAULT_WIDTH
height = DEFAULT_HEIGHT
thick = DEFAULT_THICK
return create_plane_with_thickness(width, height, thick,
sel_front=SEL_NAME_FRONT,
sel_back=SEL_NAME_BACK,
sel_edges=SEL_NAME_EDGES)And with User Data:
Python
import c4d
# Selection tag names
SEL_NAME_FRONT = "Front"
SEL_NAME_BACK = "Back"
SEL_NAME_EDGES = "Edges"
def create_plane_with_thickness(width, height, thickness,
sel_front=SEL_NAME_FRONT, sel_back=SEL_NAME_BACK, sel_edges=SEL_NAME_EDGES):
hw = width * 0.5
hh = height * 0.5
ht = thickness * 0.5
pts = [
# Front face (positive Y)
c4d.Vector(-hw, ht, -hh), # 0
c4d.Vector( hw, ht, -hh), # 1
c4d.Vector( hw, ht, hh), # 2
c4d.Vector(-hw, ht, hh), # 3
# Back face (negative Y)
c4d.Vector(-hw, -ht, -hh), # 4
c4d.Vector( hw, -ht, -hh), # 5
c4d.Vector( hw, -ht, hh), # 6
c4d.Vector(-hw, -ht, hh), # 7
]
polys = [
c4d.CPolygon(0, 1, 2, 3), # Front
c4d.CPolygon(7, 6, 5, 4), # Back
c4d.CPolygon(0, 3, 7, 4), # Left edge
c4d.CPolygon(1, 0, 4, 5), # Top edge
c4d.CPolygon(2, 1, 5, 6), # Right edge
c4d.CPolygon(3, 2, 6, 7), # Bottom edge
]
obj = c4d.PolygonObject(len(pts), len(polys))
obj.SetName("Gen_PlaneSolid")
obj.SetAllPoints(pts)
for i, p in enumerate(polys):
obj.SetPolygon(i, p)
obj.Message(c4d.MSG_UPDATE)
# Front face selection (poly 0)
front_tag = c4d.BaseTag(c4d.Tpolygonselection)
front_tag.SetName(sel_front)
front_tag.GetBaseSelect().Select(0)
obj.InsertTag(front_tag)
# Back face selection (poly 1)
back_tag = c4d.BaseTag(c4d.Tpolygonselection)
back_tag.SetName(sel_back)
back_tag.GetBaseSelect().Select(1)
obj.InsertTag(back_tag)
# Edge faces (polys 2,3,4,5)
edges_tag = c4d.BaseTag(c4d.Tpolygonselection)
edges_tag.SetName(sel_edges)
for idx in range(2, 6):
edges_tag.GetBaseSelect().Select(idx)
obj.InsertTag(edges_tag)
return obj
def main():
# Fetch User Data; fallback to a default if not present
width = op[c4d.ID_USERDATA, 1] if op is not None else 400.0
height = op[c4d.ID_USERDATA, 2] if op is not None else 200.0
thick = op[c4d.ID_USERDATA, 3] if op is not None else 10.0
return create_plane_with_thickness(width, height, thick,
sel_front=SEL_NAME_FRONT,
sel_back=SEL_NAME_BACK,
sel_edges=SEL_NAME_EDGES)Feel free to download sample scene: