CurveEvaluator::GetPointAtParam failing (C++)

CurveEvaluator::GetPointAtParam failing (C++)

Anonymous
Not applicable
841 Views
6 Replies
Message 1 of 7

CurveEvaluator::GetPointAtParam failing (C++)

Anonymous
Not applicable
Hi there!
I´m using C++.
My goal is to get the tangent at a point of an Edge. To do that I´m trying to retrieve the parameter for the CurveEvaluator for that point, which I could then use with CurveEvaluator::GetTangent(...).
After trying to use CurveEvaluator::GetParamAtPoint(...) without any success (yes, I asked here at the forums) for several weeks I now decided to implement my own GetParamForPoint function just because I lack any better ideas.
So, to make things short:
That function would need to get some point on the edge for certain parameters to check for the distance to the input point. For that, the CurveEvaluator supplements a GetPointAtParam(...) function.
What I do is the following:
1. Get minimum and maximum parameters for the CurveEvaluator through GetParamExtents(...), which works fine.
2. Create a SAFEARRAY* called 'param' with one double in it. That double is a value between minimum and maximum parameters from step 1.
3. Call CurveEvaluator::GetPointAtParam(&param, &p), where p is a SAFEARRAY* created with 'new SAFEARRAY()'. That call fails. Documentation again failed to give any clue why that call fails, as well as the HRESULT returned doesn´t help at all.

The complete block of code for that looks like this (I´ll only post the first call to GetPointAtParam(...) since the rest of them looks just the same), evalPtr is a pointer to a CurveEvaluator, paramMin and paramMax are the boundaries for valid parameters:

SAFEARRAY* p = new SAFEARRAY();
SAFEARRAY* params = SafeArrayCreateVector(VT_R8, 0, 1);
double* data;
SafeArrayAccessData(params, (void**)&data);
memcpy(data, &paramMin, sizeof(double));
SafeArrayUnaccessData(params);

HRESULT hr = evalPtr->GetPointAtParam(&params, &p);
if(FAILED(hr))
{
// I always end up here, as the call to GetPointAtParam
// always fails.
}
SafeArrayAccessData(p, (void**)&data);
CVector3 v = CVector3(data[0], data[1], data[2]);
SafeArrayUnaccessData(p);

As the call already fails when using the minimum parameter for the Evaluator as input value, I guess I must have gotten something wrong about how to supply the input parameter to the function, as I think that paramMin should definitely be valid.

If anybody has ever used GetPointAtParam(...) or (even better) GetParamAtPoint(...) successfully, I´d be really really happy if he would be willing to share how he did it as I seem completely unable to get anything really useful out of that CurveEvaluator.

Thx for reading and your help
0 Likes
842 Views
6 Replies
Replies (6)
Message 2 of 7

Anonymous
Not applicable
The GetParamAtPoint functin is used in the CurvatureApp sample program.
It's in the CalculateCurvatureGradient function within the
CurvatureEngine.cpp file which is in the "SDK\Samples\VC++\Standalone
Applications\ApprenticeServer\CurvatureApp\InventorRelated" directory..
--
Brian Ekins
Autodesk Inventor API
0 Likes
Message 3 of 7

Anonymous
Not applicable
The code section below shows how to use the GetParamAtPoint and
GetPointAtParam for an edge evaluator (the code does not have error
handling). It uses SAFEARRAY's, although, you might want to use ATL template
class CComSafeArray (easier to initialize, add/remove elements and also dont
have to worry about destroying when you are done using it).
.............
.............
CComPtr pCurveEvaluator;
pCurveEvaluator = pEdge->GetEvaluator();

SAFEARRAYBOUND s3dPointsArray ;
s3dPointsArray.lLbound =0L ;
s3dPointsArray.cElements =3 ;

SAFEARRAY *pStartPoint =NULL ;
SAFEARRAY *pEndPoint =NULL ;
pStartPoint = SafeArrayCreate (VT_R8, 1, &s3dPointsArray) ;
pEndPoint = SafeArrayCreate (VT_R8, 1, &s3dPointsArray) ;

//get the start and end points
Result = pCurveEvaluator->GetEndPoints(&pStartPoint,&pEndPoint);

long x_indice[1],y_indice[1],z_indice[1];
x_indice[0]=0;y_indice[0]=1,z_indice[0]=2;

double
startpoint_x,startpoint_y,startpoint_z,endpoint_x,endpoint_y,endpoint_z;

//get the x,y and z values of the starpoint
SafeArrayGetElement(pStartPoint,x_indice,&startpoint_x);
SafeArrayGetElement(pStartPoint,y_indice,&startpoint_y);
SafeArrayGetElement(pStartPoint,z_indice,&startpoint_z);

//get the x,y and z value of the endpoint
SafeArrayGetElement(pEndPoint,x_indice,&endpoint_x);
SafeArrayGetElement(pEndPoint,y_indice,&endpoint_y);
SafeArrayGetElement(pEndPoint,z_indice,&endpoint_z);

//get the Parameter at the startpoint for example
SAFEARRAY *pGuessParams =NULL ;
SAFEARRAY *pMaxDeviations =NULL ;
SAFEARRAY *pParams =NULL ;
SAFEARRAY *pSolTypes=NULL;
Result =
pCurveEvaluator->GetParamAtPoint(&pStartPoint,&pGuessParams,&pMaxDeviations,&pParams,&pSolTypes);

//get the parameter point
double parampoint_u;
SafeArrayGetElement(pParams,x_indice,&parampoint_u);

//do the reverse, i.e. get the startpoint from the above obtained
parameter point
SAFEARRAY *pnewStartPoint =NULL ;
Result = pCurveEvaluator->GetPointAtParam(&pParams,&pnewStartPoint);

//get the x, y and z values of the start point
double newstartpoint_x,newstartpoint_y,newstartpoint_z;
SafeArrayGetElement(pnewStartPoint,x_indice,&newstartpoint_x);
SafeArrayGetElement(pnewStartPoint,y_indice,&newstartpoint_y);
SafeArrayGetElement(pnewStartPoint,z_indice,&newstartpoint_z);

//destroy the SAFEARRAYS
SafeArrayDestroy(pStartPoint);
SafeArrayDestroy(pEndPoint);

SafeArrayDestroy(pGuessParams);
SafeArrayDestroy(pMaxDeviations);
SafeArrayDestroy(pParams);
SafeArrayDestroy(pSolTypes);

SafeArrayDestroy(pnewStartPoint);
.............
.............

-Venkatesh Thiyagarajan.

wrote in message news:5241261@discussion.autodesk.com...
Hi there!
I´m using C++.
My goal is to get the tangent at a point of an Edge. To do that I´m trying
to retrieve the parameter for the CurveEvaluator for that point, which I
could then use with CurveEvaluator::GetTangent(...).
After trying to use CurveEvaluator::GetParamAtPoint(...) without any success
(yes, I asked here at the forums) for several weeks I now decided to
implement my own GetParamForPoint function just because I lack any better
ideas.
So, to make things short:
That function would need to get some point on the edge for certain
parameters to check for the distance to the input point. For that, the
CurveEvaluator supplements a GetPointAtParam(...) function.
What I do is the following:
1. Get minimum and maximum parameters for the CurveEvaluator through
GetParamExtents(...), which works fine.
2. Create a SAFEARRAY* called 'param' with one double in it. That double is
a value between minimum and maximum parameters from step 1.
3. Call CurveEvaluator::GetPointAtParam(&param, &p), where p is a SAFEARRAY*
created with 'new SAFEARRAY()'. That call fails. Documentation again failed
to give any clue why that call fails, as well as the HRESULT returned
doesn´t help at all.

The complete block of code for that looks like this (I´ll only post the
first call to GetPointAtParam(...) since the rest of them looks just the
same), evalPtr is a pointer to a CurveEvaluator, paramMin and paramMax are
the boundaries for valid parameters:

SAFEARRAY* p = new SAFEARRAY();
SAFEARRAY* params = SafeArrayCreateVector(VT_R8, 0, 1);
double* data;
SafeArrayAccessData(params, (void**)&data);
memcpy(data, &paramMin, sizeof(double));
SafeArrayUnaccessData(params);

HRESULT hr = evalPtr->GetPointAtParam(&params, &p);
if(FAILED(hr))
{
// I always end up here, as the call to GetPointAtParam
// always fails.
}
SafeArrayAccessData(p, (void**)&data);
CVector3 v = CVector3(data[0], data[1], data[2]);
SafeArrayUnaccessData(p);

As the call already fails when using the minimum parameter for the Evaluator
as input value, I guess I must have gotten something wrong about how to
supply the input parameter to the function, as I think that paramMin should
definitely be valid.

If anybody has ever used GetPointAtParam(...) or (even better)
GetParamAtPoint(...) successfully, I´d be really really happy if he would be
willing to share how he did it as I seem completely unable to get anything
really useful out of that CurveEvaluator.

Thx for reading and your help
0 Likes
Message 4 of 7

Anonymous
Not applicable
Hi there and thx for your reply!
I´ve looked through the CurvatureEngine.cpp and found the example. After seeing that IRxSurfaceEvaluator provides functions that can be used without SAFEARRAYs I looked up IRxCurveEvaluator and it seems it does the same, too.

One problem though:
I use CComPtr< Edge > types to store the edges I use and I seem to be unable to get an IRxCurveEvaluator from them. The conversion from CurveEvaluator** to IRxCurveEvaluator** fails. I´d use IRxEdge* instead as retrieving an IRxCurveEvaluator* from them works, but IRxEdge doesn´t provide CalculateStrokes() which I absolutely need.
So: Is there a way to either convert the CComPtr< Edge > to IRxEdge* or CComPtr< CurveEvaluator > to IRxCurveEvaluator* temporarily to use that GetParamAtPoint(...) function?
If not, the example sadly didn´t help me, as I can´t use those neat functions with "legible" parameters, perhaps those would work.

Message was edited by: matches81
0 Likes
Message 5 of 7

Anonymous
Not applicable
Yay! That solved my problem. However I don´t know why 😉
GetParamAtPoint(...) works now.
First I tried to mimic your code snippet, didn´t work. Then I copied it right over and that worked. After that I changed it to do the things I need (getting parameters for the points I need instead of the start point) and now it works. The only difference from my initial version I can see is that I don´t use SafeArrayCreateVector(...) but your version of the SafeArrayCreate(...) with the SAFEARRAYBOUND.... however I thought that SafeArrayCreateVector(VT_R8, 0, 3) should give the same result, namely a one-dimensional SAFEARRAY with space for 3 doubles?

Anyways, it finally works, retrieving tangents works now, too, and I´m pretty happy. Thanks! Message was edited by: matches81
0 Likes
Message 6 of 7

Anonymous
Not applicable
I should have looked closer at the sample before I recommended it. I just
did a quick search through the samples for "GetParamAtPoint" and that one
came up. The IRx interfaces aren't really suggested for use. In the early
days of the API there was a pure COM interface and an equivalent IDispatch
ingterface. Soon it was decided to go 100% with the IDispatch interface.
The IRx functions are the orginal COM interfaces. I wouldn't recommend
using them.
--
Brian Ekins
Autodesk Inventor API

wrote in message news:5242827@discussion.autodesk.com...
Hi there and thx for your reply!
I´ve looked through the CurvatureEngine.cpp and found the example. After
seeing that IRxSurfaceEvaluator provides functions that can be used without
SAFEARRAYs I looked up IRxCurveEvaluator and it seems it does the same, too.

One problem though:
I use CComPtr< Edge > types to store the edges I use and I seem to be unable
to get an IRxCurveEvaluator from them. The conversion from CurveEvaluator**
to IRxCurveEvaluator** fails. I´d use IRxEdge* instead as retrieving an
IRxCurveEvaluator* from them works, but IRxEdge doesn´t provide
CalculateStrokes() which I absolutely need.
So: Is there a way to either convert the CComPtr< Edge > to IRxEdge* or
CComPtr< CurveEvaluator > to IRxCurveEvaluator* temporarily to use that
GetParamAtPoint(...) function?
If not, the example sadly didn´t help me, as I can´t use those neat
functions with "legible" parameters, perhaps those would work.

Message was edited by: matches81
0 Likes
Message 7 of 7

Anonymous
Not applicable
ah, okay, good to know.
Thank you very much anyhow, ripping that part of my code apart several times and redoing it again because of that example actually helped to make it work 😉
0 Likes