Pose Morph Tag; point selection Issue [SOLVED]



  • On 13/11/2015 at 10:21, xxxxxxxx wrote:

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

    ---------
    Howdy,

    What I'm trying to do is create a clone of an object that has a Pose Morph tag on it, then set each Pose Morph slider on the clone to 100%, compare the points of the morphed clone with the original object, and select the points that are in different positions on the clone than on the original object, but it's not working.

    Here is my code:

    bool SelectMorphedPoints(BaseDocument *doc)
    {
    	BaseObject *op = doc->GetActiveObject(); if(!op) return false;
    	BaseTag *tag = op->GetTag(1024237); if(!tag) return false;
    	
    	CAPoseMorphTag* pmTag = static_cast<CAPoseMorphTag*>(tag);
    	
    	LONG i, mCnt = pmTag->GetMorphCount();
    	GeData sSet;
    	
    	// set all sliders to 0.0
    	for(i=0; i<mCnt; ++i)
    	{
    		DescID sliderId = pmTag->GetMorphID(i);
    		sSet = Real(0.0);
    		pmTag->SetParameter(sliderId, sSet, DESCFLAGS_SET_0);
    	}
    	
    	// clone the object
    	BaseObject *clone = (BaseObject* )op->GetClone(COPYFLAGS_0, NULL);
    	if(clone)
    	{
    		Vector *padr = GetPointArray(op);
    		Vector *cpadr = GetPointArray(clone);
      
    		BaseTag *clTag = clone->GetTag(1024237);
    		if(clTag)
    		{
    			CAPoseMorphTag* cpmTag = static_cast<CAPoseMorphTag*>(clTag);
    			if(cpmTag)
    			{
    				for(i=0; i<mCnt; ++i)
    				{
    					DescID sliderId = cpmTag->GetMorphID(i);
    					sSet = Real(1.0);
    					cpmTag->SetParameter(sliderId, sSet, DESCFLAGS_SET_0);
    					
    					clone->Message(MSG_UPDATE);
    					
    					BaseSelect *bs = ToPoint(op)->GetPointS();
    					if(bs) bs->DeselectAll();
    					
    					LONG p, pCnt = LMin(ToPoint(op)->GetPointCount(),ToPoint(clone)->GetPointCount());
    					for (p=0; p<pCnt; p++)
    					{
    						if(!VectorEqual(padr[p], cpadr[p], 0.001)) bs->Select(p);
    					}
    					
    					if(bs->GetCount() < 1) GePrint(" no points selected");
    					
    					sSet = Real(0.0);
    					cpmTag->SetParameter(sliderId, sSet, DESCFLAGS_SET_0);
    				}
    			}
    		}
    		BaseObject::Free(clone);
    	}
    	
    	return true;
    }
    

    It prints "no points selected" for every morph. Why is it not working?

    Adios,
    Cactus Dan



  • On 16/11/2015 at 02:31, xxxxxxxx wrote:

    Hello,

    could you tell us what exactly you are doing in "VectorEqual"? If this function fails, the count will be 0. Are you sure that the given epsilon fits? Did you check if setting the parameter and sending MSG_UPDATE did indeed morph the points of the clone object?

    Best wishes,
    Sebastian



  • On 16/11/2015 at 07:11, xxxxxxxx wrote:

    Howdy,

    Well, the VectorEqual() function is the R12 API function that was changed in R15 to Vector64::IsEqual().

    Prior to R15 in c4d_tools.h:

    inline Bool VectorEqual(const SVector &v1, const SVector &v2, SReal epsilon=SCO 0.01)
    {
    	return (Abs(v1.x-v2.x)<epsilon && Abs(v1.y-v2.y)<epsilon && Abs(v1.z-v2.z)<epsilon);
    }
    

    After R15 in ge_lvector.h:

    Bool IsEqual(const Vector64& v2, const Float64& epsilon = 0.01) const
    {
    	return Abs(x - v2.x) < epsilon && Abs(y - v2.y) < epsilon && Abs(z - v2.z) < epsilon;
    }
    

    So, you can see there is no difference in the functionality of the code.

    Setting the parameters and sending the MSG_UPDATE message seems to be working because if I comment out these lines at the end of the first loop:

    //sSet = Real(0.0);
    //cpmTag->SetParameter(sliderId, sSet, DESCFLAGS_SET_0);
    

    ... and then insert the clone instead of deleting it, all the sliders are set to 100%.

    The code is working prior to R12 with the MoccaMorph tag, but not with the R12+ Pose Morph tag, so I'm at a loss as to why it's not working.

    Adios,
    Cactus Dan



  • On 17/11/2015 at 00:56, xxxxxxxx wrote:

    Hello,

    a tag will only do something when its Execute() function is called. Sending MSG_UPDATE to the host object or changing a parameter with SetParameter() will not invoke the tag's Execute() function. The Execute() function will be called when the whole document is evaluated.

    So I suggest to create a temporary BaseDocument and insert the clone into that document. Then you can evaluate this document with ExecutePasses() in your loop to make sure the tag is executed and the clone mesh will be deformed.

    Best wishes,
    Sebastian



  • On 17/11/2015 at 07:08, xxxxxxxx wrote:

    Howdy,

    AHA! That works. Thanks. 😉

    So, does that mean sending MSG_UPDATE in versions prior to R12 envoked the tag's Execute() function, since it worked before with the Mocca Morph tag?

    Adios,
    Cactus Dan



  • On 17/11/2015 at 09:46, xxxxxxxx wrote:

    Hello,

    we can only support the SDK or the current version of Cinema; I can't answer questions about R12 and earlier versions.

    Best wishes,
    Sebastian



  • On 17/11/2015 at 12:28, xxxxxxxx wrote:

    Howdy,

    Well, that wasn't really a support question. It was just a curiosity question. 😕

    Adios,
    Cactus Dan


Log in to reply