• Natvis settings not working?

    windows c++
    5
    0 Votes
    5 Posts
    873 Views
    ferdinandF
    Hey @bojidar, well, we do not write these object views (the natvis for MSVC and the Python scripts for Xcode) for public usage but for internal usage. That we hand them out to third parties is just a courtesy. When we are looking at maxon::GraphNode, <Type Name="maxon::GraphNode"> <DisplayString Condition="_mem[0] != 0">{((maxon::NodePath*)&amp;_mem[0]),na}</DisplayString> <!-- Root will have empty path and valid graph --> <DisplayString Condition="_mem[0] == 0 &amp;&amp; _graph._object != 0">Root</DisplayString> <DisplayString Condition="_mem[0] == 0">nullptr</DisplayString> <Expand> <Item Name="Path">(((maxon::NodePath*)&amp;_mem[0])),na</Item> <Item Name="Kind" Condition="_mem[0] != 0 &amp;&amp; _graph._object != 0">(maxon::NODE_KIND)((((nodes.module.xdl64!maxon::nodes::NodePathImpl::CountAndKind*) &amp; (*(nodes.module.xdl64!maxon::nodes::NodePathImpl**) &amp; _mem[0])->_path))->kind &amp; 0xFF)</Item> <Item Name="Kind" Condition="_mem[0] == 0 &amp;&amp; _graph._object != 0">maxon::NODE_KIND::NONE</Item> <Item Name="Info">((nodes.module.xdl64!maxon::nodes::NodesGraphModelImpl::Info*)this->_mem),na</Item> <Item Name="Graph">(this->_graph)</Item> <Item Name="Graph Storage">(this->_mem)</Item> </Expand> </Type> then there are indeed quite a few references to the implementation (which means that this cannot work in the public API). You could rip these out to make it work, but would then be left with only a small subset of the debug attributes. But that would be up to you. In general, you can expect the Cinema API to be more conservative and almost all object views working there, while the Maxon API is generally more internal in nature. Cheers, Ferdinand
  • Bake animation in the background

    python
    2
    0 Votes
    2 Posts
    510 Views
    i_mazlovI
    Hi @brian-michael, I've forked your posting in a dedicated thread. For your following postings please stick to our guidelines, which you can find in the Support Procedures, namely: Singular Subject: From all this follows that a topic must have a singular and sparse subject tied to a specific problem especially when it comes to N-years-old threads Regarding your question, please share more context on what specifically you're trying to do, because depending on that you can end up in a completely different ways of approaching your goal. For example, if you'd like to bake animation in a "read-only manner" (just take the object transformations and store/send them somewhere), then the suggested approach would be to clone document and process it in a separate C4DThread. You can check Ferdinand's code example on the exact same topic in application to rendering document: RenderDocument/PythonCallBack : how to display progress prints during the render. However, with such approach you're limited to not being able to modify original document (because you'd use the cloned document instead of the active one). Cheers, Ilia
  • Detect error-causing nodes in XPresso

    python
    4
    1
    0 Votes
    4 Posts
    722 Views
    K
    Hi @i_mazlov , Unfortunately, the python node approach is not effective for my use case, so I may have to emulate the error conditions on my own for each node. In any case, thank you for your answer.
  • Vertex Map Tag not in sync error

    python 2024 windows
    3
    1
    0 Votes
    3 Posts
    606 Views
    D
    Hi Ilia, Thank you very much, I was not aware of that! Cheers!
  • Global static classes?

    c++
    4
    0 Votes
    4 Posts
    619 Views
    ferdinandF
    As I said, you will run into access violations when you instantiate your fields on the class instead of the Init function. And as I also said, in your concrete case it would probably even be fine if you would directly do it in the class scope. But I would advise against breaking this rule. There is nothing to optimize here, either return a new instance when this is only called once in a blue moon and you do not want to bother with initializing a field. Or define a field and initialize it up in NodeData::Init. And no, scene elements (NodeData) should not share data on their class. We have types in the Maxon API to deal with this when you really want some heavy data structure which shall be initialized exactly once, but that is total overkill in this case. Cheers, Ferdinand
  • Refresh viewport after updating RenderData width and height

    windows python
    8
    0 Votes
    8 Posts
    1k Views
    S
    Hello @ferdinand ! Thanks for answer it is very clear, i will use virtual resolution from now on
  • Correct OCIO Color Value Conversion via Python?

    windows python 2024
    3
    0 Votes
    3 Posts
    583 Views
    B
    Hey Ferdinand, Thank you for the quick response! Ah ok I see. Thank you for the provided information, I will have a look at it. But I can also wait for the moment. My work arround for now would be to simply set everything up / import the parameters and colors with color management set to 'Basic' and manually doing the conversion via 'Convert to OCIO' in the Project settings. Thats giving me the correct result. But thanks again! Cheers, Ben
  • Programing a Tabulated BRDF Node / Shader - possible ?

    2024
    6
    1
    0 Votes
    6 Posts
    977 Views
    ferdinandF
    Hey, Out of curiosity, I did some poking in Redshift, and what I forgot, is that you are in principle unable to escape the current shading context of a sample in Redshift. I.e., you cannot just say, "screw the current UV coordinate, please sample my texture 'there'" due to the closure thing which Redshift has going. With the Standard Renderer, you can do the following, which is pretty close. I compute the v (i.e., view angle coordinate) as described above. Standard also does not give you directly light ray angles, but you can get the light contribution where I use the diffuse component of the light(s) as a faksimile: High diffuse = high angle of incident/light contribution. [image: 1730128355045-82ee51e1-15a9-487b-8cb0-91eec633352e-image-resized.png] Fig. I: A crude iridescence setup in Standard. test.png is your texture from above, I forgot to take the inverse of values as 1 - x. view_angle.zip In Redshift you cannot do the same light contribution hack, and I currently do not see how you could set the sampling coordinate of the texture in the first place. Maybe the Redshift pro's know more. Cheers, Ferdinand
  • Hide Items (Object Plugin)

    2024 python
    3
    0 Votes
    3 Posts
    597 Views
    R
    @m_adam Thanks, I await your info. Have a nice weekend
  • Get MODATA_SIZE of Mograph Particles to Build Stacks of Geometry

    python sdk
    13
    1
    0 Votes
    13 Posts
    2k Views
    ferdinandF
    No worries, everything is fine, that is what we are here for, to clear up things. When you have questions I encourage you to open a new thread so that we can see what we can do. And this is also an open forum, so you can ask questions to the community if you want to. But unless pointed out specifically otherwise, we assume things to be support requests. Cheers, Ferdinand
  • MacOS C4D Python app questions

    python macos
    4
    0 Votes
    4 Posts
    709 Views
    ferdinandF
    Good to hear. When you want to know more about how to expose libraries, I would recommend reading the Python Libraries Manual, as there are quite a few differences to a vanilla CPython. The guide is a little bit dated, I haven't updated it yet to the pip support Maxime is adding, and I also did not yet cover there mxutils.LocalImportPath. Cheers, ferdinand
  • Development requirements for C4D 2025

    c++ macos
    10
    0 Votes
    10 Posts
    3k Views
    ferdinandF
    Dear development community, just as a clarification, as I was not very clear about that above. We are working on a solution for the build system for the SDK (as I hinted at before in other postings). But for 2025 we will stay with this a bit cumbersome legacy build system solution for macOS. Please excuse the inconvenience but there are a few more moving parts in the background than it is obvious from the outside (to fix this, we must move away from the project tool). Cheers, Ferdinand
  • BaseBitmap Save TIF with LZW and save EXR using ZIP

    2024 c++ windows
    4
    0 Votes
    4 Posts
    673 Views
    ferdinandF
    Hey Kent, it depends a bit on the context. Generally, yes, flags and parameters passed to a BaseBitmap are piped through to the underlying ImageRef. But as I hinted at with the TIF settings for BaseBitmap::Save, some stuff is also ignored. For fundamental stuff like initializing a bitmap with a channel depth, color format, etc., I am not aware of cases where flags are being ignored. But as I wrote in my pseudocode example, the exact nature of the BaseBitmap::GetImageRef is also quite important. My very high level advice would be, use the Maxon Image API directly for simple things like loading, color converting, or saving an image, but avoiding it for complex tasks like for example assembling a multi layer image or drawing (not possible at all in the public API apart from 'dumb' pixel by pixel drawing). The problem with this is that when you must have a BaseBitmap output. Because while you can get an ImageRef from a BaseBitmap instance, there is no 'sane' public way to construct a BaseBitmap from an ImageRef you can of course copy over the buffer manually (not so sane) and there is a private way to do this but has its pitfalls (but is possible to do with the public API). As I said, I would invite you to reach out to us with some code and a concrete use case when you get stuck, I will then be able able to help you specifically. Cheers, Ferdinand PS: We recently dropped the term 'classic API' in favour of 'Cinema API'. We also capitalize now 'Maxon API'. Just saying this for clarity.
  • Help with C4D Preferences Plugin Installation/

    python 2024 2023
    2
    0 Votes
    2 Posts
    621 Views
    ferdinandF
    Hello @qq475519905, Thank you for reaching out to us. Your question is very ambiguous. But given your posting history, I assume this is a development question and not an end user question. I.e., you are a developer who struggles with setting up a plugin which is being loaded, and you are not a user struggling with installing someone else's plugin (the latter would be out of scope of support for the developer forum). We have plenty of Python plugin examples on Github, for anything more concrete, we will need a more concrete question from you. Most importantly executable example code which highlights your problem. Please have a look at Support Procedures: How to Ask Questions. Cheers, Ferdinand
  • Dissipating fog volume

    python
    2
    0 Votes
    2 Posts
    428 Views
    ferdinandF
    Hey @ops, Thank you for reaching out to us. Please excuse the delayed reply. You must use the c4d.modules.volume.VolumeBuilder interface for what you want to do, specifically its GetInputObject method. You have to understand that a volume builder is not a singular object, but a virtual tree of objects, and most parameters are located on one of these child objects. Cinema 4D then only displays the parameters of the child objects inline in the GUI (i.e., description) of the Volume Builder object. [image: 1729163133931-5b76e06e-da90-4205-9e68-3e0ca7d14e8f-image.png] Fig.I: The internal makeup of a Volume Builder object. The virtual hierarchy in form of Volume Filter is inaccessible both via the Object Manager and things like GeListNode.GetChildren(). Instead we must use the dedicate UI and API interface to access them. Cheers, Ferdinand Code """Sets the new min and max values of a Volume Builder fog range object. Must be run as a Script Manager script with a Volume Builder object selected. """ import c4d doc: c4d.documents.BaseDocument # The currently active document. op: c4d.BaseObject | None # The primary selected object in `doc`. Can be `None`. #: The volume builder fog range object type. We currently do not expose a symbol for this. c4d.Ofograngemap = 1039862 def main() -> None: """Called by Cinema 4D when the script is being executed. """ if not isinstance(op, c4d.modules.volume.VolumeBuilder): raise ValueError("The selected object is not a Volume Builder.") # Iterate over the objects in the Volume Builder 'Objects' parameter list. for i in range(op.GetInputObjectCount()): node: c4d.BaseList2D | None = op.GetInputObject(i) # Can happen for folders and on failure, there is no good way to distinguish between the two. if node is None: continue # This is a fog range object, we could do here further checks to ensure it is the correct one. if node.GetType() == c4d.Ofograngemap: print(f"{node[c4d.ID_VOLUMEFILTER_SDF_REMAP_NEW_MIN] = }") print(f"{node[c4d.ID_VOLUMEFILTER_SDF_REMAP_NEW_MAX] = }") # Set new values. node[c4d.ID_VOLUMEFILTER_SDF_REMAP_NEW_MIN] = 0.5 node[c4d.ID_VOLUMEFILTER_SDF_REMAP_NEW_MAX] = 2.0 # Push an update event to Cinema 4D to refresh the user interface. c4d.EventAdd() if __name__ == '__main__': main()
  • 0 Votes
    4 Posts
    838 Views
    ferdinandF
    Oh, my bad, I did overlook that you flagged this as S26. Yes, mxutils is a 2024+ feature. I used it here to carry out type checks, e.g., that a document or bitmap are not null/none. The code will run without them, but it will fail more gracefully with these checks. You could replace these calls with manual checks: bmp: c4d.bitmaps.BaseBitmap = c4d.bitmaps.MultipassBitmap( int(rData[c4d.RDATA_XRES]), int(rData[c4d.RDATA_YRES]), c4d.COLORMODE_RGB)) if bmp is None: # or more precise: if not isinstance(bmp, c4d.bitmaps.BaseBitmap) ... raise MemoryError("Failed to allocate bitmap.") Cheers, Ferdinand
  • Hide port from input menu in the Node Editor

    c++
    3
    1
    0 Votes
    3 Posts
    689 Views
    P
    Thanks for looking into it @m_adam. Maybe this is specific to Arnold, but there are shader parameters that are not linkable. It's a flag on the parameter. Typically, boolean and enum type parameters are not linkable, like the ones highlighted in the screenshot below. But could be any parameters really, depending on the shader code. [image: 1728997153428-7fe9bc40-5f47-4e10-aede-a7fe0fb0331e-image.png]
  • How to compare a port value has been changed?

    windows python 2024
    8
    0 Votes
    8 Posts
    1k Views
    DunhouD
    Wow @m_adam , thanks for that, I'll check this after work!
  • GeUserArea.GetDragObject() for xpresso node

    python
    4
    0 Votes
    4 Posts
    646 Views
    ferdinandF
    Hey everyone, Just as an FYI: cinema::GvCopyBuffer is not a public type. Just saying this so that future C++ users do not run against a wall here. One might be able to wiggle through with a forward/dummy deceleration of GvCopyBuffer, but officially this is not supported in the public C++ API either. And we therefore cannot provide forum support for this in C++ either. Cheers, Ferdinand
  • 0 Votes
    4 Posts
    847 Views
    O
    And that's good to know about using GetMl() over Get Mg(), mainly for the performance reasons if I understood correctly.