Getting a tag from a Link field

On 03/06/2014 at 16:01, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   14 
Platform:      Mac OSX  ; 
Language(s) :     C++  ;

---------
I my shader parameters I have a link field that can be empty or contain a tag (a custom tag that I created).
How, in C++ can I get the content of the link field?
I'm using this code:

BaseContainer * data = sh->GetDataInstance();
BaseTag * the_tag = (BaseTag* ) data->GetBaseLink(TAG_OBJECT);

But this seems to crash Cinema4D.
Damn! So many castings!!! What am I doing wrong?

On 03/06/2014 at 20:16, xxxxxxxx wrote:

Try it like this.

//This is an example of getting the tag the user has dropped into the link gizmo with the ID of MYLINK  
//In this case the tag is a custom tag...So we get it by it's plugin ID#  
  
INITRENDERRESULT MyShader::InitRender(BaseShader *sh, const InitRenderStruct &irs)  
{  
  BaseContainer *data = sh->GetDataInstance();  
  
  BaseTag *myTag = (BaseTag* )data->GetLink(MYLINK, GetActiveDocument(), TAG_PLUGIN_ID);   
  if(myTag) GePrint(myTag->GetName());  
  
  return INITRENDERRESULT_OK;  
}

-ScottA

On 04/06/2014 at 02:41, xxxxxxxx wrote:

Thank you so much, Scott. Got it working (still lots to do, though).
Can't help thinking that this is way more complex than:

def InitRender(self,sh,irs) :
     the_tag=sh[TAG_OBJECT]
     if the_tag is None: return c4d.INITRENDERRESULT_ASSETMISSING
     print the_tag.GetName()

Also, GePrint requires a string and not all types of objects can be converted to strings. In python, if I print the_tag, I get something like:

<c4d.BaseTag object called 'myshader/myshader' with ID 1234567 at 0x1128956b0>

Can't I do the same in C++?

On 04/06/2014 at 02:55, xxxxxxxx wrote:

BaseContainer * data = sh->GetDataInstance();
BaseTag * the_tag = (BaseTag* ) data->GetBaseLink(TAG_OBJECT);

If you would've used a static_cast instead of a C-style cast, you would've seen an error
at compilation time.

Also, GePrint requires a string and not all types of objects can be converted to strings. In python, if I print the_tag, I get something like:

<c4d.BaseTag object called 'myshader/myshader' with ID 1234567 at 0x1128956b0>

Can't I do the same in C++?

You can write yourself a little print function. You can use IsInstanceOf() to check if you
got a tag, object or shader, etc.

-Niklas

On 04/06/2014 at 07:25, xxxxxxxx wrote:

You might want to take a quick look at the second part of my C++ video tutorial Rui.
I explain a few of the fundamentals like the GePrint().
C++ requires more typing. But it's not necessarily "harder" than Python.
More typing != harder.

One of the most common things that is used in the C4D SDK is descriptions.
Almost every time you see this in Python: obj[FOO] = fooValue
It requires this in C++: obj->SetParameter(DescID(FOO), GeData(fooValue), DESCFLAGS_SET_0);

Python wraps things up into tiny little packages that are short to type. But it's not "easier" than C++.
Once you type this stuff few hundred times. You won't notice it so much.
Also once you have built up enough C++ notes. You'll cut an paste a lot of code instead of typing it.

The way I often work is that I play around in Python and try out a few ideas.
Then once I have the idea formed into a solid idea. I then switch over to C++ and make the actual plugin there.
If you can seamlessly jump back and forth from Python & C++. You'll have C4D by the nuts. 😉

-ScottA