Navigation

    • Register
    • Login
    • Search
    1. Home
    2. CJtheTiger
    C

    CJtheTiger

    @CJtheTiger

    1
    Reputation
    7
    Posts
    1
    Profile views
    0
    Followers
    0
    Following
    Joined Last Online

    • Profile
    • More
      • Following
      • Followers
      • Topics
      • Posts
      • Best
      • Groups
    CJtheTiger Follow

    Best posts made by CJtheTiger

    RE: Error when removing bound joints

    Addition

    The error does not occur immediately when Remove is being called but after all operations of the plugin are finished and Cinema 4D takes over again.

    Code

    I uploaded the code to GitHub:
    https://github.com/YoYoFreakCJ/C4D-AdvancedIkSpline
    Note: the framework code is excluded.

    To reproduce the issue with this code:

    1. Build and run the plugin.
    2. In C4D in the Extensions menu choose Advanced IK Spline.
    3. In the Advanced IK Spline change the mode to Bind to make the joints show up in the object manager.
    4. Bind the joints to any geometry.
    5. In the Advanced IK Spline change the mode back to Setup.
    6. Change any of the parameters (e.g. Width).

    The plugin will crash after this.

    posted in Cinema 4D SDK •

    Latest posts made by CJtheTiger

    RE: Error when removing bound joints

    Thank you very much Maxime, both for the solution and the explanation. The code works perfectly. Also thanks for fixing this bug. Out of curiosity: Was this causing issues anywhere else?

    For completion sake: I do need to add a directChild->Free() after directChild->Remove(), correct?

    Still gonna mark this as answered as the core issue has been solved with flying colors. Thanks again!

    posted in Cinema 4D SDK •
    RE: Error when removing bound joints

    Addition

    The error does not occur immediately when Remove is being called but after all operations of the plugin are finished and Cinema 4D takes over again.

    Code

    I uploaded the code to GitHub:
    https://github.com/YoYoFreakCJ/C4D-AdvancedIkSpline
    Note: the framework code is excluded.

    To reproduce the issue with this code:

    1. Build and run the plugin.
    2. In C4D in the Extensions menu choose Advanced IK Spline.
    3. In the Advanced IK Spline change the mode to Bind to make the joints show up in the object manager.
    4. Bind the joints to any geometry.
    5. In the Advanced IK Spline change the mode back to Setup.
    6. Change any of the parameters (e.g. Width).

    The plugin will crash after this.

    posted in Cinema 4D SDK •
    Error when removing bound joints

    Requirement

    • C++ object plugin creates joints under the plugin object.
    • Properties on the plugin object define the joints hierarchy and properties.
    • Changing the properties should delete and re-create the joints.
    • The user may bind the joints to geometry. Weights do not have to persist upon re-creation of the joints.

    Issue

    • When the joints are bound to geometry the plugin crashes upon removing the joints via code. No specific error message is provided.
    • Removing the joints from the weight tag or deleting the weight tag on the geometry prevents the error from occuring.

    Code

    The joints are being removed using this code:

    BaseObject* child = op->GetDown();
    while (child)
    {
        child->Remove();
        child = op->GetDown();
    }
    

    This code is either executed from the Message or Main thread.

    What can I do to prevent the error from occuring or analyzing this error further?

    Cinema 4D 2023.1.3

    posted in Cinema 4D SDK •
    RE: creating children in generator

    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

    posted in Cinema 4D SDK •
    RE: creating children in generator

    Good evening @ferdinand,

    my intention was not to create objects, return them in GVO and create clones of those objects to insert into the document. My intention was to create objects in GVO and insert the exact same objects in the document. During my prototyping with Python this actually worked; manipulating the objects in the document also manipulated the virtual objects. Obviously this is not what I'm trying to do anymore. 😉 Feels like this is something a teacher would schold me for.

    Right now I'm thinking: Why use virtual objects in the first place? The only benefit of virtual objects in terms of usability is that I can prevent the user from manipulating them directly. Why not instead just insert all the objects in the document using the approach you described while limiting access to the user by manipulating the layers they're in? This way I wouldn't need any virtual objects anymore. Unless you tell me otherwise this is what I'm going to try to do in the next couple of days.

    Then again I'm super tired and had a long day at work... Don't judge me for stupid ideas please.

    Thanks a lot for the scene and the Python sample!

    Best regards,
    Daniel

    posted in Cinema 4D SDK •
    RE: creating children in generator

    Hey @ferdinand,

    thank you very much for this in-depth explanation. And thanks to everyone involved for discussing this topic, it's very much appreciated.

    My Plugin Idea

    I'm creating an "Advanced IK Spline" with additional handles.

    Demo Video

    Demo Scene hosted on my personal OneDrive
    The scene might not fully represent the screenshots below. I prepared this scene as a sort of blueprint which I'm now trying to re-create with this plugin during which I decided to rename some stuff and change the icon.

    The generator object itself has various settings to control the generation of all required objects, consisting of some hidden joints, controller nulls, IK splines and layers.

    65b815db-d4db-4e60-ac1b-49f76902e3ac-image.png

    The generated objects look something like this:

    30dea042-a9b2-418b-9bbc-7ed52198571f-image.png
    Note: The naming and some portions of the hierarchy is outdated in this screenshot.

    The key features are:

    • When the user chooses Mode "Setup" none of these objects should be shown in the object manager but in the viewport. Changing the settings will delete the previously created hierarchy and generate a new one which will match the new settings.
    • When the user chooses Mode "Bind" only some Joints should be shown in the object manager so the user can select them and bind and weight paint a mesh to them.
    • When the user chooses Mode "Animate" only some controller nulls should be shown in the object manager so the user can select them and animate the joints which are bound to them via IK spline tags.

    The whole point of this project is to not having to look at all the behind-the-scenes objects which the user should not have to worry about. The user should only have to see what is relevant (in the viewport as well as in the object manager).

    I'd like to give this dude credits for coming up with this rig while I'm at it:
    https://www.youtube.com/watch?v=I4JL23DvaN0

    In response to your answer

    I think I understand all the points you're making and I'm really thankful that you're on top of your API game to help me to this extend.

    While I do trust myself to create the code for proper caching in a stable manner I value your opinion more to respect the limitations of ObjectData. So that's what I'll do for now.

    The question for me then is: How do I proceed? I could let the plugin create all these objects as intended in GVO, then make the user use Current State to Object or Make Editable to get all the virtual objects (while hiding behind-the-scene objects in an invisible layer) but this is not very user-friendly. The functionality I'd like to implement is best achieved with an approach similiar to the Character module imho.

    My best bet then is to simply hope that you can come up with a better approach after reading my plugin idea. Until then I guess I will follow the approach I just described even though this might come with different kinds of problems in terms of usability.

    What I would've loved most would've been to extend the existing IK Spline tag so the user can configure a handle to be influenced by the spline so it can act like the smaller handles you see in the demo video above. Maybe that's an idea for you guys for a future C4D update, I don't think extending existing Nodes is what us normal folks are supposed to do. 🐵

    I have to bundle this whole thing and make it reusable in an easy non-confusing manner, that's the most important thing for me.

    Best regards and thanks again,
    Daniel

    // EDIT
    Also sorry for carrying this thread off-topic with my whole "but what should I do then?"-shenanigans. If you'd like I can create a new thread addressing this new issue.

    posted in Cinema 4D SDK •
    creating children in generator

    I'm trying to create a plugin which behaves similiar to the Character module. I'll break it down to this:

    • The plugin should be an object (using ObjectData).
    • The plugin has settings for the user to modify.
    • Depending on the settings the object will generate different objects.
    • One of the settings (let's call it Mode) should toggle whether the user can see the generated objects as children of the plugin object (to interact with them) in the object manager or not. However the objects will always be visible in the viewport.

    So my idea was this:

    • In GetVirtualObjects I generate the desired objects based on the object settings. All desired objects will always be returned by this method.
    • To add the objects as children to the plugin object in the document I have to use the main thread. For this I call ExecuteOnMainThread from inside GetVirtualObjects.

    As I gathered from this thread with that lovely fella I am indeed allowed to create object hierarchies inside GetVirtualObjects, but I must not insert these generated objects in the document from inside this method (since it's not running on the main thread). So my idea for the code is this:

    BaseObject* MyPlugin::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)
    {
        Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTYFLAGS::DATA);
        if (!dirty)
            return op->GetCache(hh);
    
        BaseObject* generatedObjects = generateObjects(op);
    
        // Use a BaseLink to pass the current object to the method on the main thread as suggested in https://plugincafe.maxon.net/topic/13068/calling-executeonmainthread-from-objectdata-getvirtualobjects
        BaseContainer* bc = op->GetDataInstance();    
        BaseLink* link = bc->GetBaseLink(ID_PRV_BASE_LINK);
    
        if (link == nullptr)
        {
            link = BaseLink::Alloc();
            link->SetLink(op);
            bc->SetParameter(ID_PRV_BASE_LINK, link);
        }
    
        BaseDocument* doc = op->GetDocument();
    
        maxon::ExecuteOnMainThread([this, doc, link, generatedObjects]()
            {
                addGeneratedObjectsToDocument(doc, link, generatedObjects);
            });
    
        return generatedObjects;
    }
    
    void MyPlugin::addGeneratedObjectsToDocument(BaseDocument* doc, BaseLink* link, BaseObject* generatedObjects)
    {
        BaseObject* op = static_cast<BaseObject*>(link->GetLink(doc));
    
        clearChildren(op);
    
        switch(getMode(link))
        {
            case Mode::ShowObjects:
                generatedObjects->InsertUnderLast(op);
                break;
            default:
                // Do nothing.
                break;
        }
    }
    

    So my questions before committing to writing the rest of the code is this:

    • Is this the right approach for my goal? Should I call ExecuteOnMainThread from within GetVirtualObjects or am I on the wrong track?
    • Is this the intended way to develop a plugin like this? Generators in the traditional sence take an input (which usually is whatever the user places as children of the generator) but in this case (just like with the Character module) the generator children will solely be managed by the object itself.

    The code does work, I'd just like to make sure that I'm not messing something up by passing references the wrong way or by abusing the pipeline or anything like that.

    Thanks for all you do guys! ❤

    posted in Cinema 4D SDK •