Best posts made by pyr
-
RE: Negative Vertex Map values
hey,
found the error. works exactly as i had planned. my code was correct, but i forgot to switch off use fields on the new vertex i mapped.
thanks for the help anyway!
-
RE: Close any C4D Window
can't test it right now, but this should do the trick.
you'll need to install these packages to your c4d installation to make it work
import win32gui import win32ui import win32co from pynput.keyboard import Key, Controller handle = win32gui.FindWindow(0, "Texture Manager") try: if handle: keyboard = Controller() win32gui.SetForegroundWindow(handle) keyboard.press(Key.ctrl) keyboard.press(w) keyboard.release(Key.ctrl) keyboard.press(w) except: pass
-
RE: Python Generator: Getting polygon data from new generators
The default python generator returns a parametric object (c4d.Ocube). So you have to convert it to a editable poly in the generator itself. So you don't need a cso in your script but in the generator when using parametric objects.
Python Generator
import c4d #Welcome to the world of Python def main(): c = c4d.BaseObject(c4d.Ocube) return c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_CURRENTSTATETOOBJECT,list = [c], bc = c4d.BaseContainer(), mode = c4d.MODELINGCOMMANDMODE_ALL, doc = doc, flags = 0)[0]
script
import c4d doc = c4d.documents.GetActiveDocument() gen =doc.GetActiveObject() print gen.GetCache()
-
RE: How to remove generator childs when converting via "c"
forget about it. i removed the c4d.OBJECT_INPUT flag during development and forgot to add it back.
-
RE: Polygon Islands Convenience Method?
this script breaks an poly object into island, colorized it by random, offset to center of bounding box and some noise. after that i connects all islands again.
its super fast compared to my older "solution"
import c4d from c4d import gui import random def AddVertexColor(s,center,rad): cnt = s.GetPointCount() tag = c4d.VariableTag(c4d.Tvertexcolor, cnt) data = tag.GetDataAddressW() bs = s.GetPointS() bs.SelectAll(cnt) done = [] points = s.GetAllPoints() r = random.random() for i in range(cnt): g = (points[0]-center).GetLength() / rad b = c4d.utils.noise.Noise(points[0]*0.01,rad) c = c4d.Vector(r,g,b) c4d.VertexColorTag.SetColor(data, None, None, i, c) s.InsertTag(tag) def main(): random.seed(666) selection = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE) for s in selection: center = s.GetMp() rad = s.GetRad().GetLength() c4d.CallCommand(12298) c4d.CallCommand(17891) mesh = s.GetDown() while mesh: AddVertexColor(mesh,center,rad) mesh = mesh.GetNext() c4d.CallCommand(100004768) c4d.CallCommand(16768) # Execute main() if __name__=='__main__': main()
Latest posts made by pyr
-
RE: Setting Preferences via script
After digging through some older threads and testing things, I found that this approach works — based on the discussion here:
https://developers.maxon.net/forum/topic/13555/python-how-to-get-axis-scale-from-the-preference-settings/2import c4d doc: c4d.documents.BaseDocument # The currently active document. op: c4d.BaseObject | None # The primary selected object in `doc`. Can be `None`. def main() -> None: # get preferences pref = c4d.plugins.FindPlugin(465001632) # Memory ((465001628, 1, 465001632), (888, 133, 465001632)) desc = c4d.DescID( c4d.DescLevel(465001628, 1, 465001632), c4d.DescLevel(888, 133, 465001632) ) memoryPref = pref[desc] memoryPref[c4d.PREF_MEMORY_PVHARDFOLDER] = "c:\\blubb" c4d.EventAdd() if __name__ == '__main__': main()
To discover all available IDs inside a preference node, you can list them like this:
for bc, descid, _ in pref.GetDescription(0): name = bc[c4d.DESC_NAME] print(name,descid)
So this topic is solved
-
Setting Preferences via script
Hey everyone,
I’m trying to roll out a few default preference settings across all company workstations, but I can’t find any solid reference or example on how to do it properly through Python.
Basically, I’d like to change things like:
- some Memory settings (Picture Viewer cache, etc.)
- a few File options (Autosave paths and intervals)
- certain Redshift preferences
- and enable the Verify Script check
My goal is to make sure every workstation starts with the same defaults, ideally via a startup script or a deployed config.
Unfortunately, I haven’t found any working example in the documentation or SDK that shows how to access and write these preferences in C4D 2025 / 2026
Does anyone have a current example or best practice for setting preferences programmatically in recent C4D versions?
Thanks a lot!
— Tobias -
RE: save/keep cache of generator plugin
Could you provide an snipped where you show how to cache it in a plugin?
-
How to create a Track on a Vector Userdata?
I have a Python Tag that loads on button press a json with some animation data. Position / Rotation working fine but i still haven't figured out how to create a track on a userdata with the type vector. i think i'm missing the desc ids or something like that
def CreateOrUpdateKey(curve, time, value, interpolation): keyDict = curve.FindKey(time) if keyDict: key = keyDict["key"] key.SetValue(curve, value) key.SetInterpolation(curve, interpolation) else: keyDict = curve.AddKey(time) if not keyDict: raise MemoryError("Failed to create key") key = keyDict["key"] index = keyDict["nidx"] key.SetValue(curve, value) curve.SetKeyDefault(doc, index) key.SetInterpolation(curve, interpolation) def LoadJsonToTracks(obj, path): if not os.path.isfile(path): raise FileNotFoundError(f"JSON file not found: {path}") with open(path, "r") as f: rawData = json.load(f) fps = doc.GetFps() interpolation = c4d.CINTERPOLATION_LINEAR # --- POSITION TRACKS --- pos_curves = [] for axis in [c4d.VECTOR_X, c4d.VECTOR_Y, c4d.VECTOR_Z]: descID = c4d.DescID( c4d.DescLevel(c4d.ID_BASEOBJECT_REL_POSITION, c4d.DTYPE_VECTOR, 0), c4d.DescLevel(axis, c4d.DTYPE_REAL, 0) ) track = obj.FindCTrack(descID) if not track: track = c4d.CTrack(obj, descID) obj.InsertTrackSorted(track) curve = track.GetCurve() curve.FlushKeys() pos_curves.append(curve) # --- ROTATION TRACKS --- rot_curves = [] for axis in [c4d.VECTOR_X, c4d.VECTOR_Y, c4d.VECTOR_Z]: descID = c4d.DescID( c4d.DescLevel(c4d.ID_BASEOBJECT_REL_ROTATION, c4d.DTYPE_VECTOR, 0), c4d.DescLevel(axis, c4d.DTYPE_REAL, 0) ) track = obj.FindCTrack(descID) if not track: track = c4d.CTrack(obj, descID) obj.InsertTrackSorted(track) curve = track.GetCurve() curve.FlushKeys() rot_curves.append(curve) # --- Add keyframes from JSON --- for entry in rawData: frame = entry.get("frame") pos = entry.get("position", [0, 0, 0]) rot = entry.get("rotation", [0, 0, 0]) if frame is None or len(pos) != 3 or len(rot) != 3: continue time = c4d.BaseTime(frame, fps) for i in range(3): CreateOrUpdateKey(pos_curves[i], time, pos[i], interpolation) CreateOrUpdateKey(rot_curves[i], time, rot[i], interpolation)
-
RE: save/keep cache of generator plugin
I would also be interested.
I cache all kinds of things, but not the mesh at the end.
# check if any dependency changed def CacheCheck(self, op, doc): """ :param op: :param doc: :return: """ if op[res.GRIDDER_CACHE] is not None: preOption = op[res.GRIDDER_CACHE].GetString(1001) preNoise = op[res.GRIDDER_CACHE].GetFloat(1002) preField = op[res.GRIDDER_CACHE].GetFloat(1003) preFrame = op[res.GRIDDER_CACHE].GetFloat(1004) rd = doc.GetActiveRenderData() self.rs.SetStartFrame(rd[c4d.RDATA_FRAMEFROM].GetFrame(doc.GetFps())) force = op[res.GRIDDER_EVERYFRAME] frame = doc.GetTime().GetFrame(doc.GetFps()) noise, shaderAnimated = self.CacheShader(op, doc) if force is 1 and preFrame != frame: return False if preOption != self.HelperGetOptions(op): return False if preNoise != noise: return False field = self.CacheField(op, doc) if preField != field: return False return True return False #----------------------------------------------------------------- # after everything is calculated: bc = c4d.BaseContainer() bc.SetData(1001, self.HelperGetOptions(op)) bc.SetData(1002, self.CacheShader(op, doc)[0]) bc.SetData(1003, self.CacheField(op, doc)) if doc != None: bc.SetData(1004, frame) op[res.GRIDDER_CACHE] = bc
-
RE: How to check if document is rendering?
Hey sorry for gravedigging.
i have the problem that my tag plugin recognises the difference between rendering and not rendering. unfortunately it also always changes the state in the doc itself and not only in the doc that is rendered
-
RE: Negative Vertex Map values
hey,
found the error. works exactly as i had planned. my code was correct, but i forgot to switch off use fields on the new vertex i mapped.
thanks for the help anyway!
-
Negative Vertex Map values
i use a vertext map to manipulate the motion blur in redshift from an object. positive directions are no problem, but the vertext map only seems to store positive values. manipulating it afterwards via python script didn't help either.
which surprises me in particular because the documentation mentions a float as the data type.
in other tools it is easily possible to use negative float values to create the desired effect.
-
RE: Polygon Islands Convenience Method?
this script breaks an poly object into island, colorized it by random, offset to center of bounding box and some noise. after that i connects all islands again.
its super fast compared to my older "solution"
import c4d from c4d import gui import random def AddVertexColor(s,center,rad): cnt = s.GetPointCount() tag = c4d.VariableTag(c4d.Tvertexcolor, cnt) data = tag.GetDataAddressW() bs = s.GetPointS() bs.SelectAll(cnt) done = [] points = s.GetAllPoints() r = random.random() for i in range(cnt): g = (points[0]-center).GetLength() / rad b = c4d.utils.noise.Noise(points[0]*0.01,rad) c = c4d.Vector(r,g,b) c4d.VertexColorTag.SetColor(data, None, None, i, c) s.InsertTag(tag) def main(): random.seed(666) selection = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE) for s in selection: center = s.GetMp() rad = s.GetRad().GetLength() c4d.CallCommand(12298) c4d.CallCommand(17891) mesh = s.GetDown() while mesh: AddVertexColor(mesh,center,rad) mesh = mesh.GetNext() c4d.CallCommand(100004768) c4d.CallCommand(16768) # Execute main() if __name__=='__main__': main()