Constraint tag properties

On 05/04/2017 at 12:03, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   16 
Platform:   Windows  ;   
Language(s) :     C++  ;

---------
I want to create a Clamp Constraint Tag.
That works except setting the Clamp To parameter.
In python it is  constraintTag[50004,1] = c4d.ID_CA_CONSTRAINT_TAG_CLAMP_TO_SURFACE 
How do I do this in C++.
I guess I must use DescID, but I am not sure how?

//add constraint tag to null
constraintTag = null->MakeTag(1019364);                         //#  Constraint Tag = 1019364
constraintTag->SetName("Constraint Tag");
res = constraintTag->SetParameter(ID_CA_CONSTRAINT_TAG_CLAMP, TRUE, DESCFLAGS_SET_0);
res = constraintTag->SetParameter(50001, surfaceObject, DESCFLAGS_SET_0);			//set target
res = constraintTag->SetParameter(DescID(50004, 1), ID_CA_CONSTRAINT_TAG_CLAMP_TO_SURFACE, DESCFLAGS_SET_0);
res = constraintTag->SetParameter(DescID(50004, 3), ID_CA_CONSTRAINT_TAG_AXIS_ZP, DESCFLAGS_SET_0);				//set align = +z
res = constraintTag->SetParameter(DescID(50004, 4), 2, DESCFLAGS_SET_0);	

On 07/04/2017 at 06:11, xxxxxxxx wrote:

All help is appreciated!
I am stuck at the moment.

-Pim

On 07/04/2017 at 06:56, xxxxxxxx wrote:

I don't have a c++ environnent atm.
But here a python code which work and where you could easily port it into C++

import c4d
  
def main() :
    tag = doc.GetActiveTag()
    
    #useless but c++ code style
    bc = c4d.BaseContainer()
    
    #Get the bc
    bc = tag.GetParameter(c4d.DescID(50004), c4d.DESCFLAGS_GET_0)
    
    #Change the value to 2 => Z+
    #Not sure it's a long maybe Int32 Don't know but oyu get the idea
    bc.SetLong(3, c4d.ID_CA_CONSTRAINT_TAG_AXIS_ZP)
    
    #Reassign the bc
    tag.SetParameter(c4d.DescID(50004), bc, c4d.DESCFLAGS_SET_0)
    c4d.EventAdd()
  
if __name__=='__main__':
    main()

After maybe there is a more efficiency method to do it. But I guess this one will work.
Hope it's help.

On 07/04/2017 at 09:12, xxxxxxxx wrote:

Hi Pim,

sorry for letting you wait. Unfortunately I'm not done with your case, yet, but I don't want to leave you without any answer before the weekend.
In general your code seems to be working here. The thing is, while running in debugger, it's internally running on a bunch of CriticalStop(), which I haven't found the reason for, yet. Neither a workaround. These critical stops might look to you as if C4D has crashed, while it actually has not and you can simply press "continue" in your debugger. So if I use your code in a CommandData and step over the CriticalStops then the outcome looks actually fine to me.
So, I'm wondering, what is your actual issue. Is it the critical stops? I will investigate more in this direction Monday. But maybe you are having different issues, I have overlooked so far. In that case, please provide me with some more details.

On 07/04/2017 at 09:18, xxxxxxxx wrote:

Hi Andreas,

I do not get a crash of some sort.
The parameter is just not set.

I will gr4ph0s solution.

-Pim

On 07/04/2017 at 09:20, xxxxxxxx wrote:

Hm, that part seems to work nicely here. Maybe you are just lacking the EventAdd() in the end? Or other question I forgot to ask, in which context are you using the posted code? Is it in a CommandData or somewhere else?

On 07/04/2017 at 09:42, xxxxxxxx wrote:

Yes, I am using a commanddata.

And I was wrong, cinema indeed seems to crash but I can continue, but the parameters are not set.
And yes, I use an EventAdd() at the end.

I will do some test.

On 07/04/2017 at 09:56, xxxxxxxx wrote:

Running outside the debugger does gives no crashes, but not all parameters are not set.

Tag name set.
Clamp is set.
Target is set.
ID_CA_CONSTRAINT_TAG_CLAMP_TO_SURFACE not set.
ID_CA_CONSTRAINT_TAG_AXIS_ZP not set.
Phong Normals not set.

constraintTag->SetName("C4Dome RL");
res = constraintTag->SetParameter(ID_CA_CONSTRAINT_TAG_CLAMP, TRUE, DESCFLAGS_SET_0);
res = constraintTag->SetParameter(50001, surfaceObject, DESCFLAGS_SET_0);			//set target
res = constraintTag->SetParameter(DescID(50004, 1), ID_CA_CONSTRAINT_TAG_CLAMP_TO_SURFACE, DESCFLAGS_SET_0);
res = constraintTag->SetParameter(DescID(50004, 3), ID_CA_CONSTRAINT_TAG_AXIS_ZP, DESCFLAGS_SET_0);				//set align = +z
res = constraintTag->SetParameter(DescID(50004, 4), 2, DESCFLAGS_SET_0);

On 07/04/2017 at 10:14, xxxxxxxx wrote:

Hi gr4ph0s,

I cannot get your solution to work.
The compiler complains or cinema hangs (in de code below).

//Get the bc
BaseContainer* bc;
GeData d;
res = constraintTag->GetParameter(DescID(50004), d, DESCFLAGS_GET_0);
bc = d.GetContainer();
bc->SetInt32(1, ID_CA_CONSTRAINT_TAG_CLAMP_TO_SURFACE);
    
//Reassign the bc
d.SetContainer(*bc);
constraintTag->SetParameter(DescID(50004), d, DESCFLAGS_SET_0);

On 07/04/2017 at 11:37, xxxxxxxx wrote:

#include "c4d.h"
#include "c4d_symbols.h"
#include "tcaconstraint.h"
#include "main.h"
  
#define ID_SWITCH_CONSTRAINT_TOOL 10000010
  
class SwitchConstCommand : public CommandData
    {
	Bool Execute(BaseDocument* doc)
	{
        if (!doc)
            return false;
  
        BaseTag* tag = doc->GetActiveTag();
        if (tag == nullptr)
            return false;
  
        if (tag->GetType() != 1019364)
            return false;
  
        BaseContainer* bc_tag = tag->GetDataInstance();
        BaseContainer* bc_clamp = bc_tag->GetContainerInstance(50004);
        bc_clamp->SetInt32(3, ID_CA_CONSTRAINT_TAG_AXIS_ZP);
  
        EventAdd();
  
	return true;
	}
};
  
Bool RegisterSwitchConst()
    {
    return RegisterCommandPlugin(ID_SWITCH_CONSTRAINT_TOOL, nullptr, 0, nullptr, String(), NewObjClear(SwitchConstCommand));
    }

Worked here. But I just start to learn C++ and the c++ sdk so they might have a better solution for doing this kind of stuff using directly SetParameter.

On 07/04/2017 at 12:49, xxxxxxxx wrote:

Thanks, it works.
I forgot to get the first container.

-Pim