• C++ Import Custom Extension With Modal

    Cinema 4D SDK windows c++ 2024
    2
    0 Votes
    2 Posts
    454 Views
    i_mazlovI
    Hi @RyanTheDev, Welcome to the Maxon developers forum and its 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 procedures. You did not do anything wrong, we point all new users to these rules. Forum Overview: Provides a broad overview of the fundamental structure and rules of this forum, such as the purpose of the different sub-forums or the fact that we will ban users who engage in hate speech or harassment. Support Procedures: Provides a more in detail overview of how we provide technical support for APIs here. This topic will tell you how to ask good questions and limits of our technical support. Forum Features: Provides an overview of the technical features of this forum, such as Markdown markup or file uploads. It is strongly recommended to read the first two topics carefully, especially the section Support Procedures: Asking Questions. About your First Question Please elaborate on your question, there's no good reference or solution you can get without providing the context. What is a "custom file type"? do you mean you've implemented BaseSceneLoader plugin? When you try to open dialog? Is it happening on main thread? What's the code that does this? What does it mean "keeps failing" - does it give you error instead? You can also have a look at SCENEFILTER::DIALOGSALLOWED flag, if it's applicable in your case. Cheers, Ilia
  • How to set the active documents preview image

    Cinema 4D SDK windows python
    2
    0 Votes
    2 Posts
    527 Views
    ferdinandF
    Hey @MMayrh, Thank you for reaching out to us. This is not how this parameter works. The parameter DOCUMENT_PREVIEW_IMAGE is of data type BitmapButtonStruct, not of BaseBitmap. [image: 1731082043337-54c636b2-05c8-4e3a-af41-9edf7e80bd24-image.png] The documentation is a bit misleading here. This is not the document preview bitmap, but sort of the preview bitmap delegate. I.e., an entity that is used to retrieve a preview bitmap (for a document in this case). A BitmapButtonStruct wraps a node, an ID, and a dirty flag. [image: 1731082143508-3e4681a7-7db6-45b7-a1da-5279cc028cf2-image.png] This parameter does not make too much sense in the Python API, here is what the C++ API does when the parameter is access for a document: [image: 1731082401202-459e7ff6-a8fe-4abf-ae35-adc803c17170-image.png] I.e., it returns itself (the doc), the ID of the parameter (DOCUMENT_PREVIEW_IMAGE) and the dirty state of its internal current preview bitmap as the BitmapButtonStruct bbs. What you could technically try, is implement a node, e.g., an object, and then set that object as the preview provider for a document. Your node would for that have to implement MSG_DESCRIPTION_GETBITMAP, because that is what effectively will be called. But that is all very theoretical, DOCUMENT_PREVIEW_IMAGE is largely unused in our code base, and I do not see any implemnation for the SetParameter part. So, the document will likely just ignore you trying to overwrite its preview provider. There could be some base implemenation kicking in, but I doubt it. But what you definitely cannot do, is just set there a bitmap to overwrite the preview image of the document (assuming that was what you wanted to do). That would also not make too much sense since a document is constantly recalculating its preview image. So, on the next update that image would be gone (if it would work like that). Cheers, Ferdinand
  • How to Swap location in Object Manager

    Cinema 4D SDK c++ s26 windows
    3
    2
    0 Votes
    3 Posts
    936 Views
    P
    @ferdinand Thank you very much for your reply
  • 0 Votes
    2 Posts
    777 Views
    ferdinandF
    Hello @pchg, Thank you for reaching out to us. Please note that we normally expect question to be accompanied by code. It is also still unanswered in which context you want to do this: As an effector, as a Script Manager script, etc. Cheers, Ferdinand Result [image: 1730718564670-347fc2f0-a0cd-4583-816b-b3e38fda2280-image.png] Code """Reads out the particle data of a MoGraph Cloner object. Must be run as a Script Manager script in Cinema 4D with a MoGraph Cloner 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`. def main() -> None: """Called by Cinema 4D when the script is being executed. """ if not op or not op.CheckType(c4d.Omgcloner): raise ValueError("Please select a MoGraph Cloner object.") # Get the particle data from the cloner object. data: c4d.modules.mograph.MoData = c4d.modules.mograph.GeGetMoData(op) if data is None: return # Get the transform and color data for the particles. matrices: list[c4d.Matrix] = data.GetArray(c4d.MODATA_MATRIX) colors: list[c4d.Vector] = data.GetArray(c4d.MODATA_COLOR) # Iterate over all particle data and do something with it. If we were in an effector, we could # also write back data. Technically, we could also write back data here, but it would be volatile. for i in range(data.GetCount()): matrix: c4d.Matrix = matrices[i] color: c4d.Vector = colors[i] print(f"Particle {i} at {matrix.off} with color {color}") if __name__ == '__main__': main() And here is the 2024.0.0 effector full control mode default code which more or less is very similar but also writes data. """Realizes an effector that attracts MoGraph particles spherically around its origin. Add the example to a Matrix object to understand its effect. In Full Control mode we can realize a true attraction force as we have full control over the particle values. Compare this example to Parameter Control mode to understand the difference. """ import c4d op: c4d.BaseObject # The Python Effector object containing this code. gen: c4d.BaseObject # The MoGraph Generator executing `op`. doc: c4d.documents.BaseDocument # The document `op` and `gen`are contained in. def main() -> bool: """Called by Cinema 4D to evaluate the effector. """ # Get the particle data for the effector #op. Get out when either the data cannot be retrieved. data: c4d.modules.mograph.MoData = c4d.modules.mograph.GeGetMoData(op) if data is None: return 1.0 # The transform of both the generator and the effector, the transforms of all particles, and # finally the position of the effector as if it would live in the coordinate system of the # generator. mgGen: c4d.Matrix = gen.GetMg() mgEff: c4d.Matrix = op.GetMg() matrices: list[c4d.Matrix] = data.GetArray(c4d.MODATA_MATRIX) q: c4d.Vector = ~mgGen * mgEff.off # For each particle compute a weight `w` for how much the particle should be attracted to the # attraction point `q`, and then blend the particle position between the attraction point and # its own position `p`. for i in range(data.GetCount()) : p: c4d.Vector = matrices[i].off w: float = c4d.utils.RangeMap((mgGen * ~mgEff * p).GetLength(), 0., 100., 0., 1., True) ** 3. matrices[i].off = c4d.utils.MixVec(q, p, w) # Write the new data back. data.SetArray(c4d.MODATA_MATRIX, matrices, op[c4d.FIELDS].HasContent()) return True
  • How to modify the index

    Cinema 4D SDK s26 c++ windows
    4
    1
    0 Votes
    4 Posts
    1k Views
    P
    @ferdinand Thank you for your reply
  • TempUVHandle always None! Why?

    Cinema 4D SDK r21 python windows
    3
    0 Votes
    3 Posts
    949 Views
    ThomasBT
    @i_mazlov Thank you very much for the hint with the texture view and for the helpful links. The second thread I have already read, but was not able to find the solution so far. I study these examples. Thank you.
  • Natvis settings not working?

    Cinema 4D SDK windows c++
    5
    0 Votes
    5 Posts
    1k 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
  • 0 Votes
    3 Posts
    803 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
  • 0 Votes
    8 Posts
    2k Views
    S
    Hello @ferdinand ! Thanks for answer it is very clear, i will use virtual resolution from now on
  • 0 Votes
    4 Posts
    920 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.
  • Vertex Map Tag not in sync error

    Cinema 4D SDK python 2024 windows
    3
    1
    0 Votes
    3 Posts
    872 Views
    D
    Hi Ilia, Thank you very much, I was not aware of that! Cheers!
  • 0 Votes
    4 Posts
    1k 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
  • 0 Votes
    4 Posts
    1k Views
    O
    And that's good to know about using GetMl() over Get Mg(), mainly for the performance reasons if I understood correctly.
  • SetPortValue for Texture node ColorSpace

    Cinema 4D SDK python 2024 windows
    3
    0 Votes
    3 Posts
    893 Views
    M
    Thank you so much, this was very helpful to learn. All the best.
  • 0 Votes
    5 Posts
    1k Views
    ferdinandF
    Hey @lednevandrey, without wanting to be rude, I really struggle with understanding what you want to convey. Material[c4d.TEXTURETAG_PROJECTION] = c4d.TEXTURETAG_PROJECTION_UVW does not work because Python is case sensitive and you gave your BaseMaterial instance the symbol material. So, Python is complaining about that. But as said before, a material, i.e., BaseMaterial is not the right place to set the projection. It is the counter part to the thing you see in the Material Manager of Cinema 4D and has no projection. The projection is set in the Material Tag, which slightly confusingly is called TextureTag in the API. Cheers, Ferdinand """Assigns the first material in the document to the selected object and sets its projection to UVW. """ import c4d import mxutils doc: c4d.documents.BaseDocument # The currently active document. op: c4d.BaseObject | None # The primary selected object in `doc`. Can be `None`. def main() -> None: """Called by Cinema 4D when the script is being executed. """ if not op: raise ValueError("Please select an object.") # Get the first material in the document. material: c4d.BaseMaterial = doc.GetFirstMaterial() if not material: raise ValueError("No materials found in the document.") # Get the first existing texture tag on #op or create a new one when none exists. tag: c4d.BaseTag = op.GetTag(c4d.Ttexture) or op.MakeTag(c4d.Ttexture) if not tag: raise ValueError("Failed to get or create a texture tag.") # Set the material and projection. tag[c4d.TEXTURETAG_MATERIAL] = material tag[c4d.TEXTURETAG_PROJECTION] = c4d.TEXTURETAG_PROJECTION_UVW # Update the Cinema 4D UI. c4d.EventAdd() if __name__ == '__main__': main()
  • 0 Votes
    6 Posts
    1k Views
    ferdinandF
    Great to hear that you found your solution! Do not hesitate to ask more questions when you run into problems while exploring our Python API. But just as a heads up, we prefer users opening new topics for new questions. For details see the Support Procedures linked above. Cheers, Ferdinand
  • 0 Votes
    8 Posts
    2k Views
    DunhouD
    Wow @m_adam , thanks for that, I'll check this after work!
  • 0 Votes
    2 Posts
    728 Views
    M
    Hey BigRoy, sadly it's still impossible, I will start the discussion again, thanks for the reminder. Cheers, Maxime.
  • 0 Votes
    5 Posts
    1k Views
    R
    I was just looking for the exact same thing and would second the need for these 3 hooks without the need for a Python Generator object. It would make the pipeline integration of C4D much more straightforward. @m_adam
  • 0 Votes
    3 Posts
    780 Views
    i_mazlovI
    Hi @datamilch, you can use the EVMSG_CHANGE message as a trigger to check your objects for changes. The timer approach might seem imprecise from the first glance, but can actually be used, I don't think there're any significant reasons against it. Additionally, the recent change was made to make BaseList2D being hashable. This effectively means you can operate with your objects in a dict. The python tag approach is the least efficient, although would still work, yes. You're saying your GeDialog plugin uses "mostly the ideantical userdata". If it was "identical", you could potentially use c4d.gui.DescriptionCustomGui with the SetObject function to make it point to your object. This way you can avoid hassling around all the data sync, because it is all handled as a built-in functionality of this class. This is how the attribute manager effectively works, or the Active Object Dialog as well. For your further postings please follow our guidelines on How to Ask Questions, namely: Please consolidate your questions into a singular posting by editing your last posting Cheers, Ilia