Skip to content

Commit

Permalink
Docstrings for PyMaterialXCore classes.
Browse files Browse the repository at this point in the history
Mostly copied from corresponding C++ header files, but using backticks to
automatically link to relevant sections in the Python API documentation,
e.g. `Document` to link to `PyMaterialXCore.Document.html`.

Using `mod.attr("<name>").doc() = ...` syntax so that this patch only adds
new lines, rather than modifying existing lines.

Using `:see:` fields to link to the corresponding C++ API docs page.

Demo of generated HTML page available here:
https://stefanhabel.github.io/generated/PyMaterialXCore.html

Split from #1567.

Update #342.

Signed-off-by: Stefan Habel <19556655+StefanHabel@users.noreply.github.com>
  • Loading branch information
StefanHabel committed Oct 7, 2024
1 parent 8357e14 commit 1100bf0
Show file tree
Hide file tree
Showing 14 changed files with 370 additions and 0 deletions.
43 changes: 43 additions & 0 deletions source/PyMaterialX/PyMaterialXCore/PyDefinition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ void bindPyDefinition(py::module& mod)
.def_readonly_static("CHANNEL_NODE_GROUP", &mx::NodeDef::CHANNEL_NODE_GROUP)
.def_readonly_static("ORGANIZATION_NODE_GROUP", &mx::NodeDef::ORGANIZATION_NODE_GROUP)
.def_readonly_static("TRANSLATION_NODE_GROUP", &mx::NodeDef::TRANSLATION_NODE_GROUP);
mod.attr("NodeDef").doc() = R"docstring(
A node definition element within a `Document`.
A `NodeDef` provides the declaration of a node interface, which may then
be instantiated as a `Node`.
:see: https://materialx.org/docs/api/class_node_def.html)docstring";

py::class_<mx::Implementation, mx::ImplementationPtr, mx::InterfaceElement>(mod, "Implementation")
.def("setFile", &mx::Implementation::setFile)
Expand All @@ -51,6 +58,14 @@ void bindPyDefinition(py::module& mod)
.def_readonly_static("CATEGORY", &mx::Implementation::CATEGORY)
.def_readonly_static("FILE_ATTRIBUTE", &mx::Implementation::FILE_ATTRIBUTE)
.def_readonly_static("FUNCTION_ATTRIBUTE", &mx::Implementation::FUNCTION_ATTRIBUTE);
mod.attr("Implementation").doc() = R"docstring(
An implementation element within a `Document`.
An `Implementation` is used to associate external source code with a specific
`NodeDef`, providing a definition for the node that may either be universal or
restricted to a specific target.
:see: https://materialx.org/docs/api/class_implementation.html)docstring";

py::class_<mx::TypeDef, mx::TypeDefPtr, mx::Element>(mod, "TypeDef")
.def("setSemantic", &mx::TypeDef::setSemantic)
Expand All @@ -67,12 +82,24 @@ void bindPyDefinition(py::module& mod)
.def_readonly_static("CATEGORY", &mx::TypeDef::CATEGORY)
.def_readonly_static("SEMANTIC_ATTRIBUTE", &mx::TypeDef::SEMANTIC_ATTRIBUTE)
.def_readonly_static("CONTEXT_ATTRIBUTE", &mx::TypeDef::CONTEXT_ATTRIBUTE);
mod.attr("TypeDef").doc() = R"docstring(
A type definition element within a `Document`.
:see: https://materialx.org/docs/api/class_type_def.html)docstring";

py::class_<mx::Member, mx::MemberPtr, mx::TypedElement>(mod, "Member")
.def_readonly_static("CATEGORY", &mx::TypeDef::CATEGORY);
mod.attr("Member").doc() = R"docstring(
A member element within a `TypeDef`.
:see: https://materialx.org/docs/api/class_member.html)docstring";

py::class_<mx::Unit, mx::UnitPtr, mx::Element>(mod, "Unit")
.def_readonly_static("CATEGORY", &mx::Unit::CATEGORY);
mod.attr("Unit").doc() = R"docstring(
A unit declaration element within a `UnitDef`.
:see: https://materialx.org/docs/api/class_unit.html)docstring";

py::class_<mx::UnitDef, mx::UnitDefPtr, mx::Element>(mod, "UnitDef")
.def("setUnitType", &mx::UnitDef::setUnitType)
Expand All @@ -83,10 +110,18 @@ void bindPyDefinition(py::module& mod)
.def("getUnits", &mx::UnitDef::getUnits)
.def_readonly_static("CATEGORY", &mx::UnitDef::CATEGORY)
.def_readonly_static("UNITTYPE_ATTRIBUTE", &mx::UnitDef::UNITTYPE_ATTRIBUTE);
mod.attr("UnitDef").doc() = R"docstring(
A unit definition element within a `Document`.
:see: https://materialx.org/docs/api/class_unit_def.html)docstring";

py::class_<mx::UnitTypeDef, mx::UnitTypeDefPtr, mx::Element>(mod, "UnitTypeDef")
.def("getUnitDefs", &mx::UnitTypeDef::getUnitDefs)
.def_readonly_static("CATEGORY", &mx::UnitTypeDef::CATEGORY);
mod.attr("UnitTypeDef").doc() = R"docstring(
A unit type definition element within a `Document`.
:see: https://materialx.org/docs/api/class_unit_type_def.html)docstring";

py::class_<mx::AttributeDef, mx::AttributeDefPtr, mx::TypedElement>(mod, "AttributeDef")
.def("setAttrName", &mx::AttributeDef::setAttrName)
Expand All @@ -98,8 +133,16 @@ void bindPyDefinition(py::module& mod)
.def("setExportable", &mx::AttributeDef::setExportable)
.def("getExportable", &mx::AttributeDef::getExportable)
.def_readonly_static("CATEGORY", &mx::AttributeDef::CATEGORY);
mod.attr("AttributeDef").doc() = R"docstring(
An attribute definition element within a `Document`.
:see: https://materialx.org/docs/api/class_attribute_def.html)docstring";

py::class_<mx::TargetDef, mx::TargetDefPtr, mx::TypedElement>(mod, "TargetDef")
.def("getMatchingTargets", &mx::TargetDef::getMatchingTargets)
.def_readonly_static("CATEGORY", &mx::TargetDef::CATEGORY);
mod.attr("TargetDef").doc() = R"docstring(
The definition of an implementation target as a `TypedElement`.
:see: https://materialx.org/docs/api/class_target_def.html)docstring";
}
6 changes: 6 additions & 0 deletions source/PyMaterialX/PyMaterialXCore/PyDocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,10 @@ void bindPyDocument(py::module& mod)
.def("setColorManagementConfig", &mx::Document::setColorManagementConfig)
.def("hasColorManagementConfig", &mx::Document::hasColorManagementConfig)
.def("getColorManagementConfig", &mx::Document::getColorManagementConfig);
mod.attr("Document").doc() = R"docstring(
A MaterialX document, which represents the top-level element in the MaterialX ownership hierarchy.
Use the factory function `createDocument()` to create a `Document` instance.
:see: https://materialx.org/docs/api/class_document.html)docstring";
}
73 changes: 73 additions & 0 deletions source/PyMaterialX/PyMaterialXCore/PyElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,18 @@ void bindPyElement(py::module& mod)
BIND_ELEMENT_FUNC_INSTANCE(Token)
BIND_ELEMENT_FUNC_INSTANCE(TypeDef)
BIND_ELEMENT_FUNC_INSTANCE(Visibility);
mod.attr("Element").doc() = R"docstring(
The base class for MaterialX elements.
An `Element` is a named object within a `Document`, which may possess any
number of child elements and attributes.
Inherited by: `TypedElement`, `GeomElement`, `Backdrop`, `Collection`,
`CommentElement`, `GenericElement`, `Look`, `LookGroup`, `NewlineElement`,
`PropertySet`, `TypeDef`, `Unit`, `UnitDef`, `UnitTypeDef`, `VariantSet`,
and `VariantAssign`.
:see: https://materialx.org/docs/api/class_element.html)docstring";

py::class_<mx::TypedElement, mx::TypedElementPtr, mx::Element>(mod, "TypedElement")
.def("setType", &mx::TypedElement::setType)
Expand All @@ -137,6 +149,13 @@ void bindPyElement(py::module& mod)
.def("isMultiOutputType", &mx::TypedElement::isMultiOutputType)
.def("getTypeDef", &mx::TypedElement::getTypeDef)
.def_readonly_static("TYPE_ATTRIBUTE", &mx::TypedElement::TYPE_ATTRIBUTE);
mod.attr("TypedElement").doc() = R"docstring(
The base class for typed elements.
Inherited by: `InterfaceElement`, `ValueElement`, `AttributeDef`,
`GeomPropDef`, `Member`, and `TargetDef`.
:see: https://materialx.org/docs/api/class_typed_element.html)docstring";

py::class_<mx::ValueElement, mx::ValueElementPtr, mx::TypedElement>(mod, "ValueElement")
.def("setValueString", &mx::ValueElement::setValueString)
Expand Down Expand Up @@ -192,18 +211,49 @@ void bindPyElement(py::module& mod)
BIND_VALUE_ELEMENT_FUNC_INSTANCE(booleanarray, mx::BoolVec)
BIND_VALUE_ELEMENT_FUNC_INSTANCE(floatarray, mx::FloatVec)
BIND_VALUE_ELEMENT_FUNC_INSTANCE(stringarray, mx::StringVec);
mod.attr("ValueElement").doc() = R"docstring(
The base class for elements that support typed values.
Inherited by: `PortElement`, `GeomProp`, `Property`, `PropertyAssign`, and
`Token`.
:see: https://materialx.org/docs/api/class_value_element.html)docstring";

py::class_<mx::Token, mx::TokenPtr, mx::ValueElement>(mod, "Token")
.def_readonly_static("CATEGORY", &mx::Token::CATEGORY);
mod.attr("Token").doc() = R"docstring(
A token element representing a string value.
Token elements are used to define input and output values for string
substitutions in image filenames.
:see: https://materialx.org/docs/api/class_token.html)docstring";

py::class_<mx::CommentElement, mx::CommentElementPtr, mx::Element>(mod, "CommentElement")
.def_readonly_static("CATEGORY", &mx::CommentElement::CATEGORY);
mod.attr("CommentElement").doc() = R"docstring(
An element representing a block of descriptive text within a `Document`,
which will be stored as a comment when the document is written out.
The comment text may be accessed with the methods `Element.getDocString()`
and `Element.setDocString()`.
:see: https://materialx.org/docs/api/class_comment_element.html)docstring";

py::class_<mx::NewlineElement, mx::NewlineElementPtr, mx::Element>(mod, "NewlineElement")
.def_readonly_static("CATEGORY", &mx::NewlineElement::CATEGORY);
mod.attr("NewlineElement").doc() = R"docstring(
An element representing a newline within a `Document`.
:see: https://materialx.org/docs/api/class_newline_element.html)docstring";

py::class_<mx::GenericElement, mx::GenericElementPtr, mx::Element>(mod, "GenericElement")
.def_readonly_static("CATEGORY", &mx::GenericElement::CATEGORY);
mod.attr("GenericElement").doc() = R"docstring(
A generic element subclass, for instantiating elements with unrecognized
categories.
:see: https://materialx.org/docs/api/class_generic_element.html)docstring";

py::class_<mx::StringResolver, mx::StringResolverPtr>(mod, "StringResolver")
.def("setFilePrefix", &mx::StringResolver::setFilePrefix)
Expand All @@ -217,10 +267,33 @@ void bindPyElement(py::module& mod)
.def("setGeomNameSubstitution", &mx::StringResolver::setGeomNameSubstitution)
.def("getGeomNameSubstitutions", &mx::StringResolver::getGeomNameSubstitutions)
.def("resolve", &mx::StringResolver::resolve);
mod.attr("StringResolver").doc() = R"docstring(
A helper object for applying string modifiers to data values in the context
of a specific element and geometry.
A `StringResolver` may be constructed through the `Element.createStringResolver()`
method, which initializes it in the context of a specific `Element`, geometry,
and material.
Calling the `StringResolver.resolve()` method applies all modifiers to a
particular string value.
Methods such as `StringResolver.setFilePrefix()` may be used to edit the
stored string modifiers before calling `StringResolver.resolve()`.
:see: https://materialx.org/docs/api/class_string_resolver.html)docstring";

py::class_<mx::ElementPredicate>(mod, "ElementPredicate");
mod.attr("ElementPredicate").doc() = R"docstring(
A function that takes an `Element` and returns a `bool`,
to check whether some criteria has passed.)docstring";

py::register_exception<mx::ExceptionOrphanedElement>(mod, "ExceptionOrphanedElement");
mod.attr("ExceptionOrphanedElement").doc() = R"docstring(
A type of exception that is raised when an `Element` is used after its
owning `Document` has gone out of scope.
:see: https://materialx.org/docs/api/class_exception_orphaned_element.html)docstring";

mod.def("targetStringsMatch", &mx::targetStringsMatch);
mod.def("prettyPrint", &mx::prettyPrint);
Expand Down
5 changes: 5 additions & 0 deletions source/PyMaterialX/PyMaterialXCore/PyException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ namespace mx = MaterialX;
void bindPyException(py::module& mod)
{
static py::exception<mx::Exception> pyException(mod, "Exception");
mod.attr("Exception").doc() = R"docstring(
The base class for exceptions that are propagated from the MaterialX
library to the client application.
:see: https://materialx.org/docs/api/class_exception.html)docstring";

py::register_exception_translator(
[](std::exception_ptr errPtr)
Expand Down
33 changes: 33 additions & 0 deletions source/PyMaterialX/PyMaterialXCore/PyGeom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ void bindPyGeom(py::module& mod)
.def("getCollectionString", &mx::GeomElement::getCollectionString)
.def("setCollection", &mx::GeomElement::setCollection)
.def("getCollection", &mx::GeomElement::getCollection);
mod.attr("GeomElement").doc() = R"docstring(
The base class for geometric elements, which support bindings to geometries
and geometric collections.
Inherited by: `GeomInfo`, `MaterialAssign`, `PropertySetAssign`, and
`Visibility`.
:see: https://materialx.org/docs/api/class_geom_element.html)docstring";

py::class_<mx::GeomInfo, mx::GeomInfoPtr, mx::GeomElement>(mod, "GeomInfo")
.def("addGeomProp", &mx::GeomInfo::addGeomProp)
Expand Down Expand Up @@ -52,9 +60,18 @@ void bindPyGeom(py::module& mod)
BIND_GEOMINFO_FUNC_INSTANCE(floatarray, mx::FloatVec)
BIND_GEOMINFO_FUNC_INSTANCE(stringarray, mx::StringVec)
.def_readonly_static("CATEGORY", &mx::GeomInfo::CATEGORY);
mod.attr("GeomInfo").doc() = R"docstring(
A geometry info element within a `Document`.
:see: https://materialx.org/docs/api/class_geom_info.html)docstring";

py::class_<mx::GeomProp, mx::GeomPropPtr, mx::ValueElement>(mod, "GeomProp")
.def_readonly_static("CATEGORY", &mx::GeomProp::CATEGORY);
mod.attr("GeomProp").doc() = R"docstring(
A geometric property element within a `GeomInfo`.
:see: https://materialx.org/docs/api/class_geom_prop.html
)docstring";

py::class_<mx::GeomPropDef, mx::GeomPropDefPtr, mx::TypedElement>(mod, "GeomPropDef")
.def("setGeomProp", &mx::GeomPropDef::setGeomProp)
Expand All @@ -70,6 +87,18 @@ void bindPyGeom(py::module& mod)
.def("hasGeomProp", &mx::GeomPropDef::hasGeomProp)
.def("getGeomProp", &mx::GeomPropDef::getGeomProp)
.def_readonly_static("CATEGORY", &mx::GeomPropDef::CATEGORY);
mod.attr("GeomPropDef").doc() = R"docstring(
An element representing a declaration of geometric property data.
A `GeomPropDef` element contains a reference to a geometric node and a set
of modifiers for that node. For example, a world-space normal can be
declared as a reference to the `"normal"` geometric node with a space
setting of `"world"`, or a specific set of texture coordinates can be
declared as a reference to the `"texcoord"` geometric node with an index
setting of `"1"`.
:see: https://materialx.org/docs/api/class_geom_prop_def.html
)docstring";

py::class_<mx::Collection, mx::CollectionPtr, mx::Element>(mod, "Collection")
.def("setIncludeGeom", &mx::Collection::setIncludeGeom)
Expand All @@ -87,6 +116,10 @@ void bindPyGeom(py::module& mod)
.def("hasIncludeCycle", &mx::Collection::hasIncludeCycle)
.def("matchesGeomString", &mx::Collection::matchesGeomString)
.def_readonly_static("CATEGORY", &mx::Collection::CATEGORY);
mod.attr("Collection").doc() = R"docstring(
A collection element within a `Document`.
:see: https://materialx.org/docs/api/class_collection.html)docstring";

mod.def("geomStringsMatch", &mx::geomStringsMatch);

Expand Down
29 changes: 29 additions & 0 deletions source/PyMaterialX/PyMaterialXCore/PyInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ void bindPyInterface(py::module& mod)
.def("getConnectedNode", &mx::PortElement::getConnectedNode)
.def("setConnectedOutput", &mx::PortElement::setConnectedOutput)
.def("getConnectedOutput", &mx::PortElement::getConnectedOutput);
mod.attr("PortElement").doc() = R"docstring(
The base class for port elements.
Port elements support spatially-varying upstream connections to nodes.
Inherited by: `Input` and `Output`.
:see: https://materialx.org/docs/api/class_port_element.html)docstring";

py::class_<mx::Input, mx::InputPtr, mx::PortElement>(mod, "Input")
.def("setDefaultGeomPropString", &mx::Input::setDefaultGeomPropString)
Expand All @@ -40,11 +48,22 @@ void bindPyInterface(py::module& mod)
.def("setConnectedInterfaceName", &mx::Input::setConnectedInterfaceName)
.def("getInterfaceInput", &mx::Input::getInterfaceInput)
.def_readonly_static("CATEGORY", &mx::Input::CATEGORY);
mod.attr("Input").doc() = R"docstring(
An input element within a `Node` or `NodeDef`.
An `Input` holds either a uniform value or a connection to a spatially-varying
`Output`, either of which may be modified within the scope of a `Material`.
:see: https://materialx.org/docs/api/class_input.html)docstring";

py::class_<mx::Output, mx::OutputPtr, mx::PortElement>(mod, "Output")
.def("hasUpstreamCycle", &mx::Output::hasUpstreamCycle)
.def_readonly_static("CATEGORY", &mx::Output::CATEGORY)
.def_readonly_static("DEFAULT_INPUT_ATTRIBUTE", &mx::Output::DEFAULT_INPUT_ATTRIBUTE);
mod.attr("Output").doc() = R"docstring(
A spatially-varying output element within a `NodeGraph` or `NodeDef`.
:see: https://materialx.org/docs/api/class_output.html)docstring";

py::class_<mx::InterfaceElement, mx::InterfaceElementPtr, mx::TypedElement>(mod, "InterfaceElement")
.def("setNodeDefString", &mx::InterfaceElement::setNodeDefString)
Expand Down Expand Up @@ -111,4 +130,14 @@ void bindPyInterface(py::module& mod)
BIND_INTERFACE_TYPE_INSTANCE(floatarray, mx::FloatVec)
BIND_INTERFACE_TYPE_INSTANCE(stringarray, mx::StringVec)
.def_readonly_static("NODE_DEF_ATTRIBUTE", &mx::InterfaceElement::NODE_DEF_ATTRIBUTE);
mod.attr("InterfaceElement").doc() = R"docstring(
The base class for interface elements.
An `InterfaceElement` supports a set of `Input` and `Output` elements, with
an API for setting their values.
Inherited by: `GraphElement`, `Implementation`, `Node`, `NodeDef`, and
`Variant`.
:see: https://materialx.org/docs/api/class_interface_element.html)docstring";
}
21 changes: 21 additions & 0 deletions source/PyMaterialX/PyMaterialXCore/PyLook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ void bindPyLook(py::module& mod)
.def("getActiveVisibilities", &mx::Look::getActiveVisibilities)
.def("removeVisibility", &mx::Look::removeVisibility)
.def_readonly_static("CATEGORY", &mx::Look::CATEGORY);
mod.attr("Look").doc() = R"docstring(
A look element within a `Document`.
:see: https://materialx.org/docs/api/class_look.html)docstring";

py::class_<mx::LookGroup, mx::LookGroupPtr, mx::Element>(mod, "LookGroup")
.def("getLooks", &mx::LookGroup::getLooks)
Expand All @@ -56,6 +60,10 @@ void bindPyLook(py::module& mod)
.def_readonly_static("CATEGORY", &mx::LookGroup::CATEGORY)
.def_readonly_static("LOOKS_ATTRIBUTE", &mx::LookGroup::LOOKS_ATTRIBUTE)
.def_readonly_static("ACTIVE_ATTRIBUTE", &mx::LookGroup::ACTIVE_ATTRIBUTE);
mod.attr("LookGroup").doc() = R"docstring(
A look group element within a `Document`.
:see: https://materialx.org/docs/api/class_look_group.html)docstring";

py::class_<mx::MaterialAssign, mx::MaterialAssignPtr, mx::GeomElement>(mod, "MaterialAssign")
.def("setMaterial", &mx::MaterialAssign::setMaterial)
Expand All @@ -66,6 +74,10 @@ void bindPyLook(py::module& mod)
.def("getExclusive", &mx::MaterialAssign::getExclusive)
.def("getReferencedMaterial", &mx::MaterialAssign::getReferencedMaterial)
.def_readonly_static("CATEGORY", &mx::MaterialAssign::CATEGORY);
mod.attr("MaterialAssign").doc() = R"docstring(
A material assignment element within a `Look`.
:see: https://materialx.org/docs/api/class_material_assign.html)docstring";

py::class_<mx::Visibility, mx::VisibilityPtr, mx::GeomElement>(mod, "Visibility")
.def("setViewerGeom", &mx::Visibility::setViewerGeom)
Expand All @@ -80,6 +92,15 @@ void bindPyLook(py::module& mod)
.def("setVisible", &mx::Visibility::setVisible)
.def("getVisible", &mx::Visibility::getVisible)
.def_readonly_static("CATEGORY", &mx::Visibility::CATEGORY);
mod.attr("Visibility").doc() = R"docstring(
A visibility element within a `Look`.
Describes the visibility relationship between two geometries or geometric
collections.
:todo: Add a `Look.geomIsVisible()` method that computes the visibility
between two geometries in the context of a specific `Look`.
:see: https://materialx.org/docs/api/class_visibility.html)docstring";

mod.def("getGeometryBindings", &mx::getGeometryBindings,
py::arg("materialNode") , py::arg("geom") = mx::UNIVERSAL_GEOM_NAME);
Expand Down
Loading

0 comments on commit 1100bf0

Please sign in to comment.