Plugin Cafe Homepage
Forum Home Forum Home > Plugin Cafe > SDK Help
  New Posts New Posts
  FAQ FAQ  Forum Search   Register Register  Login Login

Please use GetParameter/SetParameter

 Post Reply Post Reply
Author
Message
Matthias Bober View Drop Down
Forum Moderator
Forum Moderator


Joined: 2006 Oct 16
Location: Germany
Online Status: Offline
Posts: 2204
Post Options Post Options   Quote Matthias Bober Quote  Post ReplyReply Direct Link To This Post Topic: Please use GetParameter/SetParameter
    Posted: 2010 Oct 27 at 6:23am

User Information:

Cinema 4D Version:    
Platform:      
Language(s):       

---------

Dear developers,

FYI, please always use SetParameter/GetParameter from now on to access parameters. Accessing the container through GetDataInstance led to some problems because a programmer can never know for sure where an object stores its data. Fiddling in the container can cancel the mechanisms used by the AM and XPresso.

cheers,
Matthias

MAXON
developer support
Back to Top
Klaus Heyne View Drop Down
Member
Member
Avatar

Joined: 2003 Jan 28
Location: Germany
Online Status: Offline
Posts: 279
Post Options Post Options   Quote Klaus Heyne Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Nov 05 at 9:38am
sorry, I don't understand. Instead of what should GetParameter be used? What would be the replacement for

BaseContainer *bc = op->GetDataInstance();
Bool b = bc->GetBool(ID_MYBOOL);
LONG l = bc->GetLong(ID_MYLONG);
...

Do you mean, we cannot store and use a pointer to the BaseContainer anymore and have to code

GeData data;
op->GetParameter(DescLevel(ID_MYBOOL), data, DESCFLAGS_GET_0);
Bool b = data.GetBool();
op->GetParameter(DescLevel(ID_MYLONG), data, DESCFLAGS_GET_0);
LONG l = data.GetLong();

for each single parameter? A text replacement wouldn't be possible, so we would have to replace manually hundreds of lines! Additionally, a lot of functions that deal with BaseContainer pointers have to be rewritten.
Back to Top
spedler View Drop Down
Member
Member


Joined: 2008 Apr 19
Location: United Kingdom
Online Status: Offline
Posts: 669
Post Options Post Options   Quote spedler Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Nov 06 at 3:20am
Klaus, I sympathise with you very much. I was going to post something similar but didn't get round to it. The other questions of course, are does this mean that existing plugins, all using BaseContainers extensively, can be expected to fail at some point in the future with later releases of C4D? And why does the SDK tell us to use them in preference to GeData?

I too would like some more details about this.

Back to Top
Matthias Bober View Drop Down
Forum Moderator
Forum Moderator


Joined: 2006 Oct 16
Location: Germany
Online Status: Offline
Posts: 2204
Post Options Post Options   Quote Matthias Bober Quote  Post ReplyReply Direct Link To This Post Posted: 2010 Nov 08 at 2:16am
It is still allowed to access the BaseContainer directly. In the long run it is recommended to use Set/GetParameter though. It would allow us to implement some nifty features which are otherwise not possible.

cheers,
Matthias

MAXON
developer support
Back to Top
ScottA View Drop Down
Member
Member


Joined: 2011 Jan 07
Online Status: Offline
Posts: 2268
Post Options Post Options   Quote ScottA Quote  Post ReplyReply Direct Link To This Post Posted: 2011 Jan 08 at 4:29pm
Hey guys.
I'm new at this C++ API stuff and I just learned how to get at an object's container using the GetDataInstance() function. Only to see it's now being frowned upon.


This is simple example of using the GetDataInstance() function:

BaseObject *objCube = BaseObject::Alloc(Ocube);  //Creates a cube primitive
BaseContainer *bc = objCube->GetDataInstance(); //Get the cube's container
    bc->SetReal(PRIM_CUBE_SUBX,2); // number of segments
    bc->SetReal(PRIM_CUBE_SUBY,5); // number of segments
    bc->SetReal(PRIM_CUBE_SUBZ,2); // number of segments
doc->InsertObject(objCube, NULL, NULL, 0); // Add it to the OM



Could someone possibly convert this same code to the Get/SetParameter method so I can see how it's done?
I don't want to develop bad work habits as a beginner.

Thanks,
ScottA
Back to Top
kuroyume0161 View Drop Down
Member
Member
Avatar

Joined: 2002 Oct 29
Location: United States
Online Status: Offline
Posts: 3660
Post Options Post Options   Quote kuroyume0161 Quote  Post ReplyReply Direct Link To This Post Posted: 2011 Jan 08 at 11:12pm
Replace the bc->SetReal() statements with these and remove the GetDataInstance() as no longer needed.

objCube->SetParameter(DescID(PRIM_CUBE_SUBX), GeData(2.0), DESCFLAGS_SET_0);
objCube->SetParameter(DescID(PRIM_CUBE_SUBY), GeData(5.0), DESCFLAGS_SET_0);
objCube->SetParameter(DescID(PRIM_CUBE_SUBZ), GeData(2.0), DESCFLAGS_SET_0);

ETA: You should be explicit about numeric types whenever possible.  If you specify a 2 for a floating point value, the compiler does a conversion to float or double (which adds instruction calls).  Maybe once or twice isn't bad, but consider when it is being done many times in repetitively called methods.  Still, this also avoids ambiguity as in the case above which may lead to incorrect values being stored.


Edited by kuroyume0161 - 2011 Jan 08 at 11:16pm
Back to Top
spedler View Drop Down
Member
Member


Joined: 2008 Apr 19
Location: United Kingdom
Online Status: Offline
Posts: 669
Post Options Post Options   Quote spedler Quote  Post ReplyReply Direct Link To This Post Posted: 2011 Jan 09 at 3:47am
That's interesting, Robert. Thanks for posting it. It does seem to me though that it's a really long-winded way of going about things. The SetParameter() call involves a constructor for the DescID, and another one for the GeData. Plus it just looks clumsy and inelegant compared to the BaseContainer method.

I think that if Maxon want us to use this method, they should make GetParameter() and SetParameter() easier to use, even if they just put a wrapper round it to avoid the extra typing. Just IMHO, of course.
Back to Top
ScottA View Drop Down
Member
Member


Joined: 2011 Jan 07
Online Status: Offline
Posts: 2268
Post Options Post Options   Quote ScottA Quote  Post ReplyReply Direct Link To This Post Posted: 2011 Jan 09 at 7:14am
Perfect!
Thanks Robert.

BTW. I don't know if you remember me or not. But I'm the guy that asked you to create your Split Selection tag maker plugin on Renderosity years ago.
That's a great little plugin that speeds up the creation of symmetrical Poser figures. And I got a lot of use out that.

-ScottA
Back to Top
bandini View Drop Down
Member
Member


Joined: 2007 Jul 04
Location: United States
Online Status: Offline
Posts: 79
Post Options Post Options   Quote bandini Quote  Post ReplyReply Direct Link To This Post Posted: 2011 Jan 15 at 3:55pm
What is the equivalent in Python? Doesn't appear to be a Get/SetParameter() function. From the documentation, I don't see a way of accessing values not stored in a container - such as certain compositing tag settings...
Back to Top
bandini View Drop Down
Member
Member


Joined: 2007 Jul 04
Location: United States
Online Status: Offline
Posts: 79
Post Options Post Options   Quote bandini Quote  Post ReplyReply Direct Link To This Post Posted: 2011 Jan 15 at 4:09pm
Ah, never mind... I see here:

BaseList2D.__getitem__(self, key)
BaseList2D.__setitem__(self, key, value)

Seems to have replaced GetParameter() and SetParameter() in python.
Back to Top
Rick Barrett View Drop Down
Forum Moderator
Forum Moderator


Joined: 2002 Oct 29
Location: United States
Online Status: Offline
Posts: 56
Post Options Post Options   Quote Rick Barrett Quote  Post ReplyReply Direct Link To This Post Posted: 2011 Jan 21 at 9:23am
Remember any function surrounded by two underscores in the python api is an internal implementation with a separate syntax. For instance, __eq__(a,b) is simply telling python how to evaluate a=b for a specific class.

In this case, __getitem__ and __setitem__ simply refer to the bracket syntax. You're probably doing it right in Python already, because it's easier to do it right in Python.

So basically just use:
op[c4d.PRIM_CUBE_SUBX] = 5
subx = op[c4d.PRIM_CUBE_SUBX]

instead of:
bc = op.GetDataInstance()
bc[c4d.PRIM_CUBE_SUBX] = 5
subx = bc[c4d.PRIM_CUBE_SUBX]


Back to Top
Oukie View Drop Down
Member
Member


Joined: 2011 Jun 12
Location: Furtwangen
Online Status: Offline
Posts: 16
Post Options Post Options   Quote Oukie Quote  Post ReplyReply Direct Link To This Post Posted: 2012 Jan 09 at 7:08am
Hi, i have a question about this GetParameter method.

We want to retrieve information of a node from an xpresso connection.

So actually i got the node object itself and now i want to get the min and max values for a rangemapper for example. The user can input them in the bottom right corner of the cinema 4d IDE.

So i got something like this.
            GeData storedData = new GeData(); // This will contain the data

            if (node.GetParameter(new DescID(C4dApi.XXX), storedData, C4d.DESCFLAGS_GET.DESCFLAGS_GET_0))
            {
                int output = storedData.GetLong();
                Logger.Debug("Data retrieved: " + output.ToString());
            }
            else
            {
                Logger.Debug("Data NOT retrieved!");
            }

So storedData will be filled with the data required from XXX.

1) Where can i find this 'strings' or IDs like you name them (ID_BASEOBJECT_ABS_POSITION e.g.) that have to be inserted instead of XXX? Is there a list to look them up?

Please note we are wrapping the API to C# code ;) ... 

cheers and thanks!


Edited by Oukie - 2012 Jan 13 at 5:20am
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down

Bulletin Board Software by Web Wiz Forums® version 9.61 [Free Express Edition]
Copyright ©2001-2009 Web Wiz

This page was generated in 0.109 seconds.