Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/Achint08/visu3d
Browse files Browse the repository at this point in the history
  • Loading branch information
Achint08 committed May 30, 2022
2 parents 644144f + cad21f4 commit 2addbe6
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 28 deletions.
20 changes: 8 additions & 12 deletions .github/workflows/pytest_and_autopublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,21 @@ jobs:
# Auto-publish when version is increased
publish-job:
# Only try to publish if:
# * Repo is etils (prevents running from forks)
# * Repo is self (prevents running from forks)
# * Branch is `main`
if: |
github.repository == 'google-research/visu3d'
&& github.ref == 'refs/heads/main'
needs: pytest-job # Only publish after tests are successful
runs-on: ubuntu-latest
permissions:
contents: write
timeout-minutes: 30

steps:
- uses: actions/checkout@v2

# Setup Python
- uses: actions/setup-python@v2
# Publish the package (if local `__version__` > pip version)
- uses: etils-actions/pypi-auto-publish@v1
with:
python-version: 3.7

# TODO(epot): Activate
# # Publish the package (if local `__version__` < pip version)
# - uses: etils-actions/pypi-auto-publish@v1
# with:
# pypi-token: ${{ secrets.PYPI_API_TOKEN }}
pypi-token: ${{ secrets.PYPI_API_TOKEN }}
gh-token: ${{ secrets.GITHUB_TOKEN }}
parse-changelog: true
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## v1.1.0
<!--
Changelog follow https://keepachangelog.com/ format.
-->

## [Unreleased]

### Changed

* Camera are now displayed with a complete frame.

## [1.1.0] - 2022-05-13

* Normalize `look_at` by default

[Unreleased]: https://github.com/google-research/visu3d/compare/v1.1.0...HEAD
[1.1.0]: https://github.com/google-research/visu3d/releases/tag/v0.3.2
86 changes: 76 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,48 @@
# Visu3d
# v3d

[![Unittests](https://github.com/google-research/visu3d/actions/workflows/pytest_and_autopublish.yml/badge.svg)](https://github.com/google-research/visu3d/actions/workflows/pytest_and_autopublish.yml)
[![PyPI version](https://badge.fury.io/py/visu3d.svg)](https://badge.fury.io/py/visu3d)

`visu3d` is a Python library offering:
### Is v3d for you ?

* An API to make `@dataclass` behave like array.
* Standard primitives for 3d geometry (`Ray`, `Camera`, `Transform`,...).
Yes!

Despite the name, `visu3d` is not limited at all to visualization, nor 3d, but
it can be used in all ML programs (and beyond).

The library provides an abstraction layer on top of TF/Jax/Numpy (same code works
everywhere) at various levels:

* **For all ML programs:** v3d introduces the `DataclassArray` abstraction which
significantly reduces boilerplate/verbosity when manipulating datastructures
by adding numpy-like indexing and vectorization to `dataclasses`. (Future
plans will move this to an independent module.)

On top of `DataclassArray`, v3d introduces:

* **For all 3d programs (Nerf, robotics, ...):** standard primitives (camera,
rays, transformation, ...) that users can use and extend. While those
primitives can be used as-is in production code, they should also serve as a
show-off/inspiration of what can be achieved with `DataclassArray`.

Everything in `v3d` is extensible:

* Your codebase can gradually opt in to specific features you need (e.g.
trivially migrate your `dataclass` to `v3d.DataclassArray` without any other
changes).
* Combine native v3d primitives with your custom ones (see doc below).

On top of the `v3d` primitives:

* **Best Colab experience:** Everything is trivially visualizable with zero
boilerplate. Inspect & debug camera poses, trajectories,....

### Core features

<section class="zippy">

Everything is a `v3d.DataclassArray`: **dataclass behave like `np.array`** (with indexing, slicing, shape manipulation, vectorization,...).

Everything is a `v3d.DataclassArray`: **dataclass behave like `np.array`** (with
indexing, slicing, shape manipulation, vectorization,...).

```python
# Single ray
Expand Down Expand Up @@ -49,10 +78,19 @@ Display multiple objects together:
v3d.make_fig([cam, rays, point_cloud])
```

Auto-plot figures with Colab magic:

```python
v3d.auto_plot_figs() # Once at the start of the Colab

cam, rays, point_cloud # Tuple auto-displayed without `v3d.make_fig` call
```

</section>
<section class="zippy">

Same code seamlessly **works across Jax, TensorFlow, Numpy**.
Same code seamlessly **works across Jax, TensorFlow, Numpy** (please help us for
[torch support](https://github.com/google-research/visu3d/issues/12)).

```python
rays = rays.as_jax() # .as_tf(), as_np(), .as_jax()
Expand Down Expand Up @@ -93,7 +131,8 @@ rays = cam.rays() # Rays in world coordinates
px_coords = cam.px_from_world @ point_cloud
```

See [the API](https://github.com/google-research/visu3d/tree/main/visu3d/__init__.py;l=31)<!-- {.external} !--> for a full list of primitive.
See [the API](https://github.com/google-research/visu3d/tree/main/visu3d/__init__.py;l=31)<!-- {.external} !-->
for a full list of primitive.

</section>
<section class="zippy">
Expand All @@ -102,8 +141,11 @@ Creating your own primitives is trivial.

Converting any dataclass to dataclass array is trivial:

* Inherit from `v3d.DataclassArray`
* Use [`etils.array_types`](https://github.com/google/etils/blob/main/etils/array_types/README.md) to annotate the array fields (or exlicitly use `my_field: Any = v3d.array_field(shape=, dtype=)` instead of `dataclasses.field`)
* Inherit from `v3d.DataclassArray`
* Use
[`etils.array_types`](https://github.com/google/etils/blob/main/etils/array_types/README.md)
to annotate the array fields (or exlicitly use `my_field: Any =
v3d.array_field(shape=, dtype=)` instead of `dataclasses.field`)

```python
from etils.array_types import FloatArray
Expand All @@ -126,6 +168,30 @@ corresponding protocol.

</section>

### Documentation

The best way to get started is to try the Colab tutorials (in the
[docs/](https://github.com/google-research/visu3d/tree/main/docs/)):

* [Intro (Colab)](https://colab.research.google.com/github/google-research/visu3d/blob/main/docs/intro.ipynb)
<!-- {.external} !-->
* [Transform (Colab)](https://colab.research.google.com/github/google-research/visu3d/blob/main/docs/transform.ipynb)
<!-- {.external} !-->
* [Create your primitives (Colab)](https://colab.research.google.com/github/google-research/visu3d/blob/main/docs/dataclass.ipynb)
<!-- {.external} !-->

Installation:

```sh
pip install visu3d
```

Usage:

```python
import visu3d as v3d
```

## Installation

```sh
Expand Down
4 changes: 2 additions & 2 deletions visu3d/array_dataclass_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,12 +281,12 @@ def test_complex_shape(
assert_dc_array_fn(p[0, ..., 0], (2, 1), xnp=xnp)
# Indexing through np.array also supported
assert_dc_array_fn(
p.flatten()[np.ones(p.size, dtype=np.bool)],
p.flatten()[np.ones(p.size, dtype=np.bool_)],
(p.size,),
xnp=xnp,
)
assert_dc_array_fn(
p.flatten()[xnp.ones(p.size, dtype=np.bool)],
p.flatten()[xnp.ones(p.size, dtype=np.bool_)],
(p.size,),
xnp=xnp,
)
Expand Down
29 changes: 26 additions & 3 deletions visu3d/dc_arrays/camera_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@

del abc # TODO(epot): Why pytype don't like abc ?


assert_supports_protocol = functools.partial(
py_utils.assert_supports_protocol,
msg='Required to support camera transformations. See `v3d.Point3d` and '
Expand Down Expand Up @@ -207,9 +206,33 @@ def _get_camera_lines(self) -> FloatArray['*shape 4 3']:
[self.w, self.h],
]
corners_world = self.cam_from_px @ self.xnp.array(corners_px)
start = enp.lazy.np.broadcast_to([0, 0, 0], corners_world.shape)
corners_world = corners_world * self.fig_config.scale
return start, corners_world

start = [
# 4 lines from center -> corners
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
# 4 lines for the frame
corners_world[0],
corners_world[1],
corners_world[2],
corners_world[3],
]
end = [
# 4 lines from center -> corners
corners_world[0],
corners_world[1],
corners_world[2],
corners_world[3],
# 4 lines for the frame
corners_world[1],
corners_world[3],
corners_world[0],
corners_world[2],
]
return self.xnp.asarray(start), self.xnp.asarray(end)


@dataclasses.dataclass(frozen=True)
Expand Down

0 comments on commit 2addbe6

Please sign in to comment.