# 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.

```

coords = cloud.toNpArrayCopy()
if coords.shape != (cloud.size(), 3):
raise RuntimeError
```

The 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, if `False`, reorder with `array.copy(order='C')`.

• The cloud memory is reserved /resized automatically.

## 5.2. Read, modify or create a scalar field with Numpy

There are two ways to access to the scalar field data from Numpy.

```
dic = cloud1.getScalarFieldDic()
sf1 = cloud1.getScalarField(dic['Coord. Z'])
max1 = sf1.getMax()
asf1 = 2*max1         # modification in place
sf1.computeMinAndMax()
```

The above code snippet is from `test002.py`.

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.

## 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)
sf = cl.getScalarField(0)
sf.fromNpArrayCopy(dr)

# --- save the point cloud

```

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`.

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`.