Creating a Copy of a UVW tag

On 05/01/2014 at 11:51, xxxxxxxx wrote:

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

I'm trying to create a second UVW tag by allocating a brand new empty UVW tag instance.
Then looping through original one and copying the data over to the allocated one.
But I'm running into all kinds of strange problems.

First- I found a problem where a generated UWV tag has to be assigned some sort of projection (frontal, box, etc..) or else nothing will work at all properly.

Second - After I make sure to assign a frontal projection to my original UWV tag.
When I run my code to copy the data from the original to the allocated one. The original UVW tag gets deleted!!!
What the heck?

Third - C4D crashes (hangs) after that point

    BaseObject *obj = doc->GetActiveObject();  
  Matrix mg = obj->GetMg();  
  BaseTag *srcTag = obj->GetTag(Tuvw, 0);  
  if( !srcTag ) return FALSE;  
  //Cast the active object to a polygon type so we can get it's poly count  
  PolygonObject *pobj = ToPoly(obj);  
  LONG numFaces = pobj->GetPolygonCount();  
  //Create a new empty UV tag in memory only at this point  
  AutoAlloc<UVWTag> newUVTag(numFaces);  
  if( !newUVTag ) return FALSE;   
  //Set this new tag's UVs to the same as the source tag's UVs      
  UVWTag *srcUVTag = (UVWTag* )srcTag;               //Cast the BaseTag to a UVWTag type  
  for(LONG i=0; i<numFaces; i++)  
      srcUVTag->Copy(newUVTag, i, srcUVTag, i);     //Copy the UV data to the new tag  
  //At this point the code deletes the existing UVW tag!!!  
  //Why on earth would it do that!?  
  obj->InsertTag(newUVTag);      //<--- C4D hangs(crashes)  

Can anyone tell me how to do this properly?


On 06/01/2014 at 06:34, xxxxxxxx wrote:


Is there any reason for not using C4DAtom::GetClone() to make a copy of the UVW tag?

Cactus Dan

On 06/01/2014 at 07:48, xxxxxxxx wrote:

The reason is I would like to know how to properly use the Copy() function that's in the SDK for this.

I've been using this code to get my work done:

    BaseTag *uvwTag = obj->GetTag(Tuvw, 0);  
  BaseTag *tClone = (BaseTag* )uvwTag->GetClone(COPYFLAGS_0, NULL);  
  UVWTag *uvwClone = (UVWTag* )tClone;

But I would like to know to to use Copy() function in the SDK.

I think my code is failing because it requires handles. And I'm feeding it objects.
I have some code from many years back that someone posted and I'm using that as a guide. But it's very different than the R13 sdk code. And I'm having trouble getting the Copy() function to work.


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


OK, I see.

Well, first of all, with the code you posted, I think the UVW tag needs to be inserted in the object before you start trying to access the data. The reason would be that a UVW tag needs to be associated with a polygon object so that the UVW coordinates stored in the UVW tag correspond with the polygons of the object.

Most objects and tags will receive the message "MSG_MENUPREPARE" when they're created and added to the document, and use that received message to do some initial setup, like allocating memory for data storage. So in your posted code, the UVW tag is allocated but not inserted in the object before trying to access the data, so maybe it has no data yet, and could be the reason it's crashing.

OH, wait, I see that the UVW tag's Alloc() function requires a count parameter, so maybe what I said above isn't the case. But I'd still be curious to see if you insert the tag before trying to copy the data would solve the crash issue?

Cactus Dan

On 06/01/2014 at 08:15, xxxxxxxx wrote:

Hmm. Well that's not how the code I have works.
In the code I have. The guy allocates the tag in memory.  And then copies the existing tag's data to it without ever adding the allocated one to the object.

Here's that part of the code he wrote:

// start by grabbing the current UVWTag  
 UVWTag *pSrcUVs = (UVWTag* )(op->GetTag(Tuvw, 0));  
 if( !pSrcUVs )  
  return false;  
 // create a working sand-box  
 UVWTag *pWrkUVs = UVWTag::Alloc(m_numFaces);  
 if( !pWrkUVs )  
  return false;  
 // before we start, set the default state of caller's UVWTag to src  
 for(i=0; i<m_numFaces; i++)  
  pDstUVs->Cpy(i, pSrcUVs, i);

I don't know who wrote this code. It's very old.
It might have possibly been Giblet?


On 06/01/2014 at 08:17, xxxxxxxx wrote:


Originally posted by xxxxxxxx

I think my code is failing because it requires handles. And I'm feeding it objects.

Ooops, I missed this one, too. 😊

Yep, the UVWHandle is the pointer to the data, and that's what is required in R12+.

Cactus Dan