Solved SplineCustomGui settings issue

Dear Community,

I am displaying a Spline using SplineCustomGui. I am able to display the spline but the custom attributes are missing. Is there a way to do this without a .res file or can someone tell my why it doesn't work?

Several people already posted (or this thread) that the provided Spline Settings don't work.

My spline code (called in the CreateLayout method):

bc = c4d.BaseContainer()
bc[c4d.SPLINECONTROL_GRID_H] = True
bc[c4d.SPLINECONTROL_GRID_V] = True
bc[c4d.SPLINECONTROL_VALUE_EDIT_H] = True
bc[c4d.SPLINECONTROL_VALUE_EDIT_V] = True
bc[c4d.SPLINECONTROL_X_MIN] = 0
bc[c4d.SPLINECONTROL_X_MAX] = 1
bc[c4d.SPLINECONTROL_X_STEPS] = 0.1
bc[c4d.SPLINECONTROL_Y_MIN] = 0
bc[c4d.SPLINECONTROL_Y_MAX] = 1
bc[c4d.SPLINECONTROL_Y_STEPS] = 0.1
bc[c4d.SPLINECONTROL_NO_FLOATING_WINDOW] = False
bc[c4d.SPLINECONTROL_NO_PRESETS] = False
spline_gui = self.AddCustomGui(
    id=spline_id,
    pluginid=c4d.CUSTOMGUI_SPLINE,
    name="Spline",
    flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT,
    minw=600,
    minh=200,
    customdata=bc
)

My current spline looks like this:
84869d98-e82f-46d0-81b1-343213791fe6-image.png

This is what it should look like:
4a17bcb4-7f7e-4f74-b1f1-41b8c8cb5302-image.png

Am I doing this wrong? I open the dialog in a plugin but it doesn't work in a script as well.

Thanks for your help.
-robkom

Hello @robkom,

thank you for reaching out to us. As pointed out by @AiMiDi, there is a difference between GeDialog and Description resource. Which is why some stuff is not supported in dialogs.

The GeDialog resources do not support all functionalities of all resource elements. The SplineCustomGui is such case. Your options are:

  1. Wrap around a description resource in your dialog.
    • Implement a node with the spline gui element in its description.
    • Display the node in a c4d.gui.DescriptionCustomGui inside your dialog.
  2. Create the required additional interface elements on your own with the tools provided by GeDialog.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

Figure 2 is Description GUI and Figure 1 is GeDialog GUI. The SplineCustomGui of Description GUI is different from that of GeDialog GUI.

Cheers,
Aimidi.

@aimidi thank you for this information. The screenshot from the SDK which describes the GeDialog GUI SplineCustomGui is actually a Description GUI SplineCustomGui? Regardless of the Description GUI do you know if it is possible to get those settings for GeDialog GUI as well? The SDK states that I can use the container to activate those settings (this didn't work).

Greetings
-robkom

@robkom
I'm sorry I developed in C++ and don't know much about Python development. In my opinion, you can try creating layouts using Dialog Resource.

Cheers,
Aimidi.

Hello @robkom,

thank you for reaching out to us. As pointed out by @AiMiDi, there is a difference between GeDialog and Description resource. Which is why some stuff is not supported in dialogs.

The GeDialog resources do not support all functionalities of all resource elements. The SplineCustomGui is such case. Your options are:

  1. Wrap around a description resource in your dialog.
    • Implement a node with the spline gui element in its description.
    • Display the node in a c4d.gui.DescriptionCustomGui inside your dialog.
  2. Create the required additional interface elements on your own with the tools provided by GeDialog.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

@ferdinand thank you.
How can I implement my node with the description? I want to show this GUI when I click on a button in my TagPlugin GUI. c4d.gui.DescriptionCustomGui takes an BaseObject as a parameter. Do I need to create another plugin for this description or how can I pass my description to it?

Thank you again
-robkom

Hello @robkom,

yes, you will need to implement some NodeData derived type, e.g., an ObjectData plugin. You can skip most of its implementations, and only have to implement parameter and gui related stuff. The most minimal implementation would be to only implement NodeData.Init(Link) to initialize the node parameters. In your dialog, you then have to create an instance of the node and attach it to the DescriptionCustomGui. Not rocket science, but still a bit of an advanced technique. Your parameters will then be obviously attached to the node and not the dialog. So, when you want to read out something in the context of the dialog, you won't read it from the dialog anymore, but from the node.

I have shown in this thread how to display a node within a GeDialog. In the example I display the internal preferences node and did not create my own node, but it shows you at least partially the workflow. Implementing such node to display will not differ from any other node implementation, it is only that you do not need to implement any of the logic related methods like GetVirtualObjects for a polygonal generator object, since you are only interested in the GUI of the node.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

Thank you @ferdinand,

sorry for interrupting you again but it's not working with my own NodeData plugin. I managed to create an ObjectData plugin however I'm not able to show the description that is allocated to my plugin. It works perfectly fine when I use the preferences node (like in your example) instead of my own ObjectData plugin. Here is my minimalistic implementation:

Plugin registration:

plugins.RegisterObjectPlugin(
        id=1058006,
        info=c4d.PLUGINFLAG_HIDEPLUGINMENU,
        str="tsplineobj",
        icon=load_icon('res/icon.tif'),
        g=tspline.Tspline,
        description="tsplineobj"
    )

Tspline tag:

class Tspline(c4d.plugins.ObjectData):

    def Init(self, node):
        return True

The custom GUI:

    def CreateLayout(self):
        self.GroupBegin(id=1100, flags=c4d.BFH_FIT)
        bc = c4d.BaseContainer()
        bc[c4d.DESCRIPTION_OBJECTSNOTINDOC] = True
        spline_gui = self.AddCustomGui(
            id=423424,
            pluginid=c4d.CUSTOMGUI_DESCRIPTION,
            name="Spline",
            flags=c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT,
            minw=600,
            minh=200,
            customdata=bc
        )
        spline_obj = c4d.BaseObject(1058006)
        spline_gui.SetObject(spline_obj)
        self.GroupEnd()
        return True

the res file:

CONTAINER tsplineobj
{
    NAME tsplineobj;

    GROUP
    {
        SPLINE MY_SPLINE { }
        STATICTEXT TEST
		{
			SCALE_H;
		}
    }
}

Is there anything I missed to implement?

Thank you for your time
-robkom

Hi @robkom,

no worries you are not interrupting, but "it's not working with my own NodeData plugin" is unfortunately quite an ambiguous statement. What do you expect to happen and what happens instead?

What jumps to the eye though, is that you do not initialize the parameters of your Tspline. Have you tried inserting Tspline into an active document to see if the Attribute Manger can deal with, i.e., that you have no syntax or semantic errors in your description? The *.res file looks sort of fine, the only problem I see is that you do not include Obase there and subsequently also do not extend the group ID_OBJECTPROPERTIES. Which you should be able to do, but I would check first if this is the culprit.

edit: What seems much more severe, and I should have pointed to that first, is that you do not ensure that spline_obj is kept alive, since you only reference the object inside CreateLayout with spline_obj, which then will be deallocated once the interpreter has left CreateLayout. Attach the object to something that lives at least as long as the CUSTOMGUI_DESCRIPTION, e.g., the dialog. I would also insert the node into a temporary document, to make sure that stuff that relies on BaseObject.GetDocument() does not fail. Something like this (modify to your liking):

class MyDialog(c4d.gui.GeDialog):
    def __init__(self):
        """
        """
        self._mySpline = c4d.BaseObject(1058006)
        self._tempDocument = c4d.documents.BaseDocument()
        self._tempDocument.InsertObject(self._mySpline)

    def CreateLayout(self, *args):
        """
        """
        # ...
        spline_gui.SetObject(self._mySpline)
        self.GroupEnd()
        return True

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

@ferdinand sorry for my plain statement.

It's not showing the description inside the dialog (I dont get any erros in the console) but instead a blank dialog. I now added Obase and the group ID_OBJECTPROPERTIES but it didn't help. How do I initialize my Tsplineobj parameters/which parameters do you mean? The attribute manager can deal with my description and I dont get any errors. splinegui.PNG

Thank you for your time
-robkom

You need to call NodeData.InitAttr() in NodeData.Init. E.g.:

def Init(self, node):
    """
    """
    self.InitAttr(node, float, c4d.PY_TUBEOBJECT_RAD)
    self.InitAttr(node, float, c4d.PY_TUBEOBJECT_IRADX)

    node[c4d.PY_TUBEOBJECT_RAD] = 200.0
    node[c4d.PY_TUBEOBJECT_IRADX] = 50.0
    return True

But you should check the allocation problem first, it is the most likely culprit. Se the edit in my last posting.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net