Skip to content

Commit a12cca1

Browse files
committed
Python SDK example for Cinema 4D 2024.2.0
1 parent 0e0cfd6 commit a12cca1

File tree

13 files changed

+249
-47
lines changed

13 files changed

+249
-47
lines changed

plugins/py-custom_icon_r21/py-custom_icon_r21.pyp

+6-7
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ PLUGIN_ID = 1053134
2222

2323
class CustomIconObjectData(c4d.plugins.ObjectData):
2424

25-
def Init(self, node):
25+
def Init(self, node, isCloneInit=False):
2626
"""Called by Cinema 4D to initialize the instance.
2727
2828
Args:
2929
node (c4d.GeListNode): The instance of the ObjectData.
30+
isCloneInit (bool): True if the object data is a copy of another one.
3031
3132
Returns:
3233
bool: True on success, otherwise False.
@@ -43,10 +44,6 @@ class CustomIconObjectData(c4d.plugins.ObjectData):
4344
# Defines the custom color mode used with the previously created BaseContainer already filled
4445
iconSettings.SetContainer(0, iconSpecialModes)
4546

46-
# Since we are going to use our custom MSG_GETCUSTOMICONS code,
47-
# set this to True so parent object (e.g. BaseObject) will ignore MSG_GETCUSTOMICONS messages.
48-
iconSettings.SetBool(c4d.ID_ICONCHOOSER_SETTINGS_PARENT_IGNORE, True)
49-
5047
# Sets icon settings container into the current Object instance data container
5148
node.GetDataInstance().SetContainer(c4d.ID_ICONCHOOSER_SETTINGS, iconSettings)
5249

@@ -93,7 +90,7 @@ class CustomIconObjectData(c4d.plugins.ObjectData):
9390
settings._specialColors = arr
9491

9592
# Fills the CustomIconSettings with the passed BaseContainer object
96-
c4d.CustomIconSettings.FillCustomIconSettingsFromBaseList2D(settings, node.GetData(), node.GetType(), True)
93+
c4d.CustomIconSettings.FillCustomIconSettingsFromBaseList2D(settings, node.GetDataInstance(), node.GetType(), True)
9794

9895
# Finally fills the icon Data settings with the CustomIconSettings
9996
c4d.CustomIconSettings.GetCustomIcon(data, settings, True)
@@ -115,9 +112,11 @@ if __name__ == "__main__":
115112
raise MemoryError("Failed to initialize the BaseBitmap.")
116113

117114
# Registers the object plugin
115+
# Since we are going to use our custom MSG_GETCUSTOMICONS code,
116+
# set TAG_ICONCHOOSER_PARENT_IGNORE o parent object (e.g. BaseObject) will ignore MSG_GETCUSTOMICONS messages.
118117
c4d.plugins.RegisterObjectPlugin(id=PLUGIN_ID,
119118
str="py-Custom Icon Object Data",
120119
g=CustomIconObjectData,
121120
description="py_custom_icon",
122121
icon=bmp,
123-
info=c4d.OBJECT_GENERATOR)
122+
info=c4d.OBJECT_GENERATOR | c4d.TAG_ICONCHOOSER_PARENT_IGNORE)

plugins/py-double_circle_r19/py-double_circle_r19.pyp

+11-9
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,12 @@ class DoubleCircleHelper(object):
147147
class DoubleCircleData(c4d.plugins.ObjectData, DoubleCircleHelper):
148148
"""CircleObject Generator"""
149149

150-
def Init(self, node):
150+
def Init(self, node, isCloneInit=False):
151151
"""Called when Cinema 4D initializes the ObjectData.
152152
153153
Args:
154154
node (c4d.GeListNode): The instance of the ObjectData.
155+
isCloneInit (bool): True if the object data is a copy of another one.
155156
156157
Returns:
157158
bool: True on success, otherwise False.
@@ -161,14 +162,15 @@ class DoubleCircleData(c4d.plugins.ObjectData, DoubleCircleHelper):
161162
if data is None:
162163
return False
163164

164-
# Defines default values in the BaseContainer
165-
data.SetFloat(c4d.PYCIRCLEOBJECT_RAD, 200.0)
166-
data.SetInt32(c4d.PRIM_PLANE, c4d.PRIM_PLANE_XY)
167-
data.SetBool(c4d.PRIM_REVERSE, False)
168-
data.SetInt32(c4d.SPLINEOBJECT_INTERPOLATION, c4d.SPLINEOBJECT_INTERPOLATION_ADAPTIVE)
169-
data.SetInt32(c4d.SPLINEOBJECT_SUB, 8)
170-
data.SetFloat(c4d.SPLINEOBJECT_ANGLE, c4d.utils.Rad(5.0))
171-
data.SetFloat(c4d.SPLINEOBJECT_MAXIMUMLENGTH, 5.0)
165+
if not isCloneInit:
166+
# Defines default values in the BaseContainer
167+
data.SetFloat(c4d.PYCIRCLEOBJECT_RAD, 200.0)
168+
data.SetInt32(c4d.PRIM_PLANE, c4d.PRIM_PLANE_XY)
169+
data.SetBool(c4d.PRIM_REVERSE, False)
170+
data.SetInt32(c4d.SPLINEOBJECT_INTERPOLATION, c4d.SPLINEOBJECT_INTERPOLATION_ADAPTIVE)
171+
data.SetInt32(c4d.SPLINEOBJECT_SUB, 8)
172+
data.SetFloat(c4d.SPLINEOBJECT_ANGLE, c4d.utils.Rad(5.0))
173+
data.SetFloat(c4d.SPLINEOBJECT_MAXIMUMLENGTH, 5.0)
172174
return True
173175

174176
def GetContour(self, node, doc, lod, bt):

plugins/py-dynamic_parameters_object_r18/py-dynamic_parameters_object_r18.pyp

+5-3
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,20 @@ class DynamicParametersObjectData(c4d.plugins.ObjectData):
4242
self.parameters = [] # Dynamic parameters value
4343
self.randomID = 0 # Random dynamic parameter ID to disable (see GetDEnabling() below)
4444

45-
def Init(self, node):
45+
def Init(self, node, isCloneInit=False):
4646
"""Called by Cinema 4D on the initialization of the ObjectData, usually the place to define parameters value.
4747
4848
Args:
4949
node (c4d.GeListNode): The instance of the ObjectData.
50+
isCloneInit (bool): True if the object data is a copy of another one.
5051
5152
Returns:
5253
bool: True if the initialization was successful, otherwise False, preventing Cinema 4D from creating the object.
5354
"""
5455

55-
# Defines how many parameters the object will have
56-
node[c4d.OPYDYNAMICPARAMETERSOBJECT_PARAMETERSNUMBER] = 10
56+
if not isCloneInit:
57+
# Defines how many parameters the object will have
58+
node[c4d.OPYDYNAMICPARAMETERSOBJECT_PARAMETERSNUMBER] = 10
5759

5860
return True
5961

plugins/py-ies_meta_r12/py-ies-meta-loader.pyp

+9-3
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,23 @@ class IESMetaLoader(c4d.plugins.SceneLoaderData):
7777
"""IESMeta Loader"""
7878
dialog = None
7979

80-
def Init(self, node):
80+
def Init(self, node, isCloneInit=False):
8181
"""
8282
Called when a new instance of this object is created. In this context, this allow to define
8383
the option by default for the SceneLoaderPlugin that will be displayed to the user.
84-
84+
85+
Args:
86+
node (c4d.GeListNode): The instance of the SceneLoaderData.
87+
isCloneInit (bool): True if the scene loader data is a copy of another one.
88+
8589
Returns:
8690
bool: False if there was an error, otherwise True.
8791
"""
8892
# Define the default value for the parameters.
8993
self.InitAttr(node, bool, IES_IMPORT_PRINT_TO_CONSOLE)
90-
node[IES_IMPORT_PRINT_TO_CONSOLE] = True
94+
95+
if not isCloneInit:
96+
node[IES_IMPORT_PRINT_TO_CONSOLE] = True
9197
return True
9298

9399
def Identify(self, node, name, probe, size):

plugins/py-look_at_camera_r13/py-look_at_camera_r13.pyp

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ PLUGIN_ID = 1028284
2020
class LookAtCamera(c4d.plugins.TagData):
2121
"""Look at Camera"""
2222

23-
def Init(self, node):
23+
def Init(self, node, isCloneInit=False):
2424
"""Called when Cinema 4D Initialize the TagData (used to define, default values).
2525
2626
Args:
2727
node (c4d.GeListNode): The instance of the TagData.
28+
isCloneInit (bool): True if the tag data is a copy of another one.
2829
2930
Returns:
3031
True on success, otherwise False.

plugins/py-osffset_y_spline_r16/py-osffset_y_spline_r16.pyp

+12-2
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,22 @@ class OffsetYSpline(c4d.plugins.ObjectData):
172172
_childContourDirty = 0 # type: int
173173
_childGVODirty = -1 # type: int
174174

175-
def Init(self, op):
175+
def Init(self, op, isCloneInit=False):
176+
"""Called when Cinema 4D Initialize the ObjectData (used to define, default values).
177+
178+
Args:
179+
op: (c4d.GeListNode): The instance of the ObjectData.
180+
isCloneInit (bool): True if the object data is a copy of another one.
181+
182+
Returns:
183+
bool: True on success, otherwise False.
184+
"""
176185
if op is None:
177186
raise RuntimeError("Failed to retrieve op.")
178187

179188
self.InitAttr(op, float, [c4d.PY_OFFSETYSPLINE_OFFSET])
180-
op[c4d.PY_OFFSETYSPLINE_OFFSET] = 100.0
189+
if not isCloneInit:
190+
op[c4d.PY_OFFSETYSPLINE_OFFSET] = 100.0
181191

182192
# Defines members variable to store the dirty state of Children Spline
183193
self._childContourDirty = 0

plugins/py-preference_r19/py-preference_r19.pyp

+2-1
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,12 @@ class PreferenceHelper(object):
101101

102102
class Preference(c4d.plugins.PreferenceData, PreferenceHelper):
103103

104-
def Init(self, node):
104+
def Init(self, node, isCloneInit=False):
105105
"""Called by Cinema 4D on the initialization of the PreferenceData, the place to define the type of object.
106106
107107
Args:
108108
node (c4d.GeListNode): The instance of the PreferenceData.
109+
isCloneInit (bool): True if the preference data is a copy of another one.
109110
110111
Returns:
111112
True if the initialization success, otherwise False will not create the object.

plugins/py-rounded_tube_r13/py-rounded_tube_r13.pyp

+11-9
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,12 @@ class RoundedTube(c4d.plugins.ObjectData, RoundedTubeHelper):
150150
super(RoundedTube, self).__init__(*args)
151151
self.SetOptimizeCache(True)
152152

153-
def Init(self, op):
153+
def Init(self, op, isCloneInit=False):
154154
"""Called when Cinema 4D Initialize the ObjectData (used to define, default values).
155155
156156
Args:
157157
op: (c4d.GeListNode): The instance of the ObjectData.
158+
isCloneInit (bool): True if the object data is a copy of another one.
158159
159160
Returns:
160161
bool: True on success, otherwise False.
@@ -168,14 +169,15 @@ class RoundedTube(c4d.plugins.ObjectData, RoundedTubeHelper):
168169
self.InitAttr(op, int, c4d.PY_TUBEOBJECT_SEG)
169170
self.InitAttr(op, int, c4d.PRIM_AXIS)
170171

171-
op[c4d.PY_TUBEOBJECT_RAD] = 200.0
172-
op[c4d.PY_TUBEOBJECT_IRADX] = 50.0
173-
op[c4d.PY_TUBEOBJECT_IRADY] = 50.0
174-
op[c4d.PY_TUBEOBJECT_SUB] = 1
175-
op[c4d.PY_TUBEOBJECT_ROUNDSUB] = 8
176-
op[c4d.PY_TUBEOBJECT_ROUNDRAD] = 10.0
177-
op[c4d.PY_TUBEOBJECT_SEG] = 36
178-
op[c4d.PRIM_AXIS] = c4d.PRIM_AXIS_YP
172+
if not isCloneInit:
173+
op[c4d.PY_TUBEOBJECT_RAD] = 200.0
174+
op[c4d.PY_TUBEOBJECT_IRADX] = 50.0
175+
op[c4d.PY_TUBEOBJECT_IRADY] = 50.0
176+
op[c4d.PY_TUBEOBJECT_SUB] = 1
177+
op[c4d.PY_TUBEOBJECT_ROUNDSUB] = 8
178+
op[c4d.PY_TUBEOBJECT_ROUNDRAD] = 10.0
179+
op[c4d.PY_TUBEOBJECT_SEG] = 36
180+
op[c4d.PRIM_AXIS] = c4d.PRIM_AXIS_YP
179181
return True
180182

181183
def GetDimension(self, op, mp, rad):

plugins/py-sculpt_modifier_deformer_r16/sculpt_modifier_deformer_r16.pyp

+10-8
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ class SculptModifierDeformer(c4d.plugins.ObjectData):
3131
def __init__(self):
3232
self.brushInterface = None
3333

34-
def Init(self, node):
34+
def Init(self, node, isCloneInit=False):
3535
"""Called when Cinema 4D Initialize the ObjectData (used to define, default values).
3636
3737
Args:
3838
node (c4d.GeListNode): The instance of the ObjectData.
39+
isCloneInit (bool): True if the object data is a copy of another one.
3940
4041
Returns:
4142
True on success, otherwise False.
@@ -48,13 +49,14 @@ class SculptModifierDeformer(c4d.plugins.ObjectData):
4849
self.InitAttr(node, int, c4d.PYSCULPTMODIFIERDEFORMER_SEED)
4950
self.InitAttr(node, float, c4d.PYSCULPTMODIFIERDEFORMER_STAMP_ROTATION)
5051

51-
node[c4d.PYSCULPTMODIFIERDEFORMER_RADIUS] = 20
52-
node[c4d.PYSCULPTMODIFIERDEFORMER_PRESSURE] = 0.2
53-
node[c4d.PYSCULPTMODIFIERDEFORMER_STAMP_ACTIVE] = False
54-
node[c4d.PYSCULPTMODIFIERDEFORMER_NUMSTAMPS] = 10
55-
node[c4d.PYSCULPTMODIFIERDEFORMER_STAMP_USEFALLOFF] = True
56-
node[c4d.PYSCULPTMODIFIERDEFORMER_SEED] = 0
57-
node[c4d.PYSCULPTMODIFIERDEFORMER_STAMP_ROTATION] = 0
52+
if not isCloneInit:
53+
node[c4d.PYSCULPTMODIFIERDEFORMER_RADIUS] = 20
54+
node[c4d.PYSCULPTMODIFIERDEFORMER_PRESSURE] = 0.2
55+
node[c4d.PYSCULPTMODIFIERDEFORMER_STAMP_ACTIVE] = False
56+
node[c4d.PYSCULPTMODIFIERDEFORMER_NUMSTAMPS] = 10
57+
node[c4d.PYSCULPTMODIFIERDEFORMER_STAMP_USEFALLOFF] = True
58+
node[c4d.PYSCULPTMODIFIERDEFORMER_SEED] = 0
59+
node[c4d.PYSCULPTMODIFIERDEFORMER_STAMP_ROTATION] = 0
5860

5961
self.brushInterface = c4d.modules.sculpting.SculptModifierInterface()
6062

plugins/py-spherify_modifier_r13/py-spherify_modifier_r13.pyp

+5-3
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,22 @@ class SpherifyModifier(c4d.plugins.ObjectData):
3838
self.falloff = None
3939
self.falloffDirty = True
4040

41-
def Init(self, op):
41+
def Init(self, op, isCloneInit=False):
4242
"""Called when Cinema 4D Initialize the ObjectData (used to define, default values).
4343
4444
Args:
4545
op: (c4d.GeListNode): The instance of the ObjectData.
46+
isCloneInit (bool): True if the object data is a copy of another one.
4647
4748
Returns:
4849
True on success, otherwise False.
4950
"""
5051
self.InitAttr(op, float, c4d.PYSPHERIFYMODIFIER_RADIUS)
5152
self.InitAttr(op, float, c4d.PYSPHERIFYMODIFIER_STRENGTH)
5253

53-
op[c4d.PYSPHERIFYMODIFIER_RADIUS] = 200.0
54-
op[c4d.PYSPHERIFYMODIFIER_STRENGTH] = 0.5
54+
if not isCloneInit:
55+
op[c4d.PYSPHERIFYMODIFIER_RADIUS] = 200.0
56+
op[c4d.PYSPHERIFYMODIFIER_STRENGTH] = 0.5
5557

5658
# Assigns falloff
5759
if self.falloff is None and c4d.API_VERSION > 19000:

scripts/03_application_development/files_media/import_obj_r13.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def main():
3737
raise RuntimeError("Failed to retrieve BaseContainer private data.")
3838

3939
# Defines the settings
40-
objImport[c4d.OBJIMPORTOPTIONS_PHONG_ANGLE_DEFAULT] = 22.5
40+
objImport[c4d.OBJIMPORTOPTIONS_PHONG_ANGLE_DEFAULT] = c4d.utils.DegToRad(22.5)
4141
if c4d.GetC4DVersion() > 22600:
4242
objImport[c4d.OBJIMPORTOPTIONS_IMPORT_UVS] = c4d.OBJIMPORTOPTIONS_UV_ORIGINAL
4343
else:

0 commit comments

Comments
 (0)