5. operations on coordinates, scalar fields, colors, meshes with Numpy
5.1. Read, modify or create cloud coordinates with Numpy
There are two ways to access the cloud coordinates from Numpy.
If you want to modify the data in place, without copy, use
toNpArray()
if you prefer to copy the scalar field data, use
toNpArrayCopy()
cloud = cc.loadPointCloud(getSampleCloud(5.0)) coords = cloud.toNpArrayCopy() if coords.shape != (cloud.size(), 3): raise RuntimeErrorThe above code snippet is from
test004.py
.
You can fill the cloud coordinates with coordsFromNPArray_copy()
.
The array should have a shape (numberOfPoints,3).
WARNING Be sure to have an array data in C-style contiguous order. For instance, a transpose operation do not reorder the data in memory. Check the boolean array.flags
array.flags['C_CONTIGUOUS']
and, ifFalse
, reorder witharray.copy(order='C')
.The cloud memory is reserved /resized automatically.
See below An example of point cloud with scalar field created from Numpy arrays.
5.2. Read, modify or create a scalar field with Numpy
There are two ways to access to the scalar field data from Numpy.
If you want to modify the data in place, without copy, use
toNpArray()
dic = cloud1.getScalarFieldDic() sf1 = cloud1.getScalarField(dic['Coord. Z']) max1 = sf1.getMax() asf1 = sf1.toNpArray() # access to Numpy array, without copy asf1[0] = 2*max1 # modification in place sf1.computeMinAndMax()The above code snippet is from
test002.py
.
if you prefer to copy the scalar field data, use
toNpArrayCopy()
You can fill a cloud scalar field with fromNpArrayCopy()
.
The method checks if the scalar field and the array have the same size, before copy.
See below An example of point cloud with scalar field created from Numpy arrays.
5.3. An example of point cloud with scalar field created from Numpy arrays
# --- generate a set of coords and a scalar field
npts = 10000000
phi = 2*np.pi*np.random.random((npts))
theta = 2*np.pi*np.random.random((npts))
r = 5 + 0.3*np.sin(2*2*np.pi*phi + 3*2*np.pi*theta)
x = np.float32(r*np.sin(phi)*np.cos(theta))
y = np.float32(r*np.sin(phi)*np.sin(theta))
z = np.float32(r*np.cos(phi))
coords = np.column_stack((x,y,z))
dr = np.float32(np.sqrt(x*x + y*y + z*z) -5)
# --- create the pointCloud, add the scalar field
cl = cc.ccPointCloud("boule")
cl.coordsFromNPArray_copy(coords)
cl.addScalarField("delta")
sf = cl.getScalarField(0)
sf.fromNpArrayCopy(dr)
# --- save the point cloud
res = cc.SavePointCloud(cl, os.path.join(dataDir, "boule.bin"))
The above code snippet is from test017.py
.
5.4. Access to the indexes of triangles nodes in a mesh
In a mesh, the array of triangles indexes has a shape(number of triangles, 3), with indexes corresponding to the indexes of nodes in the associated cloud.
The method IndexesToNpArray()
gives access to the array without copy.
the corresponding nodes coordinates are given by the method toNpArray()
from the associated cloud (getAssociatedCloud()
.
The method IndexesToNpArray_copy()
creates a copy of the array of indexes.
# --- access to the numpy array of node indexes (one row per triangle)
d = mesh1.IndexesToNpArray()
if d.shape != (19602, 3):
raise RuntimeError
if d.dtype != np.dtype('uint32'):
raise RuntimeError
d2 = mesh1.IndexesToNpArray_copy()
if d2.shape != (19602, 3):
raise RuntimeError
if d2.dtype != np.dtype('uint32'):
raise RuntimeError
The above code snippet is from test011.py
.
5.5. Access to the array of colors in cloud
The colors are stored in an array of shape(number of nodes, 4), the four components are R, G, B and alpha, each stored in a 8bits integer.
The method colorsToNpArray()
gives access to the array of colors without copy,
the method colorsToNpArrayCopy()
creates a copy of the array.
cola = cloud.colorsToNpArray()
if not cola.shape == (1000000, 4):
raise RuntimeError
if not cola.dtype == 'uint8':
raise RuntimeError
colaCopy = cloud.colorsToNpArrayCopy()
if not colaCopy.shape == (1000000, 4):
raise RuntimeError
if not colaCopy.dtype == 'uint8':
raise RuntimeError
The above code snippet is from test029.py
.