• 0 Votes
    2 Posts
    618 Views
    i_mazlovI
    Hello @Gregor-M , Welcome to the Plugin Café forum and the Cinema 4D development community, it is great to have you with us! Getting Started Before creating your next postings, we would recommend making yourself accustomed with our Forum and Support Guidelines, as they line out details about the Maxon SDK Group support procedures. Of special importance are: Support Procedures: Scope of Support: Lines out the things we will do and what we will not do. Support Procedures: Confidential Data: Most questions should be accompanied by code but code cannot always be shared publicly. This section explains how to share code confidentially with Maxon. Forum Structure and Features: Lines out how the forum works. Structure of a Question: Lines out how to ask a good technical question. It is not mandatory to follow this exactly, but you should follow the idea of keeping things short and mentioning your primary question in a clear manner. About your First Question What you're trying to achieve is supposed to be happening on the main thread. It's difficult to guess the reasons of the crash you're stumbling across without any further information (e.g. the code showcasing the issue), but could be that MTCharacterBodyPart.GetParameters() function is not a thread-safe one. Cheers, Ilia
  • Simulating mouse movement in C4D

    Cinema 4D SDK python r25 windows
    5
    0 Votes
    5 Posts
    3k Views
    D
    Hi @ferdinand, Thank you so much for the comprehensive reply! Given all this I don't think it would make sense to keep trying to unit test this particular part of our code with Python. The last approach you highlighted with testing directly on the C++ side seems like the best option, so I'll give that a try. I'll have to see how to integrate this test with the rest of the unit tests (we have a lot and they're all in Python) but hopefully that won't be too much of a problem. Thanks again for all the help, Daniel
  • 0 Votes
    3 Posts
    847 Views
    G
    I see, thanks. But honestly i don't get it why the plugins folder isn't in the search path...
  • Howto to pass arguments to a python script

    Cinema 4D SDK python windows
    4
    0 Votes
    4 Posts
    704 Views
    ferdinandF
    Hey @Gaal-Dornik, In Cinema 4D you can bind a command to multiple shortcuts, but adding arguments is not possible. You would have to poll the keyboard yourself to distinguish such events. Cheers, Ferdinand Result: [image: 1696252767040-49a4bee1-8135-412f-b238-43d21184e071-image-resized.png] Code: """Runs different code based on which keys are pressed. Must be run as a Script Manager script. Pressing Shift+ALT+A while the script is invoked will print "Foo", while pressing Ctrl+Alt+A will print "Bar". See: https://developers.maxon.net/docs/py/2024_0_0a/misc/inputevents.html """ import c4d def CheckKeyboardState(*args: tuple[str]) -> bool: """Returns #True when the given key sequence is pressed, #False otherwise. """ result = [] for char in (n.upper() for n in args if isinstance(n, str)): if char == "SHIFT": c = c4d.KEY_SHIFT elif char == "CTRL": c = c4d.KEY_CONTROL elif char == "ALT": c = c4d.KEY_ALT else: c = ord(char) bc = c4d.BaseContainer() if not c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD, c, bc): raise RuntimeError("Failed to poll the keyboard.") result += [True if bc[c4d.BFM_INPUT_VALUE] == 1 else False] return all(result) def main() -> None: """ """ if CheckKeyboardState("Shift", "Alt", "A"): print ("Foo") elif CheckKeyboardState("Ctrl", "Alt", "A"): print ("Bar") else: print("None") if __name__ == '__main__': main()
  • 0 Votes
    2 Posts
    896 Views
    ferdinandF
    Hello @BretBays, Thank you for reaching out to us. Your posting does not contain an explicit question; there is no question mark in it. There is an implied question of us implementing what you describe, but the MAXON SDK group cannot do that, implement feature descriptions provided by users. I would recommend having a look at our support guidelines regarding asking good technical questions and the scope of support. About your Question If you want to CTSO, just CTSO the object or join it, we have examples for both cases in the modeling commands section of the Python examples. The problem with your function is also that it makes quite a few assumptions which do not always hold true, it for example assumes that the deform cache of something is always found directly on an object in the object manager (which is only true for editable polygon objects). What the script is calling 'direct copy' might also lead to results the user does not consider to be a copy. CSTO is the way to go to 'duplicate that deformed shape to a simple mesh with no deformer'. If the output is then not a singular object, you can join the output or a subset of it. Cheers, Ferdinand
  • Import NumPy?

    Cinema 4D SDK python 2024
    4
    0 Votes
    4 Posts
    1k Views
    G
    Hi, I'm also trying to install numpy, but after registering c4dpy I'm getting a syntax error after running "c4dpy -m ensurepip" command. c4dpy -m ensurepip (null) File "<stdin>", line 1 c4dpy -m ensurepip ^^^^^^^^^ (null)SyntaxError: invalid syntax
  • 2024 c4d python doc link error

    Cinema 4D SDK python 2024
    4
    1
    1 Votes
    4 Posts
    892 Views
    chuanzhenC
    @ferdinand Great job!
  • 0 Votes
    5 Posts
    1k Views
    ThomasBT
    @ferdinand This is a command, and you can c4d.CallCommand it, but that is all the control you have. thank you Ferdiand,
  • New Child Render settings with python

    Cinema 4D SDK 2024 python
    6
    0 Votes
    6 Posts
    2k Views
    M
    Thank you @ferdinand, I'll need to work out how I implement but once again a thorough and considered reply....
  • c4d 2024 "MENURESOURCE_SEPERATOR"

    Cinema 4D SDK 2024 python
    5
    2
    0 Votes
    5 Posts
    1k Views
    chuanzhenC
    @ferdinand Thanks,hope to fix spelling in c4dpython doc in future versions
  • How to get OutLine of Polygon object

    Moved General Talk 2023 c++ python
    9
    1
    0 Votes
    9 Posts
    3k Views
    Paul EverettP
    you can test for all cases, that's why I call those edges "candidates". The devil is always in the details. There are many ways to skin this cat. best Paul
  • MergeDocument under a selected Null

    Cinema 4D SDK python
    2
    0 Votes
    2 Posts
    695 Views
    ferdinandF
    Hey @pyr, Thank you for reaching out to us. The sentence 'if i do the whole thing via obj.InsertUnder(null) i miss the material' is a bit ambiguous, how do you mean that? I assume you mean that when you load two documents A and B and then start copying objects over by either cloning them or removing them from A and inserting them into B, that you then miss material references. Because the call you show us will load both objects and materials found at f into doc. A straightforward way to do what you want to do, parent everything that has been imported to a null, is to track the state of the top-level objects before and after the import. The difference between the states then tells you what to move where. In practice, there are some technical hoops to jump through, primarily the problem that you might run into dead references when you try to store objects references over the import process. Cheers, Ferdinand Result: moomoo.mp4 Code: """Demonstrates how to parent the objects merged into a document to a null object. Must be run as a script manager script and will import the contents of #FILE into the active document. """ import c4d doc: c4d.documents.BaseDocument # The active document. FILE: str = r"file:///e:/test.c4d" # The document to import. def main() -> None: """ """ # Get the UUID markers of all top level objects. We get the markers and not the object # references because importing a document bears a good chance that these references will be # dead (C4DAtom.IsAlive() == False) when we access them again. uuidCollection: list[bytes] = [] op: c4d.BaseObject = doc.GetFirstObject() while op: uuidCollection.append(bytes(op.FindUniqueID(c4d.MAXON_CREATOR_ID))) op = op.GetNext() # Now we import our document. c4d.documents.MergeDocument(doc, FILE, c4d.SCENEFILTER_OBJECTS | c4d.SCENEFILTER_MATERIALS | c4d.SCENEFILTER_MERGESCENE) # We create our null object to parent the imported stuff to. We also add its UUID to # #uuidCollection, so that we do not attempt to parent #null to itself ;) null: c4d.BaseObject = c4d.BaseObject(c4d.Onull) null.SetName(FILE) doc.InsertObject(null) c4d.EventAdd() uuidCollection.append(bytes(null.FindUniqueID(c4d.MAXON_CREATOR_ID))) # Now we iterate again over all top level objects and parent everything that does not appear in # #uuidCollection to #null. op: c4d.BaseObject = doc.GetFirstObject() # We have to do this on two steps, because when we would already move #op in the first step # where we find the things to move, we would sabotage our own loop here (because as soon as # we move the first op to the null, op.GetNext() would be None). move: list[c4d.BaseObject] = [] while op: if bytes(op.FindUniqueID(c4d.MAXON_CREATOR_ID)) not in uuidCollection: move.append(op) op = op.GetNext() # Actually move the items. for op in move: op.InsertUnderLast(null) c4d.EventAdd() if __name__ == "__main__": main()
  • 0 Votes
    4 Posts
    1k Views
    S
    @ferdinand Just ran into the same problem. Thank you for the solution!
  • Can you get a list of missing plugins?

    Cinema 4D SDK python
    3
    1
    0 Votes
    3 Posts
    1k Views
    K
    Thanks for the fast response @ferdinand . Sorry that the title of my question is somewhat misleading. The thread that you've linked is actually quite detailed and useful I'll take a closer look into that.
  • 0 Votes
    6 Posts
    2k Views
    ferdinandF
    Hey @danielsian, Yes, a tree view could be another solution, another one could be a GeUserArea. I deliberately did not mention both options since they are more complex. Especially TreeViewFunctions, the underlying interface for tree views, tends to be overwhelming for newcomers. I would recommend the dynamic UI workflow hinted at above, as this will result in the least amount of code. But it will of course not be as beautiful as something truly custom. Cheers, Ferdinand
  • Gradient Interpolation Error in 2024 release

    Cinema 4D SDK python 2024
    3
    0 Votes
    3 Posts
    766 Views
    D
    @m_adam Brilliant! Thanks a lot!
  • Running Automatic UV for all objects

    Cinema 4D SDK python windows
    3
    1
    1 Votes
    3 Posts
    2k Views
    M
    Hi @BineeMan sorry for the late reply I was pretty busy Friday and thanks @Dunhou for demonstrating how Packed Auto UV work. For Cubic and Angle you need to use c4d.modules.bodypaint.CallUVComman as demonstrated in the call_uv_command_ example. So for the Angle automatic UV you need to use the command ID c4d.UVCOMMAND_OPTIMALMAPPING with the next parameters: c4d.OPTIMALMAPPING_PRESERVEORIENTATION # Preserve Orientation c4d.OPTIMALMAPPING_STRETCHTOFIT # Stretch to Fit c4d.OPTIMALMAPPING_DISTORTION # Maximu, Distortion c4d.OPTIMALMAPPING_RELAXCOUNT # Relaxation Steps c4d.OPTIMALMAPPING_SPACING # Spacing And for the Cubic automatic UV you need to use the command ID c4d.UVCOMMAND_OPTIMALCUBICMAPPING with the next parameters: c4d.OPTIMALMAPPING_PRESERVEORIENTATION # Preserve Orientation c4d.OPTIMALMAPPING_STRETCHTOFIT # Stretch to Fit c4d.OPTIMALMAPPING_TWOD # 2D c4d.OPTIMALMAPPING_AREAFAK # Maximum Area Factor c4d.OPTIMALMAPPING_RELAXCOUNT # Relaxation Steps c4d.OPTIMALMAPPING_SPACING # Spacing Cheers, Maxime.
  • Can't snap to Generator output spline

    Cinema 4D SDK r25 python windows
    4
    0 Votes
    4 Posts
    1k Views
    ferdinandF
    Hey @Madara, in short, a Python generator object is not meant to generate splines. You can collapse the cache of your constructed spline and return its LineObject cache instead of the spline itself. For an example, see [1]. In your case that would be connect_obj. This will work in the sense that the generator cache will be then like a SplineObject cache and when you 'Current State to Object' your generator, it will behave like a spline and give you the interpolated editable linear spline and not a spline generator. However, spline snapping not only inspects caches, but also checks if OBJECT_ISSPLINE is true. So, you cannot bamboozle it by faking a SplineObject cache. You will have to implement a proper spline plugin for what you want to do, as you can overwrite there GetContour Cheers, Ferdinand PS: Your code contains multiple elements that can crash Cinema 4D and/or corrupt the loaded document. Specifically, these sections: if link_clone: #Parametric object pobj = u.SendModelingCommand( command = c4d.MCOMMAND_CURRENTSTATETOOBJECT, list = [connect_obj], mode = c4d.MODELINGCOMMANDMODE_ALL, doc = op.GetMain()) connect_obj = pobj[0] ... offspline = u.SendModelingCommand( c4d.MCOMMAND_SPLINE_CREATEOUTLINE, [connect_obj], c4d.MODELINGCOMMANDMODE_ALL, bc=settings, doc=doc) A Python generator's main() function is subject to the threading restrictions of Cinema 4D because it is just a wrapper for ObjectData.GetVirtualObjects. Executing SendModelingCommand in a threaded context is fine, but you cannot do it on the active document (both doc and op.GetDocument() are the active document). This is here even worsened by the fact that that the objects in list are not actually part of the document you pass as doc. To circumvent that you must create your own document just as I have in [1] with temp. Find a more detailed example of that technique in smc_extrude_s26.py. [1] import c4d op: c4d.BaseObject # The Python generator object. def main() -> c4d.BaseObject: """ """ # A user data Boolean to toggle collapsing the cache of this generator. collapse: bool = op[c4d.ID_USERDATA, 1] spline: c4d.BaseObject = c4d.BaseObject(c4d.Osplinecircle) if not spline: return c4d.BaseObject(c4d.Onull) # Just return the circle spline itself when #collapse is false. if not collapse: return spline # Otherwise grab the LineObject cache of the spline and return a copy of it. temp: c4d.documents.BaseDocument = c4d.documents.BaseDocument() temp.InsertObject(spline) temp.ExecutePasses(c4d.threading.GeGetCurrentThread(), False, False, True, c4d.BUILDFLAGS_NONE) cache: c4d.LineObject | None = spline.GetCache() if not isinstance(cache, c4d.LineObject): return c4d.BaseObject(c4d.Onull) return cache.GetClone(c4d.COPYFLAGS_NONE)
  • GetDefaultValue Not Working in C4D 2024

    Cinema 4D SDK python
    3
    0 Votes
    3 Posts
    629 Views
    E
    @m_adam I'm looking forward to the next version update. Thank you for your response.
  • C4d Connector problem in 2024

    Cinema 4D SDK python
    6
    0 Votes
    6 Posts
    2k Views
    M
    Hi @filipst just to let you know that with the hotfix released yesterday(20/09/2023). The issue within Cinema 4D has been solved. In the same time make sure to use the latest version of the add-on in VsCode (v1.1.0). Cheers, Maxime.