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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ devel_isolated/
# Ignore generated docs
*.dox
*.wikidoc
docs/source/generated/

# eclipse stuff
.project
Expand Down
21 changes: 21 additions & 0 deletions docs/source/_static/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,24 @@
overflow: visible !important;
}
}


/* Copyright (left) + GitHub link (right) on one row, wrapping gracefully
on narrow viewports instead of overflowing. A slightly smaller font
than body text keeps both on one line at normal widths. */
footer div[role="contentinfo"] {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: baseline;
font-size: 0.8em;
}

footer div[role="contentinfo"] p {
margin-bottom: 0;
}

.footer-github-link {
white-space: nowrap;
}

8 changes: 8 additions & 0 deletions docs/source/_templates/autosummary/class.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{{ fullname | escape | underline}}

.. currentmodule:: {{ module }}

.. autoclass:: {{ objname }}
:members:
:undoc-members:
:show-inheritance:
5 changes: 5 additions & 0 deletions docs/source/_templates/footer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% extends "!footer.html" %}
{% block contentinfo %}
{{ super() }}
<a href="https://github.com/jhavl/spatialgeometry" class="footer-github-link">GitHub</a>
{% endblock %}
166 changes: 146 additions & 20 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,174 @@ API Reference

.. currentmodule:: spatialgeometry

Class summary
=============

Spatial geometry classes for 3D shapes and scene graph management.

.. autosummary::
:toctree: generated

SceneNode
SceneGroup
Shape
CollisionShape
CollisionShapeGroup

The class hierarchy for all Spatial Geometry classes is shown below:

.. inheritance-diagram::
spatialgeometry.Shape
spatialgeometry.Axes
spatialgeometry.Arrow
spatialgeometry.Path
spatialgeometry.CollisionShape
spatialgeometry.CollisionShapeGroup
spatialgeometry.Mesh
spatialgeometry.Cylinder
spatialgeometry.Cuboid
spatialgeometry.Sphere
spatialgeometry.Ellipsoid
spatialgeometry.Box
spatialgeometry.SceneNode
spatialgeometry.SceneGroup
:parts: 1
:top-classes: spatialgeometry.SceneNode, collections.UserList



Collision shapes
================

These are the basic 3D geometric shapes that can be rendered into a scene, and can also
be used for collision detection.

.. autosummary::

Cuboid
Sphere
Ellipsoid
Cylinder
Mesh
Box

These shapes all inherit from:

* the :class:`CollisionShape` base class which means they can be used for collision detection, and
* the :class:`SceneNode` base class which means they can be nodes in a scene graph to allow visualization and
animation of complex scenes.

Collision shapes also support the collision operator ``&`` which returns True if the two shapes are colliding, and False otherwise. For example:

.. runblock:: pycon

from spatialgeometry import Cuboid, Sphere
from spatialmath import SE3

c = Cuboid(scale=[1, 2, 3])
s1 = Sphere(1, pose=SE3(4, 0, 0))
s2 = Sphere(1, pose=SE3(0, 0, 0))

c & s1
c & s2


.. autoclass:: Cuboid
:members:
:undoc-members:
:show-inheritance:
:inherited-members:
:exclude-members: collided

.. autoclass:: Sphere
:members:
:undoc-members:
:show-inheritance:
:inherited-members:
:exclude-members: collided

.. autoclass:: Cylinder
:members:
:undoc-members:
:show-inheritance:
:inherited-members:
:exclude-members: collided

.. autoclass:: Ellipsoid
:members:
:undoc-members:
:show-inheritance:
:inherited-members:
:exclude-members: collided

.. autoclass:: Box
:members:
:undoc-members:
:show-inheritance:
:inherited-members:
:exclude-members: collided

.. autoclass:: Mesh
:members:
:undoc-members:
:show-inheritance:
:inherited-members:
:exclude-members: collided

Shape
Axes
Arrow
CollisionShape
Mesh
Cylinder
Cuboid
Sphere
Box
SceneNode
SceneGroup


Shapes
======

.. automodule:: spatialgeometry.geom.Shape
These are the basic 3D geometric shapes that can be rendered into a scene, but they cannot
be used for collision detection.

.. autosummary::

Axes
Arrow
Path

They all inherit directly from the :class:`Shape` base class.

.. autoclass:: Axes
:members:
:undoc-members:
:show-inheritance:
:inherited-members:

.. autoclass:: Arrow
:members:
:undoc-members:
:show-inheritance:
:inherited-members:

Collision shapes
=================

.. automodule:: spatialgeometry.geom.CollisionShape
.. autoclass:: Path
:members:
:undoc-members:
:show-inheritance:
:inherited-members:


Scene Graphs
============

.. autoclass:: SceneNode
:members:
:undoc-members:
:show-inheritance:
:inherited-members:

Scene graph
===========

.. automodule:: spatialgeometry.geom.SceneNode
.. autoclass:: SceneGroup
:members:
:undoc-members:
:show-inheritance:
:inherited-members:

.. automodule:: spatialgeometry.geom.SceneGroup
.. autoclass:: CollisionShapeGroup
:members:
:undoc-members:
:show-inheritance:
:inherited-members:
:exclude-members: collided
89 changes: 87 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# -- Project information -----------------------------------------------------

project = 'Spatial Geometry'
copyright = '2020, Jesse Haviland and Peter Corke'
copyright = '2020-present, Jesse Haviland and Peter Corke'
author = 'Jesse Haviland and Peter Corke'

# Parse version number out of pyproject.toml
Expand Down Expand Up @@ -62,13 +62,98 @@
mermaid_height = "auto"

autosummary_generate = True
autodoc_member_order = 'bysource'

# Merge each class's own docstring with its (MRO-resolved) __init__
# docstring on autoclass:: pages -- most shape __init__s have no docstring
# of their own and inherit Shape.__init__'s pose/color/stype/base docs,
# which otherwise never surface (Sphinx's default 'class' setting shows
# only the class docstring, never __init__'s).
autoclass_content = 'both'

# Alphabetical (Sphinx's own default) rather than 'bysource' -- this is a
# reference page meant for looking up a member you already know the name
# of, not a narrative to read top-to-bottom in definition order.
autodoc_member_order = 'alphabetical'

# Sphinx's own 'alphabetical' sort is plain case-sensitive string
# comparison, so e.g. "T" (a property) sorts before "attach" rather than
# alongside the rest of the a's. No config option controls this.
#
# FRAGILE: the older, semi-public sphinx.ext.autodoc.Documenter.sort_members
# method still exists but is dead code for this build -- as of Sphinx
# 9.1.0 the real sort lives in a private, version-specific internal
# (sphinx.ext.autodoc._dynamic._member_finder._sort_members, called as a
# plain same-module function, not a method). Found by grepping the
# installed package for '.sort(' after patching the documented method had
# no effect. If a Sphinx upgrade moves this again, this patch silently
# stops taking effect (falls back to Sphinx's own case-sensitive order)
# rather than erroring -- if member order looks wrong again after
# upgrading Sphinx, this is the first place to check.
import sphinx.ext.autodoc._dynamic._member_finder as _member_finder

_orig_sort_members = _member_finder._sort_members


def _sort_members_case_insensitive(documenters, order, **kwargs):
if order == 'alphabetical':
documenters.sort(key=lambda entry: entry[0].full_name.lower())
return documenters
return _orig_sort_members(documenters, order, **kwargs)


_member_finder._sort_members = _sort_members_case_insensitive

# Show "Shape" rather than "spatialgeometry.geom.Shape.Shape" in class
# headers, signatures and cross-references.
add_module_names = False

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

exclude_patterns = ['test_*']


# Every autoclass:: directive in api.rst uses :inherited-members:, so a
# subclass page (e.g. Cuboid) lists CollisionShape's and Shape's members
# indistinguishably from its own -- :show-inheritance: only adds a single
# "Bases: X" line at the top of the page, it doesn't label individual
# members. This hook appends an "Inherited from" note to each member's
# docstring when it isn't actually defined on the class whose page it's
# being rendered on.
#
# Relies on __qualname__ being set at the point of original definition and
# never rewritten by inheritance (true for plain methods and for a
# property's fget/fset individually) -- NOT reliable for a property that
# overrides only its setter while reusing the base class's getter (e.g.
# Mesh.color): fget.__qualname__ still points at the base class, so a
# genuinely-overridden setter goes unlabelled. No case like that needs the
# label anyway (the point is finding where unfamiliar members come from,
# not ones a class visibly redefines), so this is left unhandled.
def _label_inherited_members(app, what, name, obj, options, lines):
if what not in ("method", "attribute", "property"):
return

parts = name.rsplit(".", 2)
if len(parts) != 3:
return
_, cls_name, _ = parts

target = obj.fget if isinstance(obj, property) else obj
qualname = getattr(target, "__qualname__", None)
if not qualname or "." not in qualname:
return

defining_cls_name = qualname.rsplit(".", 1)[0]
if defining_cls_name == cls_name or "." in defining_cls_name:
return

lines.append("")
lines.append(f"*Inherited from* :class:`~spatialgeometry.{defining_cls_name}`.")


def setup(app):
app.connect("autodoc-process-docstring", _label_inherited_members)

# options for spinx_pyrunblock, used for inline examples
# Python session setup, turn off color printing for SE3, set NumPy precision
autorun_languages = {}
Expand Down
Loading
Loading