Array of structs to NDarray
Laur-Ivan opened this issue · 2 comments
Hello!
I have somewhat of a weird question. I am using Numpy.NET with the Unity game engine. Most of it works fine, but I am trying to convert an Array of Vector3 to NDarray, but I had no success yet.
Since that's an Unity specific class, I get why it might not work. But might I define a struct as a wrapper and transform an array of structs to the NDarray? The struct would be very simple, holding three floats (x,y,z).
Numpy always usees one dimensional arrays under the hood, in your case a float[]
. With that you create your NDArray and then you reshape it to reflect your multi-dimensional data. Check out reshape documentation and try it on a python console to find out more.
Or you create the NDArray with a two dimensional float[,], but Numpy.NET will internally copy that into a 1D array again as you can see in the code of that constructor.
If you would agree to store the values in a (n, 3) dimension where n is the number of items in the array and 3 is x,y,z in that order.
It seems that Vector3 answers to the constraint 'T : unmanaged' so it can be treated as binary data within unsafe code.
So I'm proposing something like that
struct Vector3 {
public float x;
public float y;
public float z;
}
static unsafe void Main(string[] args) {
Vector3[] myVectors = new Vector3[100];
fixed (Vector3* ptr_vector = myVectors) {
var nd = new Numpy.NDarray(new IntPtr(ptr_vector), (3 * myVectors.Length * sizeof(float)), np.float32);
nd = nd.reshape(myVectors.Length, 3);
//TODO: w/e i wanted to do with 'nd'
}
//do not use 'nd' outside the fixed block
}
If you are looking to use myVectors outside the fixed block then use GCHandle.Alloc(bytesBuffer, GCHandleType.Pinned).AddrOfPinnedObject
to prevent GC from moving it and then use the same NDarray constructor.