• Actively Link Hair Guides to a Spline or Alembic?

    r25 python
    3
    0 Votes
    3 Posts
    659 Views
    B
    Hi @ferdinand Thanks for the response and heads up on the crashes. RE: you want to control hair guide vertices programmatically Yep yep you are right on this part. Basically, have a geometric hair animated and simulated for preview. But rendered on the actual hair object. This is the workflow for other DCC, and the more logical one. This way you separate the hair source and hair generation. It's easier to debug. Anyhow, for looking at your python example, this should get me by on my current use case. Thanks for your illustration as always! Will close thread now.
  • Copy Assets to new Location

    python
    3
    0 Votes
    3 Posts
    589 Views
    C
    Hi ferdinand, I am very sorry for my lack of reading the Guidelines properly. But still, very huge thanks to you for the explanation anyway. This already helped me. I will try things out and will probably come back here with some code.
  • Asset Browser: Add Watch Folder

    python
    4
    0 Votes
    4 Posts
    1k Views
    a_blockA
    Thanks, Ferdinand. I'll take a closer look as soon as I find the time.
  • Remove render sequence automatic numbering

    8
    0 Votes
    8 Posts
    2k Views
    L
    Hello @ferdinand Thanks a lot for the code above, I really appreciate your help. I changed a few things for match what I was looking for and now it's working perfectly. Thanks again!
  • Make Node Callbacks Optional?

    python
    3
    0 Votes
    3 Posts
    358 Views
    B
    @ferdinand Thanks as always for the explanation. The illustration code works for my use case. Will close now thread
  • How to Modify the Axis of a Point Object?

    python
    7
    0 Votes
    7 Posts
    3k Views
    ferdinandF
    Hey @delizade, The script works for anything that is a c4d.PointObject, i.e., editable polygon and spline objects. But not for generators, e.g., the Cube object or the Circle spline, as you cannot edit their points and therefore have no control over the placement of their "axis" in relation to their vertices. When you want to set the transform of any BaseObject, e.g., a PointObject, a generator, or a null object, you must simply set either its local or global matrix. But this will not keep vertices 'in place' as generators and a null object have no vertices one could edit, and the vertices of PointObject instances must be corrected manually to achieve the 'move the axis idea'. But you can of course just set the global or local matrix (a.k.a. transform) of a BaseObject. Find an example below. For more detailled information, I would recommend having a look at the Matrix Manual. Cheers, Ferdinand The result, the two cubes are not at the same location because combining two transforms is not commutative, i.e., the order matters. A * B is not always the same as B * A for matrices: [image: 1669892200687-8392f997-7526-4a6d-b00b-e020d7669c59-image.png] The code: """Demonstrates the basic concept of transformations as realized by Cinema 4D. """ import c4d def main() -> None: """Constructs two transforms and applies them in the global coordinate system to two cube objects. """ # Construct a transform that translates by 500 units on the y-axis and one that rotates by # 45° on the x-axis. move: c4d.Matrix = c4d.utils.MatrixMove(c4d.Vector(0, 500, 0)) rotate: c4d.Matrix = c4d.utils.MatrixRotX(c4d.utils.DegToRad(45)) # Combine both transforms into a singular one by multiplying them. Note that matrix # multiplication, combining transforms, is not commutative. I.e., the order matters opposed # to numbers; move * rotate is not the same as rotate * move. tMoveRotate: c4d.Matrix = move * rotate tRotateMove: c4d.Matrix = rotate * move # Allocate two cube objects. cubeMoveRotate: c4d.BaseObject = c4d.BaseObject(c4d.Ocube) cubeRotateMove: c4d.BaseObject = c4d.BaseObject(c4d.Ocube) if None in (cubeMoveRotate, cubeRotateMove): raise MemoryError("Could not allocate cube object.") # And set their global matrix, i.e., the absolute transform in the global coordinate system. cubeMoveRotate.SetMg(tMoveRotate) cubeRotateMove.SetMg(tRotateMove) # Name both null objects, set their display color, insert them into the active document, and # push an update event. cubeMoveRotate.SetName("Cube: Move -> Rotate") cubeRotateMove.SetName("Cube: Rotate -> Move") cubeMoveRotate[c4d.ID_BASEOBJECT_USECOLOR] = c4d.ID_BASEOBJECT_USECOLOR_ALWAYS cubeRotateMove[c4d.ID_BASEOBJECT_USECOLOR] = c4d.ID_BASEOBJECT_USECOLOR_ALWAYS cubeMoveRotate[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(1, 0, 0) cubeRotateMove[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(0, 0, 1) doc.InsertObject(cubeMoveRotate) doc.InsertObject(cubeRotateMove) c4d.EventAdd() if __name__ == '__main__': main()
  • Node Method IsValid() Throws ValueError

    python r25
    5
    0 Votes
    5 Posts
    496 Views
    B
    @m_adam Gotcha. Thanks for the heads up!
  • Drag and Drop from GeUserArea in Python

    python
    3
    0 Votes
    3 Posts
    846 Views
    a_blockA
    Hi Maxime, that's a bummer. Just a few additions: is done by calling HandleMouseDrag. Your code is paused until the drag operation ended Yes, no objection. But it should be said, during this "pause" one does still receive messages, among them BFM_DRAGRECEIVE_START and BFM_DRAGRECEIVE. Just not BFM_DRAGEND. Which makes me think, if only the receiver would not "consume" this message, it could already work... From a pure implementation point of view, it also does make sense since it would make no sense if each drag operation have to support all possible managers I wouldn't want it differently. But I still think, the initiator of an action deserves result information. after all these years, I'm still wondering, what's this obsession with not delivering feedback to a caller. Yes, I'm looking at you CallCommand()... Finally it is not possible to drag objects directly to the viewport I didn't even consider, drag and drop could work differently for materials and objects, or objects not working at all. So, thanks for the info and avoiding even more headache on my end. I guess, we are back to the drawing board then. Anyway, greetings to the team. Cheers, Andreas
  • Reset Rotate With Compensate Points?

    r25 python
    4
    0 Votes
    4 Posts
    910 Views
    B
    For some fortunate happpenstance, found a code snippet that does this: https://gist.github.com/andreberg/885210
  • Custom GUI Linkbox checking for Accepted types?

    r23 python
    3
    0 Votes
    3 Posts
    901 Views
    CairynC
    @ferdinand Thanks for the reply! Ah, of course, I should have considered that Command is actually the last message I get for that operation. This Message stuff totally got me on the wrong track. Naturally, resetting the link and thereby cancelling and reverting the user's drag or pick operation is not as nice as showing a "stop sign" mouse pointer during the operation. Since the ACCEPT clause in a Resource allows setting accepted types, I wonder why there is no API functionality allowing the same. It's not even in the C++ implementation. I suppose people should use external resources anyway, but seeing stuff in the API makes functionality clearer to me at least. Regarding PyCapsule, no, I didn't happen across that previously, I just took code from some other thread on this forum to get into the message. I was lazy and looked for PyCapsule in the Cinema 4D API doc, and assumed it undocumented when it wasn't found. Totally my fault, I should have checked the web too. Never program in an unfamiliar scope past midnight! Nice code btw.
  • Sample a shader in 3D space

    c++ classic api r21 r20
    16
    0 Votes
    16 Posts
    4k Views
    fwilleke80F
    Thanks, Paul! I'll try that out Cheers, Frank
  • MatrixToHPB Not Giving the Global Rotation?

    r25 python
    3
    1
    0 Votes
    3 Posts
    378 Views
    ferdinandF
    Hello @bentraje, thank you for reaching out to us. There is nothing much left to add for us here. All angle values are represented internally in radians in Cinema 4D, only the UI does convert to degrees. Except for displaying angle values in UIs, I would however recommend to embrace the unit of radians in code rather than converting in and out of it. There is no computional downside to always doing the conversions, e.g., theta: float = c4d.utils.DegToRad(90). But writing something like theta: float = math.pi * .5 forces oneself to understand the intimate relation between a trigangle and the unit circle, i.e., the circle or trigonometric functions. Understanding radians and why it is a useful unit is then an emergent property of that understanding of trigonometry. Cheers, Ferdinand
  • Load Save Weights Command from Weight Manager?

    r25 python
    3
    1
    0 Votes
    3 Posts
    458 Views
    B
    @manuel Gotcha. Thanks for the confirmation. Closing this thread now.
  • Swap Out Joint Axis Rotation?

    r25 python
    7
    0 Votes
    7 Posts
    655 Views
    B
    @manuel Interesting. Thanks for the heads up. It works now as expected. Closing the thread.
  • ReferenceError: the object 'c4d.Material' is not alive

    r25 python
    9
    0 Votes
    9 Posts
    2k Views
    B
    @ferdinand Thanks for the response. I'll get back to you on this just having some stuff in the pipeline that are more immediate. That said, I do want to confirm that your code is working from the get go. It's just my implemention of it in the GUI dialog. I'll just have to iron out the logic on that one.
  • Possible Bug when running in Commandline

    r21 python
    4
    0 Votes
    4 Posts
    1k Views
    FSSF
    LegionLib_Release.dll: Legion::Mutex::lock + 0xc (SP: 0x000000379A5FF720, PC: 0x00007FFA368CF13C) Corona4D.2023_Release.dll: forcePluginDelayLoad + 0x1229cd (SP: 0x000000379A5FF750, PC: 0x00007FFA39D91F6D) Corona4D.2023_Release.dll: forcePluginDelayLoad + 0x1232fd (SP: 0x000000379A5FF7A0, PC: 0x00007FFA39D9289D) Corona4D.2023_Release.dll: forcePluginDelayLoad + 0x139f47 (SP: 0x000000379A5FF7D0, PC: 0x00007FFA39DA94E7) LegionLib_Release.dll: Legion::LowSystemMemoryChecker::`default constructor closure' + 0x90 (SP: 0x000000379A5FF870, PC: 0x00007FFA368F1CA0) KERNEL32.DLL: BaseThreadInitThunk + 0x14 (SP: 0x000000379A5FF8C0, PC: 0x00007FFAD5C674B4) ntdll.dll: RtlUserThreadStart + 0x21 (SP: 0x000000379A5FF8F0, PC: 0x00007FFAD6EC26A1) Registers The counter part to the Mutex. Now looking into hot reloading the dll. If I dont return avenge me.
  • How to read a bugreport?

    r23 windows
    2
    0 Votes
    2 Posts
    2k Views
    ferdinandF
    Hello @fss, thank you for reaching out to us. I would first point out three things: We cannot help users with bugs caused by third party plugins or libraries. We cannot disclose how to read our crash reports in detail, both from a practical and willingness standpoint. I also have difficulties following what you are here talking about in all detail; it is just a little bit too much tech jargon for my librarian brain. Information about Cinema 4D Crash Reports The primary data provided by a crash report is the _BugReport.txt file. It contains a stack trace for the list of stack frames which led up to the exception/crash. Our traces are organized bottom-up, i.e., the first entry in the stack is the thing which led to the crash. Stack traces mostly make sense in an environment where you have also access to the source code (or debug symbols) of the binary you are debugging. You can debug against our SDK, or more specifically the frameworks contained in them, to get more meaningful stack traces when debugging, however: We cannot provide the full declarations of the Cinema 4D API (i.e., the private frameworks and core modules) or debug symbols for them. When you want to debug a binary that is not port of Cinema 4D, e.g., the Corona plugin binary, you will either need at least the declarations of entities (a.k.a. "frameworks") or the debug symbols for it. So, when a crash happens in our core, you will also not get too much useful information out of a debugger attached to the binary with the public frameworks included. Because they do not contain information about our core. In its serialized form a trace (a _BugReport.txt) does not provide too much useful information. // The stack trace container. CINEMA_4D_Crash_Report_WINDOWS { // The thread container in the trace. Call_Stacks { // The thread in which the exception did occur. Call_Stack_Thread_9180 { // The stack frame which caused the exception which led to the crash. Here it happened // in the binary which handles a CPython virtual machine for Cinema 4D. pythonvm.module.xdl64: Ordinal0 + 0x14ae32 (SP: 0x000000BD342F8850, PC: 0x00007FFADC16AE32) // The frame before that in the same binary. pythonvm.module.xdl64: Ordinal0 + 0x145db3 (SP: 0x000000BD342F8950, PC: 0x00007FFADC165DB3) // The call before that came from the CPython binary, it yields a bit more descriptive // information without a debugger attached, as we get here function names and not just some // memory offset to the binary. python39.dll: PyUnicode_InternInPlace + 0x461 (SP: 0x000000BD342F89B0, PC: 0x00007FFAD8221DDD) // ... } // A stack trace for another thread which has been executed. Call_Stack_Thread_BLAHBLAH { // ... } //... } } I do not really understand where you get your information from regarding logos, 'KernelLand', and the 'hexadress of the position in the dump that corresponds to the error number'. But without the source code or debug symbols you cannot make much sense of it. It could be that Corona is using a lot of Windows libraries, but in general, our code is very OS agnostic. So, it seems unlikely that you found a crash in a Windows binary. Cheers, Ferdinand
  • Tags vanishing when Object is made Editable

    2023 c++
    5
    0 Votes
    5 Posts
    712 Views
    ManuelM
    cool, so you can mark this thread as resolved ^^ Cheers, Manuel
  • creating children in generator

    7
    0 Votes
    7 Posts
    2k Views
    CJtheTigerC
    Hello @ferdinand, sorry for keeping quiet, I'm rather busy these days. I am aware of the OHIDE flag. But what if the user converts the object using Current State to Object? I wouldn't want invisible objects to stay in the document, the user should be in charge of handling them all once he takes this step. Just like when converting a Character object. So either I try to hook into the CStO command and remove the OHIDE bit from all objects or I keep using layers. Is there a reason to choose one over the other? Thanks again for all the help you and everyone involved provided! Best regards, Daniel
  • Crash when converting objects in bulk

    r23 python
    5
    0 Votes
    5 Posts
    1k Views
    ManuelM
    You can also filter your objects. Using GetInfo for example, you can check if the current object is a generator or not. If you make a generator editable, the generator will/should handle the children itself. The only exception are primitives. Primitives are generators but they do not care about their children. Cheers, Manuel