diff --git a/differt-core/python/differt_core/__init__.py b/differt-core/python/differt_core/__init__.py index d316611b..d7c9d528 100644 --- a/differt-core/python/differt_core/__init__.py +++ b/differt-core/python/differt_core/__init__.py @@ -3,6 +3,14 @@ The present package only provides lower-level utilities with a focus on performances. + +Currently, Rust uses NumPy's C API to communicate between Python +and Rust, hence casting NumPy arrays to JAX arrays in the process, +thus making it impossible to trace variables used in Rust code. + +In the future, we plan on providing XLA-compatible functions, +so that one can use :mod:`differt_core` and still be able to differentiate +its code. We welcome any contribution on that topic! """ __all__ = ("__version__",) diff --git a/differt-core/python/differt_core/geometry/__init__.py b/differt-core/python/differt_core/geometry/__init__.py index 45786572..3fdf557f 100644 --- a/differt-core/python/differt_core/geometry/__init__.py +++ b/differt-core/python/differt_core/geometry/__init__.py @@ -1 +1 @@ -"""TODO.""" +"""Geometry utilities used by :mod:`differt.geometry`.""" diff --git a/differt-core/python/differt_core/geometry/triangle_mesh.py b/differt-core/python/differt_core/geometry/triangle_mesh.py index e8cb9c6e..f1336191 100644 --- a/differt-core/python/differt_core/geometry/triangle_mesh.py +++ b/differt-core/python/differt_core/geometry/triangle_mesh.py @@ -1,4 +1,4 @@ -"""TODO.""" +"""Triangle mesh utilities used by :mod:`differt.geometry.triangle_mesh`.""" __all__ = ("TriangleMesh",) diff --git a/differt-core/python/differt_core/rt/__init__.py b/differt-core/python/differt_core/rt/__init__.py index 45786572..ee2b7a5e 100644 --- a/differt-core/python/differt_core/rt/__init__.py +++ b/differt-core/python/differt_core/rt/__init__.py @@ -1 +1 @@ -"""TODO.""" +"""Ray Tracing utilities used by :mod:`differt.rt`.""" diff --git a/differt-core/python/differt_core/scene/__init__.py b/differt-core/python/differt_core/scene/__init__.py index 45786572..b3f8578a 100644 --- a/differt-core/python/differt_core/scene/__init__.py +++ b/differt-core/python/differt_core/scene/__init__.py @@ -1 +1 @@ -"""TODO.""" +"""Scene utilities used by :mod:`differt.scene`.""" diff --git a/differt-core/python/differt_core/scene/triangle_scene.py b/differt-core/python/differt_core/scene/triangle_scene.py index 95047f0a..3d1cf7da 100644 --- a/differt-core/python/differt_core/scene/triangle_scene.py +++ b/differt-core/python/differt_core/scene/triangle_scene.py @@ -1,4 +1,4 @@ -"""TODO.""" +"""Triangle scene utilities used by :mod:`differt.scene.triangle_scene`.""" __all__ = ("TriangleScene",) diff --git a/differt-core/src/geometry/triangle_mesh.rs b/differt-core/src/geometry/triangle_mesh.rs index 777fd351..42c6472f 100644 --- a/differt-core/src/geometry/triangle_mesh.rs +++ b/differt-core/src/geometry/triangle_mesh.rs @@ -14,7 +14,7 @@ pub(crate) struct TriangleMesh { face_colors: Option>, face_materials: Option>, #[pyo3(get)] - /// List of material names. + /// list[str]: List of material names. material_names: Vec, object_bounds: Option>, } @@ -119,21 +119,25 @@ impl TriangleMesh { #[pymethods] impl TriangleMesh { - /// TODO. + /// jaxtyping.Float[np.ndarray, 'num_vertices 3']: The array of triangle vertices. #[getter] fn vertices<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray2> { let array = arr2(&self.vertices); PyArray2::from_owned_array_bound(py, array) } - /// TODO. + /// jaxtyping.Int[np.ndarray, 'num_triangles 3']: The array of triangle indices. #[getter] fn triangles<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray2> { let array = arr2(&self.triangles); PyArray2::from_owned_array_bound(py, array) } - /// TODO. + /// jaxtyping.Float[numpy.ndarray, 'num_vertices 3'] | None: The array of face colors. + /// + /// The array contains the face colors, as RGB triplets, + /// with a black color used as defaults (if some faces have a color). + /// This attribute is :data:`None` if all face colors are unset. #[getter] fn face_colors<'py>(&self, py: Python<'py>) -> Option>> { if let Some(face_colors) = &self.face_colors { @@ -143,7 +147,12 @@ impl TriangleMesh { None } - /// TODO. + /// jaxtyping.Int[numpy.ndarray, 'num_vertices'] | None: The array of face materials. + /// + /// The array contains the material indices, + /// with a special placeholder value of :data:`-1`. + /// The obtain the name of the material, see :attr:`material_names`. + /// This attribute is :data:`None` if all face materials are unset. #[getter] fn face_materials<'py>(&self, py: Python<'py>) -> Option>> { if let Some(face_materials) = &self.face_materials { @@ -152,7 +161,11 @@ impl TriangleMesh { None } - /// TODO. + /// jaxtyping.Int[numpy.ndarray, 'num_objects 2'] | None: The array of object indices. + /// + /// If the present mesh contains multiple objects, usually as a result of + /// appending multiple meshes together, this array contain start end end + /// indices for each sub mesh. #[getter] fn object_bounds<'py>(&self, py: Python<'py>) -> Option>> { if let Some(object_bounds) = &self.object_bounds { @@ -163,7 +176,7 @@ impl TriangleMesh { } /// Move all the elements of ``other`` into ``self`` and update - /// :attr`object_bounds`. + /// :attr:`object_bounds`. /// /// After calling this method, ``other`` will be empty. /// @@ -246,6 +259,19 @@ impl TriangleMesh { .push([offset, self.vertices.len()]); } + /// Load a triangle mesh from a Wavefront .obj file. + /// + /// Currently, only vertices and triangles are loaded. Triangle normals + /// are ignored because they are computed with + /// :meth:`differt.geometry.triangle_mesh.TriangleMesh.normals` using + /// JAX so that they can be differentiated with respect to triangle + /// vertices. + /// + /// Args: + /// file (str): The path to the Wavefront .obj file. + /// + /// Returns: + /// TriangleMesh: The corresponding mesh containing only triangles. #[classmethod] pub(crate) fn load_obj(_: &Bound<'_, PyType>, filename: &str) -> PyResult { let input = BufReader::new(File::open(filename)?); @@ -264,6 +290,19 @@ impl TriangleMesh { Ok(obj.into()) } + /// Load a triangle mesh from a Stanford PLY .ply file. + /// + /// Currently, only vertices and triangles are loaded. Triangle normals + /// are ignored because they are computed with + /// :meth:`differt.geometry.triangle_mesh.TriangleMesh.normals` using + /// JAX so that they can be differentiated with respect to triangle + /// vertices. + /// + /// Args: + /// file (str): The path to the Stanford PLY .ply file. + /// + /// Returns: + /// TriangleMesh: The corresponding mesh containing only triangles. #[classmethod] pub(crate) fn load_ply(_: &Bound<'_, PyType>, filename: &str) -> PyResult { let mut input = BufReader::new(File::open(filename)?); diff --git a/differt-core/src/scene/triangle_scene.rs b/differt-core/src/scene/triangle_scene.rs index 931de4a8..d37e4541 100644 --- a/differt-core/src/scene/triangle_scene.rs +++ b/differt-core/src/scene/triangle_scene.rs @@ -5,7 +5,12 @@ use pyo3::{exceptions::PyValueError, prelude::*, types::PyType}; use super::sionna::SionnaScene; use crate::geometry::triangle_mesh::TriangleMesh; -/// A scene that contains one triangle mesh and corresponding materials. +/// A scene that contains one mesh, usually begin the results of multiple call +/// to :meth:`TriangleMesh.append`. +/// +/// This class is only useful to provide a fast constructor for scenes +/// created using the Sionna file format. #[derive(Clone)] #[pyclass] struct TriangleScene { diff --git a/differt/src/differt/geometry/triangle_mesh.py b/differt/src/differt/geometry/triangle_mesh.py index 9bc57d94..42b49eab 100644 --- a/differt/src/differt/geometry/triangle_mesh.py +++ b/differt/src/differt/geometry/triangle_mesh.py @@ -78,15 +78,7 @@ def triangles_contain_vertices_assuming_inside_same_plane( @jaxtyped(typechecker=typechecker) class TriangleMesh(eqx.Module): - """ - A simple geometry made of triangles. - - TODO: extend arguments. - - Args: - vertices: The array of triangle vertices. - triangles: The array of triangle indices. - """ + """A simple geometry made of triangles.""" vertices: Float[Array, "num_vertices 3"] = eqx.field(converter=jnp.asarray) """The array of triangle vertices.""" @@ -98,7 +90,7 @@ class TriangleMesh(eqx.Module): """The array of face colors. The array contains the face colors, as RGB triplets, - with a special placeholder value of :data:`(-1, -1, -1)`. + with a black color used as defaults (if some faces have a color). This attribute is :data:`None` if all face colors are unset. """ face_materials: Int[Array, " num_triangles"] | None = eqx.field( @@ -218,10 +210,9 @@ def bounding_box(self) -> Float[Array, "2 3"]: ) @classmethod - @eqx.filter_jit def empty(cls) -> "TriangleMesh": """ - Create an empty mesh. + Create a empty mesh. Returns: A new empty scene. @@ -253,7 +244,6 @@ def set_face_colors( ) @classmethod - @eqx.filter_jit @jaxtyped(typechecker=typechecker) def plane( cls, diff --git a/differt/src/differt/plotting/_utils.py b/differt/src/differt/plotting/_utils.py index 5a2903b9..27d9794e 100644 --- a/differt/src/differt/plotting/_utils.py +++ b/differt/src/differt/plotting/_utils.py @@ -69,7 +69,7 @@ def get_backend(backend: str | None = None) -> BackendName: """ Return the name of the backend to use. - If data:`None` is provided, then the default + If :data:`None` is provided, then the default backend is returned. Otherwise, the backend corresponding to value of :data:`backend`. diff --git a/differt/src/differt/scene/triangle_scene.py b/differt/src/differt/scene/triangle_scene.py index f9e3f6d4..16441eb3 100644 --- a/differt/src/differt/scene/triangle_scene.py +++ b/differt/src/differt/scene/triangle_scene.py @@ -32,15 +32,7 @@ @jaxtyped(typechecker=typechecker) class TriangleScene(eqx.Module): - """ - A simple scene made of one or more triangle meshes, some transmitters and some receivers. - - Args: - transmitters: The array of transmitter vertices. - receivers: The array of receiver vertices. - meshes: The triangle mesh. - materials: The mesh materials. - """ + """A simple scene made of one or more triangle meshes, some transmitters and some receivers.""" transmitters: Float[Array, "*transmitters_batch 3"] = eqx.field( converter=jnp.asarray, diff --git a/docs/source/conf.py b/docs/source/conf.py index 3654f7be..89b347fb 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -89,7 +89,8 @@ # -- Sphinx autodoc typehints settings -always_document_param_types = True +always_document_param_types = False +autodoc_member_order = "bysource" # We force class variables to appear first # -- MyST-nb settings myst_heading_anchors = 3