/** Converts points into a format understood by the NN algorithm and initializes it */
  public void process(List<Point3D_F64> cloud) {
    nn.init(3);

    // swap the two lists to recycle old data and avoid creating new memory
    Stack<double[]> tmp = unusedNnData;
    unusedNnData = usedNnData;
    usedNnData = tmp;
    // add the smaller list to the larger one
    unusedNnData.addAll(usedNnData);
    usedNnData.clear();

    // convert the point cloud into the NN format
    for (int i = 0; i < cloud.size(); i++) {
      Point3D_F64 p = cloud.get(i);

      double[] d;
      if (unusedNnData.isEmpty()) {
        d = new double[3];
      } else {
        d = unusedNnData.pop();
      }

      d[0] = p.x;
      d[1] = p.y;
      d[2] = p.z;

      usedNnData.add(d);
    }

    // declare the output data for creating the NN graph
    listPointVector.reset();
    for (int i = 0; i < cloud.size(); i++) {
      PointVectorNN p = listPointVector.grow();
      p.reset();
      p.p = cloud.get(i);
      p.index = i;
    }

    findNeighbors();
  }