# PointCNN: five benchmark numbers from 2018, a Tensorflow 1.6 floor, and a requirements file that misses h5py

> The NeurIPS 2018 PointCNN implementation in Python and Tensorflow 1.6. The architecture lives in one file and its hyperparameters in tuples of K, D, P, C and links, the classification script is run through a shell wrapper with a GPU flag, and the only release is a single tag from October 2018.

**yangyanli/PointCNN** — PointCNN: Convolution On X-Transformed Points (NeurIPS 2018)

- Repository: https://github.com/yangyanli/PointCNN
- Website: https://arxiv.org/abs/1801.07791
- Stars: 1,435 · Forks: 358
- Language: Python
- License: NOASSERTION
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/yangyanli-pointcnn

## A file and a directory share the name pointcnn_cls

The top of the repository carries two shapes of the same name. There is pointcnn_cls.py and a pointcnn_cls directory, pointcnn_seg.py and a pointcnn_seg directory, and the same pairing for pointnetpp_cls. Which of the pair an import picks depends on what is inside the directory and on the order of sys.path, and the file never says which one is meant to win. The roles it does assign are narrower: the core X-Conv and the PointCNN architecture are defined in pointcnn.py, and the network, training and data augmentation hyperparameters for classification live in the pointcnn_cls directory while the segmentation equivalents live in pointcnn_seg. The two flat modules are left unmentioned, as are pointfly.py and pointnetpp_cls.py, neither of which the file explains. A pages config, _config.yml, sits in the same tree, which is what a repository uses when it publishes a project page, while the homepage field points at the arXiv abstract instead.

## The prose asks for h5py, and requirements.txt does not have it

The dependency paragraph says the code has dependencies on some python packages such as transforms3d, h5py, plyfile, and maybe more if it complains, and tells you to install them before use. The declared list tells a different story. requirements.txt holds nine lines: matplotlib, plyfile, python-mnist, requests, scipy, svgpathtools, tensorflow-gpu>=1.6.0, tqdm and transforms3d. h5py is not among them, although the prose names it second. python-mnist, svgpathtools and matplotlib appear in the file and are never mentioned in the prose, and python-mnist in particular points at a dataset library in a repository whose documented datasets are ModelNet40, ScanNet and ShapeNet Parts. Installing with pip install -r requirements.txt therefore does not satisfy the instruction as written, which is what the maybe more if it complains clause is really describing: a dependency list that is known to be incomplete, shipped anyway. The two package-manager paths also disagree on the framework itself, since the file asks for the gpu build specifically.

## The 1.5 workaround edits a header inside Tensorflow

The usage section states that PointCNN is implemented and tested with Tensorflow 1.6 in python3 scripts, and that Tensorflow before 1.5 is not recommended because of the API. requirements.txt agrees on the floor and puts it at tensorflow-gpu>=1.6.0. Then the paragraph for people stuck on 1.5 offers an edit to /usr/local/lib/python3.5/dist-packages/tensorflow/include/tensorflow/core/framework/numeric_types.h, changing isnan() to std::nan() on line 49. That path is inside the installed framework, not inside this repository, so the documented fix is to modify a shared library in site-packages on Ubuntu 14.04 and lose the change on the next reinstall or on another machine. It also sits below the floor the requirements file sets, so a project that follows requirements.txt never needs it. Two different Tensorflow versions are being described in the same paragraph block, one as the tested configuration and one as the environment where the reader actually lives, and the fix offered for the second one is a patch to a third party's headers.

## Every X-Conv layer is one tuple of K, D, P, C and links

The hyperparameters are declared as tuples and zipped into dicts against a name tuple, which makes each layer a single readable line. Taking shapenet_x8_2048_fps.py as the example:

```
xconv_param_name = ('K', 'D', 'P', 'C', 'links')
xconv_params = [dict(zip(xconv_param_name, xconv_param)) for xconv_param in
                [(8, 1, -1, 32 * x, []),
                 (12, 2, 768, 32 * x, []),
                 (16, 2, 384, 64 * x, []),
                 (16, 6, 128, 128 * x, [])]]

xdconv_param_name = ('K', 'D', 'pts_layer_idx', 'qrs_layer_idx')
xdconv_params = [dict(zip(xdconv_param_name, xdconv_param)) for xdconv_param in
                  [(16, 6, 3, 2),
                   (12, 6, 2, 1),
                   (8, 6, 1, 0),
                   (8, 4, 0, 0)]]
```

K is the neighborhood size, D the dilation rate, P the number of representative points in the output, where -1 means every input point becomes an output representative point, and C the number of output channels. The fifth field, links, adds DenseNet style connections, so [-1, -2] tells the current layer to receive inputs from the previous two layers. Two of the four X-Conv layers above share C at 32 * x while the later pair double it, and the file name carries x8 and 2048 and fps without the file saying what the x multiplier scales.

## X-DeConv indexes back into the X-Conv list

The decoder is configured by reference instead of by channel count. Each entry in xdconv_params is a tuple of K, D, pts_layer_idx and qrs_layer_idx, where K and D mean what they mean above, pts_layer_idx names which X-Conv layer's output feeds this X-DeConv layer, and qrs_layer_idx names which X-Conv layer's output is forwarded and fused with the decoder output. The P and C values for a decoder layer are not written down at all: they are derived from qrs_layer_idx. Read the four entries and the wiring is visible. The first decoder layer takes points from X-Conv layer 3 and fuses with layer 2, the second takes points from layer 2 and fuses with layer 1, and the last two both take points from layer 0 while the final one fuses with layer 0 as well. Changing a decoder entry therefore changes topology, not just width, and the reference form means a reordered xconv_params list silently re-points every decoder tuple that names an index.

## The accuracy numbers are pinned to a date, not a release

Five records are quoted as of Jan. 23, 2018: classification accuracy on ModelNet40 at 91.7% with 1024 input points only, classification accuracy on ScanNet at 77.9%, segmentation part averaged IoU on ShapeNet Parts at 86.13%, segmentation mean IoU on S3DIS at 65.39%, and per voxel labelling accuracy on ScanNet at 85.1%. The qualifier matters, because the repository has exactly one tag, v1.0, named NIPS 2018 Release and dated 2018-10-25. The figures were measured about nine months before that tag, and the file attaches them to no commit. Sections further down point at three newer benchmarks, the ScanObjectNN paper, PartNet and ABC, and the four measured records are not re-scored on any of them, so the headline table cannot be read as a current standing. The arXiv preprint at 1801.07791 is linked as the source for more details, and the project homepage field points at the same abstract rather than at a documentation site.

## Pretrained weights come from a personal cloud share link

One line covers model weights, and it points outside the repository: pretrained models can be downloaded from a onedrv.ms share link. There is no release asset for them, no checksum and no version label attached to that link in the file. The only release in this repository is the 2018 tag, so anyone taking the weights has no in-repository way to tell which checkpoint the link is serving, or whether it changed since. The same header also points readers away from this code: a banner introduces PointCNN++ at the ant-research/pointelligence repository, describing a modernized codebase, improved performance and ongoing development, and asks researchers and developers to check that repository for state of the art results. So the file reads as a signpost for maintained work with the original kept in place for reference. Four third-party ports are listed for people who want the idea in another framework, PyTorch Geometric, a Berkeley course project, MXNet and Jittor.

## The ScanNet recipe stops in the middle of a path

Classification has a four-line recipe: enter data_conversions, run python3 ./download_datasets.py -d modelnet, step into ../pointcnn_cls and run ./train_val_modelnet.sh with -g 0 and -x modelnet_x3_l4. The GPU flag and the experiment name are the whole interface. Segmentation is a longer path that starts outside the repository, since ScanNet task data and the label map have to be downloaded from scan-net.org and the benchmark files from the ScanNet repository, and it insists on a directory layout holding data, scannet_labelmap and benchmark. The last command moves the label map into the benchmark directory, changes into data_conversions again and calls extract_scannet_objs.py with a path argument that ends at ../../data/scan and stops there. The line is incomplete in the file, so the dataset path has to be worked out from the layout block above it. Compare that with the three Esri write-ups, on 3D cities, on replacing 50,000 man hours with AI, and on point cloud segmentation through the ArcGIS API for Python, which are the only place the code is shown being used rather than run.

## Conclusion

PointCNN is worth reading as the clearest published statement of the X-Conv idea, and it is not something to install unchanged on a current machine. Three things decide that: the code targets Tensorflow 1.6 and the only documented escape route for 1.5 edits a header inside the installed framework, the declared dependency list omits h5py while the prose asks for it, and the model weights sit behind a personal cloud share link rather than a release asset. Check the license before reuse, since the repository metadata names no identifier while the file text says MIT. For new work the authors point at PointCNN++ instead, and the code here last moved on 2026-03-12 behind a single v1.0 tag dated 2018-10-25.

## FAQ

### Which Tensorflow version does PointCNN need?

The code is implemented and tested with Tensorflow 1.6 in python3 scripts, and the file says Tensorflow before 1.5 is not recommended because of the API. The declared dependency is tensorflow-gpu>=1.6.0. For readers forced onto 1.5 by their operating system, the file suggests editing numeric_types.h in the installed Tensorflow to change isnan() to std::nan().

### What Python packages do I need to install for PointCNN?

The prose names transforms3d, h5py and plyfile, plus maybe more if it complains. requirements.txt lists matplotlib, plyfile, python-mnist, requests, scipy, svgpathtools, tensorflow-gpu>=1.6.0, tqdm and transforms3d, so h5py has to be installed by hand and several listed packages are never named in the text.

### Where are the X-Conv parameters of PointCNN set?

The core X-Conv and PointCNN architecture are defined in pointcnn.py, while the network, training and data augmentation hyperparameters for classification live in pointcnn_cls and the segmentation ones in pointcnn_seg. The worked example is shapenet_x8_2048_fps.py, where each X-Conv layer is a tuple of K, D, P, C and links.

### What accuracy numbers does PointCNN claim?

Five records as of Jan. 23, 2018: 91.7% classification accuracy on ModelNet40 with 1024 input points only, 77.9% classification accuracy on ScanNet, 86.13% part averaged IoU on ShapeNet Parts, 65.39% segmentation mean IoU on S3DIS, and 85.1% per voxel labelling accuracy on ScanNet. The repository's single tag, v1.0, is dated 2018-10-25.

### Is PointCNN the current work of its authors?

The file opens with a banner pointing to PointCNN++ in the ant-research/pointelligence repository, describing a modernized codebase, improved performance and ongoing development, and asks readers to check there for state of the art results. In this repository the only release is the v1.0 tag from 2018-10-25, and the last commit on record is dated 2026-03-12.

### What license applies to the PointCNN code?

The file states that the code is released under the MIT License and points at a LICENSE file in the root of the tree. The repository's license metadata does not carry a license identifier, so the two sources disagree and the LICENSE file is the place to check.

## Sources

- [Issues](https://github.com/yangyanli/PointCNN/issues)
- [Project website](https://arxiv.org/abs/1801.07791)
- [README](https://github.com/yangyanli/PointCNN/blob/master/README.md)
- [Releases](https://github.com/yangyanli/PointCNN/releases)
- [yangyanli/PointCNN on GitHub](https://github.com/yangyanli/PointCNN)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/yangyanli-pointcnn
