Fri, 08/19/2022 - 17:02
Hi all
I am writing a program that creates geometric models, with each geometric element is defined in a class which holds the parameters and also the calling functions. Therefore there are 1D and 2D arrays to be initialised every time a class instance is created. So far I managed to create NCollection_Array1 objects without special initialisation, however with NCollection_Array2 objects I am unable to assign values to them (rather unsurprising given the "should be used with caution" warning in the documentation). However, I also failed to create a proper constructor to the arrays, I'm sure I'm missing something here. Below is an example with default constructor to illustrate:
class surface
{
public:
//example internal variables
Standard_Integer udegree;
Standard_Integer vdegree;
TColgp_Array2OfPnt Poles;
TColgp_Array1OfReal Uknots;
TColgp_Array1OfReal Vknots;
protected:
//example surface
Handle(Geom_BSplineSurface) Surface;
public:
//parameters are initialized here
void parameters_init();
//surface created here
void surface_init();
};
surface::parameters_init()
{
//assume udegree, vdegree initialized and poles and knots values given
//Uknots, Vknots and Poles are resized correctly
Uknots.Resize(umin, umax, vmin, vmax);
Vknots.Resize(umin, umax, vmin, vmax);
Poles.Resize(umin, umax, vmin, vmax);
//Uknots and Vknots are assigned correctly, trying to assign Poles with gp_Pnt incurs in segmentation fault
//Similar for other types of 2D arrays such as TColStd_Array2OfReal
Uknots.SetValue(umin, Uknot_value);
Vknots.SetValue(vmin, Vknot_value);
Poles.SetValue(umin, vmin, gp_Pnt(xmin, ymin, zmin);
}
I tried to create a default constructor for the class such as the one below so that the arrays are properly initialised, however I could not find an initalisation that works, and the compiler errors don't make sense to me.
class surface
{
surface();
//(...)
}
surface::surface()
{
Points(1,1,1,1);
}
I guess I could store the data using shared_ptr but I was looking for a more elegant solution. I am using C++17 with GCC 12.1 and OCC 7.6.2 from the Msys2 package.
Thanks!
Mon, 08/22/2022 - 10:13
This code sample makes no sense to me - C++ initialization list should look like "surface::surface() : Points (1, 1, 1, 1) {}".
NCollection_Array2 has no ::Resize() method that takes 4 arguments, so the code should not compile. Method description takes 5 mandatory arguments - the latter indicating if old values in array should be copied or discarded:
Thu, 08/25/2022 - 10:10
Hi Kirill! Thanks very much for your reply. I apologise for the spelling errors, I tried to simplify the code into something understandable and ended up making some mistakes that I didn't catch.
Just wanted to follow up that the issue was a tad bit more complicated. The OCC version that I was using for compilation was in reality 7.5.3.1 and not 7.6.2. For some reason either in 7.5.3.1 (or GCC versions before 12.2?) it is not possible to create an unitialised NCollection_Array2 (although I've only tested with reals and gp_Pnt). The fact that the compiler will throw strange errors like complaining that 1 is not a Standard_Integer and also the NCollection_Array2 documentation ("use with caution") made it quite hard to find the issue. I'd be curious if someone else would be able to see the same issue since the definition of NCollection_Array2 did not change between the OCC versions, but at least it is solved for now.
The issue can be isolated using the example code below, if the error is present the code should fail after printing Array1:
Expected result:
Thu, 08/25/2022 - 12:11
OCCT 7.5 has a bug in NCollection_Array2::Resize() method fixed in OCCT 7.6, if that would make any help to your findings.
Thu, 08/25/2022 - 13:47
That's the one with 99% certainty. Thank you very much for the information, much appreciated!