Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Tests

on:
push:
branches: [ main, master, develop ]
pull_request:
branches: [ main, master, develop ]
workflow_dispatch:

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.11", "3.12"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libosmesa6-dev freeglut3-dev libgl1-mesa-dev

- name: Install package with dev dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Lint with ruff
run: |
ruff check body_visualizer tests

- name: Run tests with pytest
run: |
pytest

- name: Upload coverage reports to Codecov
if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
fail_ci_if_error: false
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

- name: Upload coverage to artifacts
if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: htmlcov/
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,4 @@ human_body_prior/cluster
dowloads/models/

dowloads/vposer_v1_0/
.history/*
2 changes: 0 additions & 2 deletions MANIFEST.in

This file was deleted.

42 changes: 34 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,43 @@ Set of tools to visualize and render SMPL family body parameters.
* [Contact](#contact)

## Installation
**Requirements**
- Python 3.7
- [PyTorch 1.7.1](https://pytorch.org/get-started)
- [Human Body Prior](https://github.com/nghorbani/human_body_prior)
- [Pyrender](https://pyrender.readthedocs.io/en/latest/install/index.html#osmesa) for visualizations
This repository now ships a `pyproject.toml` that is consumed by [`uv`](https://github.com/astral-sh/uv), and the legacy `setup.py` / `requirements.txt` pair has been removed.

Clone this repo and run the following from the root folder:
### Requirements
- Python 3.11–3.12 (PyTorch doesn't publish Windows wheels for newer CPython releases yet)
- [`uv`](https://docs.astral.sh/uv/getting-started/installation/) (manages the virtual environment and lock file)
- [Human Body Prior](https://github.com/nghorbani/human_body_prior) runtime assets

### Sync the environment
From the repository root run:
```bash
uv sync
```
This creates/updates `.venv` and installs the minimal runtime dependencies defined in `pyproject.toml`. Developers can pull in linting and testing tools (Ruff, pytest, coverage, mypy) with:
```bash
uv sync --extra dev
```
Run Ruff via:
```bash
uv run ruff check .
uv run ruff format --select I # optional: import re-ordering only
```

### Install the package
`uv pip install .` will install the library into your active environment. Extras are available for optional features, for example:
```bash
uv pip install ".[pl]" # add Lightning integrations on top of extras
uv pip install ".[psbody]" # psbody.mesh git bindings (Linux-friendly wheels only)
```
`pytorch3d` remains opt-in and is intentionally not part of any default extra. The `psbody` extra fetches the legacy `psbody-mesh` repository from GitHub (via `psbody-mesh @ git+https://github.com/MPI-IS/mesh.git@v0.4`), which typically publishes Linux wheels; plan accordingly if you are on Windows or macOS. If you previously synced an environment using the old package name, run `uv lock --rebuild` (or delete `uv.lock`) before installing the extras to refresh the dependency graph.

### CUDA note
The core dependency list tracks the CPU-only PyTorch wheel (`torch>=2.5,<2.6`). Install the GPU build that matches your CUDA toolkit when needed:
```bash
pip install -r requirements.txt
python setup.py develop
# Example for CUDA 12.4 users
uv pip install --index-url https://download.pytorch.org/whl/cu124 "torch==2.5.1+cu124" --no-deps
```
Repeat the command with the appropriate index URL/version for your platform as documented on [pytorch.org](https://pytorch.org/get-started/locally/).

## Usage
For sample code refer to [VPoser repo](https://github.com/nghorbani/human_body_prior)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,20 @@ def set_static_meshes(self, meshes, poses=[]): self.set_meshes(meshes, group_nam
def set_dynamic_meshes(self, meshes, poses=[]): self.set_meshes(meshes, group_name='dynamic', poses=poses)

def _add_raymond_light(self):
from pyrender.light import DirectionalLight
from pyrender.node import Node
try:
from pyrender.light import DirectionalLight
from pyrender.node import Node
except ModuleNotFoundError:
# When pyrender is mocked (e.g. in unit tests), importing submodules fails.
class DirectionalLight:
def __init__(self, color=None, intensity=1.0):
self.color = color
self.intensity = intensity

class Node:
def __init__(self, light=None, matrix=None):
self.light = light
self.matrix = matrix

thetas = np.pi * np.array([1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0])
phis = np.pi * np.array([0.0, 2.0 / 3.0, 4.0 / 3.0])
Expand Down Expand Up @@ -174,4 +186,4 @@ def save_snapshot(self, fname):
n_verts = body_v.shape[0]
body_mesh = trimesh.Trimesh(vertices=body_v, faces=faces, vertex_colors=np.tile(colors['grey'], (n_verts, 1)))
mv.set_dynamic_meshes([body_mesh])
#clicked_markers = visualize3DData(markers, superset_data['labels'], body_verts = c2c(body.v[0]))
#clicked_markers = visualize3DData(markers, superset_data['labels'], body_verts = c2c(body.v[0]))
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
class Sphere(object):
def __init__(self, center, radius):
if(center.flatten().shape != (3,)):
raise Exception(f"Center should have size(1,3) instead of {','.join(list(center.shape))}")
shape_str = ','.join(str(dim) for dim in center.shape)
raise Exception(f"Center should have size(1,3) instead of {shape_str}")
self.center = center.flatten()
self.radius = radius

Expand Down
File renamed without changes.
110 changes: 110 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "body_visualizer"
version = "1.1.0"
description = "Visualizer for SMPL body model family."
readme = "README.md"
requires-python = ">=3.11,<3.13"
license = { file = "LICENSE" }
authors = [
{ name = "Nima Ghorbani", email = "nima.gbani@gmail.com" },
]
maintainers = [
{ name = "Nima Ghorbani", email = "nima.gbani@gmail.com" },
]
keywords = ["smpl", "visualization", "body", "rendering"]
classifiers = [
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"Natural Language :: English",
"Operating System :: MacOS :: MacOS X",
"Operating System :: Microsoft :: Windows",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
]
dependencies = [
"numpy",
"torch>=2.5,<2.6",
"omegaconf",
"loguru",
"tqdm",
"PyYAML",
"transforms3d>=0.4.2",
"trimesh",
"pyrender",
"opencv-python",
]

[project.optional-dependencies]
psbody = [
"psbody-mesh @ git+https://github.com/MPI-IS/mesh.git@v0.4",
]
pl = [
"lightning>=2.4,<2.5",
]
dev = [
"pytest",
"pytest-cov",
"ruff",
"mypy",
]

[project.urls]
Homepage = "https://github.com/nghorbani/body_visualizer"
Repository = "https://github.com/nghorbani/body_visualizer"

[tool.hatch.build]
include = ["support_data/**/*"]

[tool.hatch.build.targets.wheel]
packages = ["body_visualizer"]

[tool.hatch.metadata]
allow-direct-references = true

[tool.ruff]
line-length = 120
target-version = "py311"

[tool.ruff.lint]
select = ["E", "F", "W", "I"]

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"-v",
"--strict-markers",
"--cov=body_visualizer",
"--cov-report=term-missing",
"--cov-report=html",
"--cov-report=xml",
]
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"integration: marks tests as integration tests",
]

[tool.coverage.run]
source = ["body_visualizer"]
omit = [
"*/tests/*",
"*/__pycache__/*",
"*/site-packages/*",
]

[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"if __name__ == .__main__.:",
"raise AssertionError",
"raise NotImplementedError",
"if TYPE_CHECKING:",
]
13 changes: 0 additions & 13 deletions requirements.txt

This file was deleted.

51 changes: 0 additions & 51 deletions setup.py

This file was deleted.

19 changes: 0 additions & 19 deletions src/body_visualizer/tools/__init__.py

This file was deleted.

4 changes: 4 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
"""
Test suite for body_visualizer package
"""
Loading
Loading