SplineData GetParameter Helper

On 07/03/2014 at 04:59, xxxxxxxx wrote:

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

---------
I'm creating some helper methods for the C4DAtom::GetParameter method, since using it as is, is a bit verbose. Here's a example of my helper for a Float.

Bool GetParameter(GeListNode* node, const Int32 id, Float& value) {
    GeData d;
    if(node->GetParameter(id, d, DESCFLAGS_GET_0)) {
        value = d.GetFloat();
        return true;
    }
    return false;
}
  
//Usage:
Float offset;
if(!GetParameter(op, TEST_EFFECTOR_OFFSET, offset)) return;

This works and sets the offset correctly as a Float set by the user in the GUI.

But when I try to do the same thing to a custom data type, in this case SplineData, the data disappears when out of the helper function's scope. Here's the code:

Bool GetParameter(GeListNode* node, const Int32 id, SplineData *&splineData) {
    GeData d(CUSTOMDATATYPE_SPLINE, DEFAULTVALUE);
    if(node->GetParameter(id, d, DESCFLAGS_GET_0)) {
        splineData = (SplineData* )d.GetCustomDataType(CUSTOMDATATYPE_SPLINE);
        cout << splineData->GetKnotCount() << endl; **// outputs 4, correct**
        return true;
    }
    return false;
}
  
//Usage:
SplineData* splineData;
if(!GetParameter(op, TEST_EFFECTOR_SPLINE, splineData)) return;
if(splineData) cout << splineData->GetKnotCount() << endl; **// outputs 0, incorrect**

I can't figure out how to get the correct SplineData out of the helper function. Any help on this would be great as I'm relatively new to c++.

On 08/03/2014 at 07:42, xxxxxxxx wrote:

You need to copy the SplineData with SplineData::CopyTo() and remove the address-of operator from the splineData parameter.

Just declare the GeData variable as you've done in the Float example.

Remember to either use AutoAlloc<SplineData> or free it with SplineData::Free().

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

That was it. Thanks DavidW!

On 08/03/2014 at 12:27, xxxxxxxx wrote:

Could you please post your working version fusepilot?

-ScottA

On 08/03/2014 at 15:51, xxxxxxxx wrote:

Yep,

Bool GetParameter(GeListNode* node, const Int32 id, SplineData *splineData) {
    GeData d;
    if(node->GetParameter(id, d, DESCFLAGS_GET_0)) {
        SplineData *sd;
        sd = (SplineData* )d.GetCustomDataType(CUSTOMDATATYPE_SPLINE);
        sd->CopyTo(splineData);
        return true;
    }
    return false;
}
  
//Usage:
AutoAlloc<SplineData> splineData;
if(!GetParameter(op, TEST_EFFECTOR_SPLINE, splineData)) return;

On 08/03/2014 at 16:24, xxxxxxxx wrote:

Thanks.

-ScottA

On 25/03/2014 at 09:20, xxxxxxxx wrote:

I hate to bring this up again. But in the process of making these functions work for R13, I've noticed that version of the SDK does not contain a SplineData::CopyTo. And all the solutions I've found about C++ deep copying suggest creating something like, well the CopyTo function. Which I don't think I can do.

So how were you suppose to do this prior to R14 when SplineData::CopyTo was introduced? Or how can I create my own SplineData::CopyTo helper function?

Thanks.

On 26/03/2014 at 18:03, xxxxxxxx wrote:

I figured out a solution. Just copy all of the CustomSplineKnots over.

void CopySplineDataTo(SplineData* src, SplineData *dst) {
    vector<CustomSplineKnot*> knots;
    
    for (LONG i = 0; i < src->GetKnotCount(); i++) {
        knots.push_back(src->GetKnot(i));
    }
    
    LONG num_knots = knots.size();
    
    dst->DeleteAllPoints();
    dst->MakePointBuffer(num_knots);
    
    for (LONG k = 0; k < num_knots; k++) {
        CustomSplineKnot* knot = knots[k];
        
        dst->InsertKnot(knot->vPos.x, knot->vPos.y);
        CustomSplineKnot* new_knot = dst->GetKnot(k);
        CopyMem(knot, new_knot, sizeof(CustomSplineKnot));
    }
}
  
  
Bool Get(GeListNode *node, const LONG id, SplineData *spline_data) {
    GeData d;
    if(node->GetParameter(id, d, DESCFLAGS_GET_0)) {
        SplineData *sd;
        sd = (SplineData* )d.GetCustomDataType(CUSTOMDATATYPE_SPLINE);
#if API_VERSION >= 14000
        sd->CopyTo(spline_data);
#else
        CopySplineDataTo(sd, spline_data);
#endif
        return true;
    }
    return false;
}