@ferdinand Cinema 4D 2025 requires at least macOS 13.6+ (Ventura), but Xcode 13.4 requires macOS Monterey 12
Posts made by mikeudin
-
RE: 2025.0.0 SDK Release
-
RE: 2025.0.0 SDK Release
What XCode version is required to compile plugins for v2025?
-
RE: Copy info from one Object to other Object
@Manuel said in Copy info from one Object to other Object:
This is a python bug; it works as expected when using c++.
I will open a bug report and we will try to fix the issue as soon as possible.Still having this bug on 2024.4
-
RE: Python equivalent of the Xpresso node "Get nearest point on spline"?
Hi @ops !
Take a look to my version of @ferdinands solution. I was made some fixes to the code. Hope you find it usefull.
find_close_point_on_spline.c4d -
RE: 2024.4 update makes CheckDirty error for ObjectData plugin Fieldlist
It would have been better if you have included line numbers in your stack trace, as without them I have to guess...
Error messages going not in traceback format
Here is a sample plugin with same issue.
odatafieldsexample.zip
-
2024.4 update makes CheckDirty error for ObjectData plugin Fieldlist
Hello there!
After updating to Cinema 4D 2024.4 my plugin causes this Exception:ReferenceError: the object 'c4d.modules.mograph.FieldLayer' is not alive The above exception was the direct cause of the following exception: SystemError: <function VTexterData.CheckDirty at 0x4b3546450> returned a result with an exception set
It happens after adding some fieldlayer to the Field List. What is problem it can be?
Here is my CheckDirty func:def get_field_layers(op): """ Returns all field layers that are referenced in a field list. Source: https://plugincafe.maxon.net/topic/11809/iterating-trough-field-list/2?_=1678357010902 """ def flatten_tree(node): """ Listifies a GeListNode tree. """ r = [] while node: r.append(node) for child in node.GetChildren(): r += flatten_tree(child) mask = node.GetMaskHead() if mask: for child in mask.GetChildren(): r += flatten_tree(child) node = node.GetNext() return r # get the GeListHead for the FieldList root = op.GetLayersRoot() if root is None: return [] # Get the first node under the GeListHead first = root.GetFirst() if first is None: return [] # traverse the graph return flatten_tree(first) def CheckDirty(self, op, doc): fdirty = 0 desc = op.GetDescription(c4d.DESCFLAGS_DESC_NONE) bc = desc.GetParameterI(c4d.VFTAG_TEXT_ANIMATOR_TRANSFORM, None) if not bc: return fenabled = [t[c4d.VFTAG_TEXT_ANIMATOR_ENABLE] for t in op.GetTags() if t.CheckType(c4d.Tvfanimatortag)] get_tvalue = lambda i: fenabled[i] if i < len(fenabled) else False #get correct value in case if tags count != axes count tfields = [op[c4d.VFTAG_TEXT_ANIMATOR_FIELDS + i] for i in range(len(bc[c4d.DESC_CYCLE])) if get_tvalue(i)] if not tfields: return for f in tfields: if not f or not f.HasContent(): continue fdirty += f.GetDirty(doc) for l in get_field_layers(f): if not l.IsAlive(): continue if l.GetTypeName() in ('Time','Decay','Delay') and l.GetStrength() > 0.0: fdirty += doc.GetTime().GetFrame(doc.GetFps()) continue fdirty += l.GetDirty(c4d.DIRTYFLAGS_ALL) lobject = l.GetLinkedObject(doc) if lobject: fdirty += lobject.GetDirty(c4d.DIRTYFLAGS_MATRIX | c4d.DIRTYFLAGS_DATA | c4d.DIRTYFLAGS_DESCRIPTION) fdirty += op.GetDirty(c4d.DIRTYFLAGS_MATRIX) if fdirty != self.lastFieldsDirty: self.lastFieldsDirty = fdirty op.SetDirty(c4d.DIRTYFLAGS_DATA)
-
RE: Memory Leak? How to fix loosing memory with python generator?
@Dunhou You must use text shaping library to get glyphs outlines and convert it to bezier curves.
-
Memory Leak? How to fix loosing memory with python generator?
Hello guys!
I using this nice appoach to convert eps text data to spline using AI (Adobe Illustrator) importer. But it seems there is some memory leak because the amount of memory increases every time. How it can be fixed?
Here is a test file. Thank you!
gen_eps2.c4d -
RE: How to use ctypes library with Object Plugin properly?
@ferdinand Thank very much! i'll check what can i do.
-
How to use ctypes library with Object Plugin properly?
Hello guys!
I need to connect an C lang written lib to make some calculation during getting spline object. Here is a raw example with some details in a comments. Important part: cache created inside lib object. It must be existing during livetime of the Object and free before removing. What is best way to implement this approach? Thx!from ctypes import * class MyPluginData(c4d.plugins.ObjectData): """SomeObject Generator""" self.Init(node, isCloneInit): # It must be called once on object creation and can't be rewritten lib = CDLL('my_lib.so') #or dll on Windows self.Free(node): """ If your class has a destructor it is called as usual after this function. """ # It must be called on system sleep, app close, object deletion etc. # to avoid memory leaks lib.cleanup() self.GetContour(op, doc, lod, bt): """ Here we using lib by calling some lib.foo() and lib.bar()""" # During the execution lib object creates some cache that must be cleaned up after object destruction data = lib.foo() # process data return some_spline
-
How to LoadDocument from string in memory? 🤔
I have a Adobe Illustrator file contents generated by code not saved in a disk. Now i need to import it into Cinema 4D as a document. Is it possible open in Cinema 4D data not from file but from memory?
Found some SDK examples here but have no idea how to save text data to c4d.storage.MemoryFileStruct correctly to open it with LoadDocument after that.
Here is my .ai file code example:%!PS-Adobe-3.0 %%BoundingBox: 0 0 330 700 %%Pages: 1 %%EndComments 0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit [] 0 setdash %%EndProlog %%Page: 1 1 newpath 81 387 m 80 384 80 382 81 381 c 82 379 84 379 88 379 c 151 379 l 154 379 156 379 157 381 c 158 382 158 384 158 387 c 151 635 l 151 637 150 639 149 640 c 148 641 146 642 144 642 c 95 642 l 92 642 90 641 89 640 c 88 639 88 637 88 635 c 81 387 l 177 0 m 171 0 169 2 169 7 c 161 314 l 160 318 157 321 153 321 c 86 321 l 81 321 79 318 79 314 c 70 7 l 70 2 67 0 62 0 c 17 0 l 14 0 12 0 11 2 c 10 3 10 5 10 8 c 27 615 l 27 645 34 666 48 680 c 62 693 84 700 114 700 c 125 700 l 155 700 176 693 190 680 c 204 666 211 645 212 615 c 229 8 l 229 5 228 3 227 2 c 226 0 224 0 222 0 c 177 0 l closepath stroke %%Trailer
Thx!
-
How it works new CalcGradientPixel?
Hello guys!
Here is my old versions Python Node code that was working perfectly before v2024:import c4d def main(): global Color,Alpha,AlphaGradient Color = Alpha = c4d.Vector() AlphaGradient = Gradient.GetAlphaGradient() irs = c4d.modules.render.InitRenderStruct() if Gradient.InitRender(irs): Color = Gradient.CalcGradientPixel(Position) Gradient.FreeRender() if AlphaGradient and AlphaGradient.InitRender(irs): Alpha = AlphaGradient.CalcGradientPixel(Position) AlphaGradient.FreeRender()
Now following a new API changes this code:
import c4d def main(): global Color,Alpha,AlphaGradient Color = Alpha = c4d.Vector() AlphaGradient = Gradient.GetAlphaGradient() irs = c4d.modules.render.InitRenderStruct() if Gradient: Color = Gradient.PrepareRenderData(irs).CalcGradientPixel(Position) if AlphaGradient: Alpha = AlphaGradient.PrepareRenderDataWithAlpha(irs).CalcGradientPixel(Position)
Traceback (most recent call last): File "Gradient", line 14, in main Exception: no converter found for 'net.maxon.interface.gradientrenderdata-C'
How it works a new Gradient now?
-
RE: 2024 NodeData Init isCloneInit argument for older version
@baca Thank you! Works like a charm!
-
2024 NodeData Init isCloneInit argument for older version
Hello!
In R2024 for NodeData plugins Init method now requires isCloneInit argument. But now, after code changing, older versions gives an error:TypeError: Init() takes exactly 3 arguments (2 given)
Is there a way to make this new code feature compatible with older Cinema 4D versions? Now I have to create two pypv files: up_to_2024.pypv and 2024_and_after.pypv. Which is not convinient for developement obviously.
Thank you! -
Colorchooser in 2024
Trying to test in R2024 this SDK example from Github gets error:
Traceback (most recent call last): File "scriptmanager", line 60, in <module> File "scriptmanager", line 46, in main TypeError: argument 1 must be c4d.Vector4d, not ColorA64
Seems that datatype was changed but with no log in changelist and colorchooser API documentation.
-
MessageDialog in NodeData plugin
Hello guys!
I’m working on a plugin which there may be exceptions and there is a need to notify the user. As I understand from this information, gui message windows cannot be shown because of threading issues. But you can use Messages. As shown here and here. So the question is: how do I make this correct when using the GetContour or GVO method with ObjectData plugin? There is a proper way to "trigger Messages method" inside the GVO? I now is it possible to use c4d.MSG_DESCRIPTION_POSTSETPARAMETER but in this case exceptions may occurs in different scenarios that not depends from plugin GUI.
Thank you!def GetContour(self, node, doc, lod, bt): # Checks if there is an active object if node is None: raise RuntimeError("node is None, should never happens, that means there is no generator.") try: spline = self.GenerateSpline(node, doc) except Exception as e: # Disable generator flag node[c4d.ID_BASEOBJECT_GENERATOR_FLAG] = False # Wrong way to show message ???? c4d.gui.MessageDialog(str(e)) # Return empty spline return c4d.BaseObject(c4d.Ospline) return spline
-
RE: How to apply new fixed FieldList securely
@ferdinand Thank for your response!
I finally decided to simple check fieldlist without editing it. I hope this is legal.def CheckFieldListHasContent(doc, fieldlist): if not fieldlist.HasContent(): return False for f in get_field_layers(fieldlist): if f.CheckType(c4d.FLfield) and not f.GetLinkedObject(doc): f.Remove() return fieldlist.HasContent()
-
How to apply new fixed FieldList securely
Re: Fieldlist HasContent() GetCount() bug workaround
Hello guys!
I think i've found the solution how to fix FieldsLists with "ghost" layers (without linked FieldObjects, deleted in OM). I want to apply it to fix my ObjectPlugin FieldLists but i do not know how to make it securely. Maybe after each object deletion in Cinema 4D scene? How to implement this? There better solution?
Here is a code that works for me:def get_field_layers(op): """ Returns all field layers that are referenced in a field list. Source: https://developers.maxon.net/forum/topic/11809/iterating-trough-field-list/2?_=1678357010902 """ def flatten_tree(node): """ Listifies a GeListNode tree. """ r = [] while node: r.append(node) for child in node.GetChildren(): r += flatten_tree(child) node = node.GetNext() return r # get the GeListHead for the FieldList root = op.GetLayersRoot() if root is None: return [] # Get the first node under the GeListHead first = root.GetFirst() if first is None: return [] # traverse the graph return flatten_tree(first) def CleanUpFieldListDeadLayers(doc, fieldlist): for f in get_field_layers(fieldlist): if f.CheckType(c4d.FLfield) and not f.GetLinkedObject(doc): f.Remove() return fieldlist def main(): fixed_fieldlist = CleanUpFieldListDeadLayers(doc,op[c4d.MYPLUGIN_FIELDLIST]) op[c4d.MYPLUGIN_FIELDLIST] = fixed_fieldlist if __name__ == '__main__': main()