Skip to content

Commit

Permalink
feat(lib): first working prototype (#1)
Browse files Browse the repository at this point in the history
* wip(lib): first steps

* chore: still wip

* chore: wip

* wip: add basic tests

* chore: fixes

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

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

* wip

* Auto stash before merge of "prototype" and "origin/prototype"

* chore(ci): trying to fix tests

* feat: is it all done?

* chore: thicker markers

* chore: should be good

* chore: update README.md

* chore: remove example

* chore(ci): setup ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
jeertmans and pre-commit-ci[bot] committed Jun 18, 2024
1 parent 5947056 commit 41bb857
Show file tree
Hide file tree
Showing 16 changed files with 1,628 additions and 1 deletion.
36 changes: 36 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Upload Packages

on:
push:

release:
types: [published]

jobs:
publish-python:
name: Publish Python package
runs-on: ubuntu-latest
environment: release
permissions:
# IMPORTANT: this permission is mandatory for trusted publishing
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Rye
env:
RYE_INSTALL_OPTION: --yes
run: |
curl -sSf https://rye.astral.sh/get | bash
echo "$HOME/.rye/shims" >> $GITHUB_PATH
- name: Configure Rye
run: rye config --set-bool behavior.use-uv=true

- name: Build package
run: rye build

- name: Publish to PyPI
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
68 changes: 68 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
on:
push:
branches:
- main
pull_request:
workflow_dispatch:

name: Tests

env:
QT_QPA_PLATFORM: offscreen
DISPLAY: :99

jobs:
pytest:
strategy:
fail-fast: false
matrix:
os: [macos-13, ubuntu-latest, windows-latest]
pyversion: ['3.9', '3.10', '3.11'] # 3.8 is not supporter by Rye, 3.12 by Sionna
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Rye
if: matrix.os != 'windows-latest'
env:
RYE_TOOLCHAIN_VERSION: ${{ matrix.pyversion}}
RYE_INSTALL_OPTION: --yes
run: |
curl -sSf https://rye.astral.sh/get | bash
echo "$HOME/.rye/shims" >> $GITHUB_PATH
# Stolen from https://github.com/bluss/pyproject-local-kernel/blob/2b641290694adc998fb6bceea58d3737523a68b7/.github/workflows/ci.yaml
- name: Install Rye (Windows)
if: matrix.os == 'windows-latest'
shell: bash
run: |
C:/msys64/usr/bin/wget.exe -q 'https://github.com/astral-sh/rye/releases/latest/download/rye-x86_64-windows.exe' -O rye-x86_64-windows.exe
./rye-x86_64-windows.exe self install --toolchain-version ${{ matrix.pyversion }} --modify-path -y
echo "$HOME\\.rye\\shims" >> $GITHUB_PATH
- name: Configure Rye
shell: bash
run: |
rye config --set-bool behavior.use-uv=true
rye pin ${{ matrix.pyversion }}
- name: Install Linux dependencies
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install freeglut3-dev xvfb
sudo apt-get install x11-utils
nohup Xvfb $DISPLAY -screen 0 1400x900x24 -dpi 96 +extension RANDR +render &
- name: Install Mesa
if: matrix.os == 'windows-latest'
uses: ssciwr/setup-mesa-dist-win@v2

- name: Install local package
shell: bash
run: rye sync

- name: Run pytest
shell: bash
run: rye run pytest
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# python generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info

# venv
.venv
34 changes: 34 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: check-yaml
- id: check-toml
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.13.0
hooks:
- id: pretty-format-yaml
args: [--autofix]
- id: pretty-format-toml
exclude: poetry.lock
args: [--autofix, --trailing-commas]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.8
hooks:
- id: ruff
args: [--fix]
types_or: [python, pyi, jupyter]
- id: ruff-format
types_or: [python, pyi, jupyter]
- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.367
hooks:
- id: pyright
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
additional_dependencies:
- tomli
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.11.8
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and follows the Sionna versioning:
`(sionna_major, sionna_minor, sionna_patch, fix)`.

The three first parts indicate the official supported version of
Sionna, and `fix` is used to indicate patch version
for our library.

<!-- start changelog -->

(unreleased)=
## [Unreleased](https://github.com/jeertmans/sionna-vispy/compare/v0.18.0...HEAD)

(v0.18.0)=
## [v0.18.0](https://github.com/jeertmans/sionna-vispy/commits/v0.18.0)

(v0.18.0-added)=
### Added

- Created first package.
[#1](https://github.com/jeertmans/sionna-vispy/pull/1)

<!-- end changelog -->
128 changes: 127 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,129 @@
# sionna-vispy

Describe your project here.
A [VisPy](https://github.com/vispy/vispy)
backend to preview
[Sionna](https://github.com/NVlabs/sionna) scenes
that works both inside and **outside** Jupyter Notebook.

<p align="center">
<img alt="Example VisPy canvas" width="480" src="https://github.com/jeertmans/sionna-vispy/assets/27275099/40905bb3-8851-43bf-9374-35a331fa0b59">
</p>

This library consists of two parts:

1. a VisPy-based `InteractiveDisplay` to replace `sionna.rt.previewer`;
2. and a `patch()` context manager that dynamically replaces
the old pythreejs previewer with the new VisPy previewer.

## Installation

For the best out-of-the-box experience, we recommend
installing with Pip with `recommended` extras:

```bash
pip install sionna-vispy[recommended]
```

This will install this package, as well as PySide6 and jupyter-rfb,
so that `scene.preview(...)` works inside and **outside** Jupyter Notebooks.

Alternatively, you can install sionna-vispy with:

```bash
pip install sionna-vispy
```

And later install your preferred
[VisPy backend(s)](https://vispy.org/installation.html).

## Usage

The VisPy scene previewer works both
inside and **outside** Jupyter Notebooks.

First, you need to import the package (import order does not matter):

```python
import sionna_vispy
```

Next, the usage of `patch` depends on the environment,
see the subsections.

> [!NOTE]
> If `with patch():` is called before any
> call to `scene.preview(...)`,
> then you only need to call
> `patch()` once.
### Inside Notebooks[^1]

Very simply, rewrite any

```python
scene.preview(...)
```

with the following:

```python
with sionna_vispy.patch():
canvas = scene.preview()

canvas
```

> [!WARNING]
> `canvas` must be the return variable
> of the cell, because the `with` context
> does not return an instance of
> `InteractiveDisplay`.
[^1]: Note that you need `jupyter_rfb` to work inside Jupyter Notebooks.

### Outside Notebooks

Canvas need to be *shown* and the VisPy application
must be started to open a window:

```python
with sionna_vispy.patch():
canvas = scene.preview(...)

canvas.show()
canvas.app.run()
```

## How it works

This package replaces the pythreejs previewer with some
VisPy implementation by
[*monkey-patching*](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch)
`sionna.rt.scene.InteractiveDisplay`.

Additionally, `patch()` will (by default) look at
any existing `sionna.rt.scene.Scene` class instance in the local
namespace of the callee, and temporarily replace any
existing preview widget to make sure to use the new previewer. You can
opt-out of this by calling `patch(patch_existing=False)` instead.

## Design goals

This package aims to be a very minimal replacement to the pythreejs
previewer, with maximum compatibility.

As a result, **it does not aim to provide any additional feature**.

Instead, it aims at providing a very similar look to that of
pythreejs, with all the nice features that come with VisPy.

## Contributing

This project welcomes any contribution, and especially:

+ bug fixes;
+ graphical improvements to closely match the original pythreejs previewers;
+ or documentation typos.

As stated above, new features are not expected to be added, unless they are also
added to the original pythreejs previewer.
Loading

0 comments on commit 41bb857

Please sign in to comment.