Skip to content

Commit

Permalink
Update readme with conda/pip bindings (#100)
Browse files Browse the repository at this point in the history
* update readme with conda/pip bindings

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
CCInc and pre-commit-ci[bot] authored Feb 16, 2022
1 parent 91e70d7 commit f5de2fa
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 121 deletions.
61 changes: 61 additions & 0 deletions NAMING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@


### Naming Convention

#### C++

We mostly use Google's [Style Guide](https://google.github.io/styleguide/cppguide.html).
```c++

namespace name
{
class ClassName
{
public:
// Default constructor
ClassName() = default;
ClassName(int public_variable, int private_variable, bool private_read_only)
: public_variable(public_variable), private_variable_(private_variable),
private_read_only_(private_read_only){};

int public_variable{};

// Getters and Setters
void PrivateVariable(int private_variable) { private_variable_ = private_variable; }
int PrivateVariable() const { return private_variable_; }
bool PrivateReadOnly() const { return private_read_only_; }

// Any other function
int PrivateVariablePlusOne() const { return private_variable_ + 1; }
int SumPublicAndPrivate() const { return public_variable + private_variable_; }
static std::string ReturnEmptyString() { return {}; }

private:
int private_variable_{};
bool private_read_only_{false};
};
} // namespace name
```
#### Python
```python
test_class = ClassName(public_variable=1,private_variable=2,private_read_only=True)
# using pybind .def_readwrite
test_class.public_variable = 4
assert test_class.public_variable == 4
# using pybind .def_property
test_class.private_variable = 5
assert test_class.private_variable == 5
# using pybind .def_property_readonly
assert test_class.private_read_only == True
# using pybind .def
assert test_class.PrivateVariablePlusOne() == 6
assert test_class.SumPublicAndPrivate() == 9
# using pybind .def_static
assert test_class.ReturnEmptyString == ""
```
181 changes: 60 additions & 121 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
# copc-lib

copc-lib is a library which provides an easy-to-use reader and writer interface for [COPC](https://copc.io/) point clouds. This project provides a complete interface for handling COPC files, so that no additional LAZ or LAS libraries are required.
copc-lib provides an easy-to-use reader and writer interface for [COPC](https://copc.io/) point clouds, with bindings for python and C++.

## Build from source
## Installation

### Dependencies
The quickest way to get started with copc-lib is with our conda and pip packages.

### Conda
Conda includes both the C++ and python bindings:

```bash
conda install -c conda-forge copc-lib
```

### Pip
Pip provide only python bindings:

```bash
pip install copclib
```

### Building from source

#### Dependencies

copc-lib has the following dependencies:

- laz-perf>=[3.0.0](https://github.com/hobu/laz-perf/releases/tag/3.0.0)
- Catch2
- Pybind11
- Catch2 (test suite only)
- Pybind11 (python bindings only)

To install dependencies:
To install all dependencies:
```bash
conda install -c conda-forge "laz-perf>=3.0" Catch2 pybind11
```

### C++
#### C++

```bash
git clone https://github.com/RockRobotic/copc-lib.git
Expand All @@ -28,13 +46,24 @@ cmake --build .
sudo cmake --install .
```

### Python
#### Python

```bash
git clone https://github.com/RockRobotic/copc-lib.git
pip install ./copc-lib
```

#### Example Files & Unit Tests

To build the copc-lib examples and unit tests along with the main library, you must enable them:

```bash
mkdir build && cd build
cmake .. -DWITH_TESTS=ON -DWITH_PYTHON=ON
cmake --build .
ctest # All tests should pass
```

## Usage

The `Reader` and `Writer` objects provide the primary means of interfacing with your COPC files. For more complex use cases, we also provide additional objects such as LAZ Compressors and Decompressors (see [example/example-writer.cpp](example/example-writer.cpp)).
Expand All @@ -53,30 +82,32 @@ add_executable(funlib fun-main.cpp)
target_link_libraries(funlib COPCLIB::copc-lib LAZPERF::lazperf)
```

#### Example Files & Unit Tests

To build the copc-lib examples and unit tests along with the main library, you must enable them:

```bash
mkdir build && cd build
cmake .. -DWITH_TESTS=ON
cmake --build .
```
The primary public interface will be your [FileReader](./cpp/include/copc-lib/io/reader.hpp) and [FileWriter](./cpp/include/copc-lib/io/writer.hpp) objects. Check the headers and [example files](./example) for documentation.

Then, you can run the unit tests and the examples:
```cpp
#include <iostream>
#include <copc-lib/io/reader.hpp>

```bash
ctest # All tests should pass

cd bin
./example_reader
./example_writer
void main()
{
// Create a reader object
FileReader reader("autzen-classified.copc.laz");

// Get the node metadata from the hierarchy
auto node = reader.FindNode(copc.VoxelKey(0, 0, 0, 0));
// Fetch the points of a node
auto points = reader.GetPoints(node);

// Iterate through each point
for (const auto &point : points)
std::cout << "X: " << point.X ", Y: " << point.Y << ", Z: " << point.Z << std::endl;
}
```

Alternatively, you can build the test and example files from their respective CMakeLists, assuming copc-lib is already installed.

### Python

[Example files](./example) are also provided for python.

```python
import copclib as copc

Expand All @@ -89,41 +120,11 @@ node = reader.FindNode(copc.VoxelKey(0, 0, 0, 0))
points = reader.GetPoints(node)

# Iterate through each point
for point in points.Get():
print(point)
for point in points:
print(point.x, point.y, point.z)
```

## Coming Soon

- \[x\] Basic C++ Reader Interface
- \[x\] Return Point structures from the reader rather than raw char\* arrays, to support a more familiar laspy-like interface.
- \[x\] Add writer for COPC data
- \[x\] Python bindings
- \[x\] JavaScript bindings (not planned, see below)
- \[x\] Spatial querying for nodes (given spatial coordinates, retrieve the appropriate Entry object)
- \[ \] Conda and pip packages

## Conformity to Spec

This version of copc-lib is pinned to a draft version of COPC respective of the state at [COPC.io](https://github.com/copcio/copcio.github.io/tree/a6e8654f65db7c7d438ebea90993bd7a8d59091a).

### ``extended stats`` VLR

| User ID | Record ID |
| -------------------------- | ---------------- |
| ``rock_robotic`` | ``10001`` |

We additionally add an ``extended stats extents`` VLR to store mean and (population) variance values for each dimension. This VLR can be parsed in the same way as the ``extents`` VLR defined by the COPC spec.

struct CopcExtentExtended
{
double mean; // replaces minimum
double var; // replaces maximum
}

This VLR is optional to process existing COPC files. If present, mean/variance are set appropriately for each dimension in `CopcExtents`; if not, `CopcExtents` will have default values of `mean=0` and `var=1`.

This VLR is only written by the `Writer` if the flag `has_extended_stats` is true in `CopcConfigWriter::CopcExtents`.
Note that, in python, dimension names for points follow the [laspy naming scheme](https://laspy.readthedocs.io/en/latest/intro.html#point-format-6), with the exception of `scan_angle`.

## Helpful Links

Expand All @@ -137,68 +138,6 @@ Pull requests are welcome. For major changes, please open an issue first to disc

Please make sure to update tests as appropriate.

### Naming Convention

#### C++

We mostly use Google's [Style Guide](https://google.github.io/styleguide/cppguide.html).
```c++

namespace name
{
class ClassName
{
public:
// Default constructor
ClassName() = default;
ClassName(int public_variable, int private_variable, bool private_read_only)
: public_variable(public_variable), private_variable_(private_variable),
private_read_only_(private_read_only){};

int public_variable{};

// Getters and Setters
void PrivateVariable(int private_variable) { private_variable_ = private_variable; }
int PrivateVariable() const { return private_variable_; }
bool PrivateReadOnly() const { return private_read_only_; }

// Any other function
int PrivateVariablePlusOne() const { return private_variable_ + 1; }
int SumPublicAndPrivate() const { return public_variable + private_variable_; }
static std::string ReturnEmptyString() { return {}; }

private:
int private_variable_{};
bool private_read_only_{false};
};
} // namespace name
```
#### Python
```python
test_class = ClassName(public_variable=1,private_variable=2,private_read_only=True)
# using pybind .def_readwrite
test_class.public_variable = 4
assert test_class.public_variable == 4
# using pybind .def_property
test_class.private_variable = 5
assert test_class.private_variable == 5
# using pybind .def_property_readonly
assert test_class.private_read_only == True
# using pybind .def
assert test_class.PrivateVariablePlusOne() == 6
assert test_class.SumPublicAndPrivate() == 9
# using pybind .def_static
assert test_class.ReturnEmptyString == ""
```

Note that dimension names for points follow the [laspy naming scheme](https://laspy.readthedocs.io/en/latest/intro.html#point-format-6), with the exception of `scan_angle`.

## License

Please see [LICENSE.md](LICENSE.md)
Expand Down

0 comments on commit f5de2fa

Please sign in to comment.