Group Details Private

administrators

  • RE: find out if generator object? (in case of a Field object)

    Hello @indexofrefraction,

    Thank you for reaching out to us. Here seem to mix up two questions, let me split them up.

    How to find out if something has a green check mark?

    The green checkmark and its counterpart the red cross are just an alternative way to set ID_BASEOBJECT_GENERATOR_FLAG, i.e., the enabled state of an object.

    43590b8e-b198-4dc5-9262-1cfe4ded213a-image.png

    The caveat is however that this parameter is part of the BaseObject Description model, i.e., literally every object has that parameter. It is just that some object types hide and restrict write access to it. So, this applies:

    # Get/set the generator flag of an object where we know that it has that GUI, can be disabled.
    state: bool = op[c4d.ID_BASEOBJECT_GENERATOR_FLAG]
    op[c4d.ID_BASEOBJECT_GENERATOR_FLAG] = not state
    
    def CanDisable(obj: c4d.BaseObject) -> bool:
        """Tests if #obj can be disabled, i.e., if it has the "check mark GUI".
        """
        # An object which is disabled always has that GUI.
        if not obj[c4d.ID_BASEOBJECT_GENERATOR_FLAG]:
            return True
        
        # Attempt to disable the object.
        obj[c4d.ID_BASEOBJECT_GENERATOR_FLAG] = False
        
        # The object refused being disabled, it hides that GUI.
        if obj[c4d.ID_BASEOBJECT_GENERATOR_FLAG]:
            return False
        
        # The object let us write the state, reinstate the previous state and return #True
        obj[c4d.ID_BASEOBJECT_GENERATOR_FLAG] = True
        return True
    
    # Figure out if something lets us write to #ID_BASEOBJECT_GENERATOR_FLAG, i.e., if it can be
    # disabled.
    print(CanDisable(op))
    

    What is a generator?

    But the underlying question is: What qualifies as a generator? We have to remind ourself that modern day Cinema 4D (V5 up 2025.1.0) is a 27 years old software project. There is bound to be some terminological noise and inconsistency how flags are set/interpreted because when there is one thing developers love to do, then it is bending the rules 😉 .

    The OBJECT flags do exist to enable API features when an ObjectData plugin is registered. BaseList2D::GetInfo just exposes that registration data and is not meant as a user facing classification of objects. Because which OBJECT flags are passed and which kind of object plugin registration function is called, then determines how Cinema 4D operates that object in the scene graph. OBJECT_GENERATOR in combination with IS_SPLINE for example makes it so that Cinema 4D calls ObjectData::GetVirtualObjects or ObjectData::GetContour, the methods which implement a polygon or spline object generator.

    But over the time, our developers got creative, and there are now objects which act both as objects and splines, objects can (sort of) act as tags, and many things more. And then there are of course things like null objects, lights, cameras and more, which escape the pattern "poly generator, spline generator, point deformer, or particle deformer" entirely. When interpreted practically, I would classify everything as a generator that has a cache that is not a null object. You can read more about our object model here.

    Last but not least, when you just want to find out if something is a field, you can just test for OBJECT_FIELDOBJECT. But just as for OBJECT_GENERATOR, some things might bend on a technical level the rules of what a field is and what not, as these are not classification flags but API features enabling flags.

    Cheers,
    Ferdinand

    posted in Cinema 4D SDK
  • RE: Automating ColorSpace Change for Textures in Redshift

    Hi sorry I fixed my code.

    Cheers,
    Maxime.

    posted in Cinema 4D SDK
  • RE: Docked Dialog Problem with width of CUSTOMGUI_FILENAME

    Hi Sebastian,

    Thanks for your patience. TLDR; it's a bug but you still need to set minimal width.

    The issue is twofold:

    1. For this UI element to work as intended you need to specify the minimal width argument minw, for example using the c4d.gui.SizeChr() function:
      self.AddCustomGui(self.ID_TEXT_1, c4d.CUSTOMGUI_FILENAME, '', c4d.BFH_SCALEFIT, c4d.gui.SizeChr(80), 0, bc)
    2. There's currently a bug, which prevents this from working properly. The fix is going to be included in one of further Cinema 4D releases.

    After the fix is released, given you're using the minw argument, the issue wouldn't be there anymore. Thanks for drawing our attention to this issue!

    Cheers,
    Ilia

    posted in Cinema 4D SDK
  • RE: KDTree or OcTree with C4D Python

    Hey @gheyret,

    you can project a world space coordinate into screen space with BaseView. But ViewportSelect is more meant for user interactions as its name implies.

    We had this morning a quick talk about your subject, and my stance was mostly that it does not make too much sense to port something like KDTree to Python. Because while porting itself is entirely technically possible and the result is then performant (enough), it implies a technical complexity which is not. So, you are then basically able to process point neighbour hood blazingly fast in Python, but that implies processing a lot of points (at which Python sucks). Which is why I recommended ViewportSelect as a workaround for cases where you only have to lookup the neighbor of a handful of points. But for your case, you will not get very far with ViewportSelect.

    Because in the end remains the fact that the popular computational geometry algorithms which could use something like a KDTree: differential growth, shortest path on a mesh, heat maps, optimal coverage (e.g., space colonization), etc., tend to be very complex computationally and therefore not very sensible to be implemented in Python. Going over ViewportSelect would make things even slower (and also imprecise).

    Maxime has this still on his agenda and you might get lucky. I am of course aware that there is a wide range of what people would consider "acceptable" computation times. Technical artists are sometimes fine with a script running for 5, 10, 20 minutes; i.e., just brute forcing something. And in the end you can also write yourself at least an octree relatively easily in Python (with a then to be expected performance).

    Cheers,
    Ferdinand

    posted in General Talk
  • RE: KDTree or OcTree with C4D Python

    Hey @gheyret this is on my bucket list of things I want to port it since a long time, but to be honest it's rather low-priority.

    But I will keep it in mind.With that's said depending on what you want to do you may find ViewportSelect Interesting.

    Cheers,
    Maxime.

    posted in General Talk
  • RE: Tree view boolean column bug

    Hi @Gregor-M please make sure that your script is executable before sending it to us. Since in it's current state it does raise

    Traceback (most recent call last):
      File "scriptmanager", line 53, in GetDown
      File "scriptmanager", line 33, in GetChildren
    AttributeError: 'Entity' object has no attribute 'children'. Did you mean: 'GetChildren'?
    

    I added self.children = [] within the __init__ of Entity and it fixed the issue but this indicate that you are working on a different version than us. But even with it I'm not able to reproduce any issue and everything is working as expected.

    With that's said your else statement within the SetCheck looks very suspicious and I won't be surprised that the behavior you are experiencing is coming from this else statement.

    Finally note that you can call the function TreeViewCustomGui.SetRoot to define a root. Then the root argument that is available in all functions will be pointing to it.

    Cheers,
    Maxime.

    posted in Cinema 4D SDK
  • RE: Docked Dialog Problem with width of CUSTOMGUI_FILENAME

    Hi @datamilch,

    Although I highly suspect this to be a bug, I'll need more time to double check it. I'll update you further, once have a more clear vision on this.

    Cheers,
    Ilia

    posted in Cinema 4D SDK
  • RE: Change Icon Color parameter

    Hi @chuanzhen,

    The "Display Color" value of the "Icon Color" attribute is a dynamic value (comparing to "None" and "Custom" being static values), this was explained in the related thread: Python Documentation - Icon Color. This is the reason why it requires special handling, namely (as Manuel explained in the related thread: Simple Organisational Structure Generation Script), one needs to send a c4d.MSG_GETCUSTOMICON_SETTINGS message to the object to properly set this attribute. Please check the example code snippet that shows its usage.

    Cheers,
    Ilia

    Example code, showing the usage of the c4d.MSG_GETCUSTOMICON_SETTINGS message:

    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:
        obj = c4d.BaseObject(c4d.Ojoint)
        
        # Configure object display color attribute
        obj[c4d.ID_BASEOBJECT_USECOLOR] = c4d.ID_BASEOBJECT_USECOLOR_ALWAYS
        obj[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector(1, 0, 1)
    
        # Configure object icon color attribute
        settings = c4d.CustomIconSettings()
        settings._colorMode = 2
        obj.Message(c4d.MSG_GETCUSTOMICON_SETTINGS, {'setting': settings})
        obj[c4d.ID_BASELIST_ICON_COLORIZE_MODE] = c4d.ID_BASELIST_ICON_COLORIZE_MODE_CUSTOM + 1
    
        obj.SetName("Magenta Joint")
        doc.InsertObject(obj)
    
    
    if __name__ == '__main__':
        main()
        c4d.EventAdd()
    
    posted in Cinema 4D SDK
  • RE: Issue: CommandData Plugin Compilation Errors in Cinema 4D 2025.1.0 SDK

    Hey @skibinvitaliy,

    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: How to Ask Questions.

    About your First Question

    No one is judging you here, problems are part of the game and what we are here for to help with 🙂 . But please familiarize yourself with our forum rules, such question should be accompanied by example code and the version you are migrating from, as we otherwise mostly have to guess what is going wrong.

    I am assuming you are migrating from a pre-2025 SDK, that is at least what your errors imply. With 2025 we introduced our cinema namespace. Please follow our Migrating Plugins to the 2025.0 API guide. You are likely just missing a couple of using namespace cinema; at the top of your files.

    Cheers,
    Ferdinand

    posted in Cinema 4D SDK
  • RE: Python Tag plugin : Is it possible to disable(ghost) the host object's parameters?

    Hey @ymoon,

    thank you for reaching out to us. While you can access the description of a scene element at any time via c4d.C4DAtom.GetDesccription, it will always be static, i.e., read only there. Only in the context of NodeData.GetDEnabling and NodeData.GetDDescription, the description of a node will be dynamic (that is what the 'D' stands for in these methods), i.e., writeable.

    It is therefore only possible to runtime modify the description of nodes you do implement yourself. Otherwise the system would inevitably produce race conditions. Where a parameter X of an object O being shown or not, would depend on how two objects A (wants to show O.X) and B (wants to hide O.X) are placed in relation to O in the object manager; and which of (A, B) is therefore executed first and which last.

    There is one exception to that rule, and this is user data, accessible via GetUserDataContainer (Python) and C4DAtom::GetDynamicDescription(Writeable) (C++), here you can always modify the description. There is however no direct flag in the description to disable an element, the closest thing you can do, is hide an element with DESC_HIDE.

    Cheers,
    Ferdinand

    posted in Cinema 4D SDK