AcDbSpline constructor problem

AcDbSpline constructor problem

Anonymous
Not applicable
1,034 Views
5 Replies
Message 1 of 6

AcDbSpline constructor problem

Anonymous
Not applicable

Dear colleagues,

 

I have a problem wit AcDbSpline constructor, it always behaves like default constructor. I try:

 

 

AcDbSpline *tmp = new AcDbSpline(ptAry, kChord);
or
AcDbSpline *tmp = new AcDbSpline(ptAry);

 

but nothing, it is always default constructor. I create points array like this:

 

 

AcGePoint3dArray ptAry(6);
for (int n = 0; n < 6; n++)
{
double x = 0, y = 0;
x = ...;
y = ...;
ptAry[n].set(x, y, 0);
}

And it seems OK because later I can draw AcDbLine using the points from the ptAry. 

 

What am I missing here?

 

 

0 Likes
Accepted solutions (1)
1,035 Views
5 Replies
Replies (5)
Message 2 of 6

tbrammer
Advisor
Advisor

If this is actually your code, than your array initialization is wrong!

 

AcGePoint3dArray ptAry(6);
for (int n = 0; n < 6; n++)
	ptAry[n].set(x, y, 0);

The first line constructs an array with a physical  length of 6 elements. But it still has a logical  length of 0!

In other words: ptAry.length()=0. So you are calling the AcDbSpline() constructor with an empty array of points.

 

See acarray.h:

AcArray< T, R > ::AcArray(int physicalLength, int growLength)
: mpArray(nullptr),
  mPhysicalLen(physicalLength),
  mLogicalLen(0),    <-------------------- !!
  mGrowLen(growLength)  [...}

 

Use ptAry.setLogicalLength(6) before the for-loop to fix this.

Or use ptAry.append(pt) instead of. These methods will increment the logical length for you.

 

 

In case your ptAry is ok:

The ARX docs for the AcDbSpline() constructors say:

 

    If any of the parameters are not acceptable, then the gelib object for the spline is not created and this constructor

    behaves like the default constructor (that is, the passed in values are not used and the data query methods on the

    spline return invalid values).

 

The constructors you are using are:

 

    AcDbSpline(const AcGePoint3dArray& fitPoints,
               int                     order = 4,  //order=degree+1
               double                  fitTolerance = 0.0);
			   
    AcDbSpline(const AcGePoint3dArray& fitPoints,
               AcGe::KnotParameterization    knotParam,
               int                     degree = 3, //order=degree+1
               double                  fitTolerance = 0.0);

The first one is deprecated according to the ARX 2018 docs. You shouldn't use it anymore. the second one should work.

 

I would suggest to use the default constructor and setFitData(...) / setNurbsData(...) methods and look at their retured ErrorStatus to find out what is going wrong.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
Message 3 of 6

Anonymous
Not applicable

Thanks for suggestions. I will try them tomorrow at work and let you know about results.

 

1. Regarding array initialization:

What confuses me is that I can use array initialized and filled in this way to draw AcDbLines. I will set logical length explicitly to 6 at the beginning and try that way.

 

2. Regarding AcDbSpline constructors:

We should use the second one you mentioned, the first one is deprecated, all clear. I just wanted to point out that none of them work in my case.

If the setting logical length doesn't help, I will try default constructor and setFitData(...) / setNurbsData(...) to see return values.

 

 

0 Likes
Message 4 of 6

tbrammer
Advisor
Advisor
Accepted solution

bjevtic wrote:

 

1. Regarding array initialization:

What confuses me is that I can use array initialized and filled in this way to draw AcDbLines. I will set logical length explicitly to 6 at the beginning and try that way.


Have a look at the implementation of the AcArray<T> methods. As it is a template class they are all in the header acarray.h.

Look at operator[](int i) and isValid(int i):

 

 

template <class T, class R> inline T&
AcArray<T,R>::operator [] (int i)
{ AC_ARRAY_ASSERT(this->isValid(i)); return mpArray[i]; }

template <class T, class R> inline bool
AcArray<T,R>::isValid(int i) const
{ return i >= 0 && i < mLogicalLen; }

 

 

ptAry[i] will return the i-th array elment ptAry.mpArray[i] - if  AC_ARRAY_ASSERT(isValid(i))  doesn't stop the program.

isValid(i) will return false - so it depends on the definition of AC_ARRAY_ASSERT:

 

#ifdef ASSERT
#define AC_ARRAY_ASSERT ASSERT
#elif defined assert
#define AC_ARRAY_ASSERT assert
#elif defined _ASSERTE
#define AC_ARRAY_ASSERT _ASSERTE
#else
#define AC_ARRAY_ASSERT(T)
#endif

So if neither ASSERT nor assert nor _ASSERTE is defined your logically  empty array behaves as if it has the correct logical length.

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
Message 5 of 6

Anonymous
Not applicable

!!!!, i got it now. i can access the elements (memory) to write and read but the array is logically still 0. i haven't seen this implementation.

 

that's the problem for sure, cant wait to test it tomorrow.

 

thanks for help

 

(edit: no curse words on the forum...)

0 Likes
Message 6 of 6

Anonymous
Not applicable

that was it.

setLogicalLength()

thanks a lot for the help!

 

0 Likes