C++ Additional Features#

Extending With EVSpace#

Including EVSpace#

If users wish to include the EVSpace library source in their extensions, there are additional C++ helper functions that can be of use. The pyevspace-api.hpp header will detect if the evspace.hpp header has already been included, and if so will make the functions documented on this page available. If you do not want these functions defined in your source code, define the PYEVSPACE_NO_INCLUDE_HEADERS macro before including the pyevspace-api.hpp header. If you do not include evspace.hpp before including the PyEVSpace API header, defining the PYEVSPACE_INCLUDE_HEADERS before including the PyEVSpace header will include evspace.hpp, and make the helper functions available. The EVSpace header is necessary when providing these functions because they directly handle EVSpace types. To understand why these functions are necessary to interface with the extension module with EVSpace types, read the C++ ABI compatibilitiy issues page.

Note

The C PyCapsule is always available to import from the PyEVSpace module, and none of the above actions modify this. The functionality defined on this page is only for extension types compiled as a C++ project, because projects targeting C cannot include a C++ library like EVSpace, and so these functions must not be defined for them. Therefore, the contents of this page are only applicable when the __cplusplus macro is defined, which is done automatically by compilers targeting C++.

When adding the EVSpace source code along with the PyEVSpace API header, you will need to add these include directories to the compiler path:

  • <path-to-pyevspace>/include/

  • <path-to-evspace>/include/

  • <path-to-evspace>/external/

The PyEVSpace test suite includes a small extension module for testing the C capsule and the functions documented here. That file may serve as a reference for how to use these functions in practice, but note the examples in the tests are trivial and only meant to ensure proper behavior during tests.

Additional Features Documentation#

Changed in version 0.16.0: Because the module is now multi-phase initialized, there is no global state, and therefore no global module capsule PyEVSpace_CAPI* variable. As these functions are helpers that wrap capsule functions, there is now no direct access to the capsule to make these function calls. As the user of these methods should be using the capsule anyway, these functions now require the caller to pass a pointer to the module capsule in order to avoid relying on a global state variable, which is mandatory to support multi-phase initialization.

Macros#

PYEVSPACE_INCLUDE_HEADERS#

When defined before including pyevspace-api.hpp, explicitly include the evspace.hpp header and define the helper functions documented on this page.

PYEVSPACE_NO_INCLUDE_HEADERS#

When defined before including pyevspace-api.hpp, do not include the evspace.hpp header or define the helper functions documented on this page.

To EVSpace Conversions#

Changed in version 0.16.0: These functions all now require a pointer to the PyEVSpace module capsule.

int PyEVSpace_ToVector(PyObject *obj, evspace::Vector &vector, PyEVSpace_CAPI *capsule)#

Modify vector so that its internal state matches the state of a pyevspace.Vector type. Return 0 on success, and -1 on failure without modifying vector.

Parameters:
  • obj – must be a PyObject* with the same type as PyEVSpace_CAPI.Vector_Type

  • vector – the vector instance to set equal to obj

  • capsule – a pointer to the module capsule

Return values:
  • 0 – on success

  • -1 – on failure with an appropriate exception set

int PyEVSpace_ToMatrix(PyObject *obj, evspace::Matrix &matrix, PyEVSpace_CAPI *capsule)#

Modify matrix so that its internal state matches the state of a pyevspace.Matrix type. Return 0 on success, and -1 on failure without modifying matrix.

Parameters:
  • obj – must be a PyObject* with the same type as PyEVSpace_CAPI.Matrix_Type

  • matrix – the matrix instance to set equal to obj

  • capsule – a pointer to the module capsule

Return values:
  • 0 – on success

  • -1 – on failure with an appropriate exception set

int PyEVSpace_ToAngles(PyObject *obj, evspace::EulerAngles &angles, PyEVSpace_CAPI *capsule)#

Modify angles so that its internal state matches the state of a pyevspace.EulerAngles type. Return 0 on success, and -1 on failure without modifying angles.

Parameters:
Return values:
  • 0 – on success

  • -1 – on failure with an appropriate exception set

To PyObject* Conversions#

PyObject *PyEVSpaceVector_ToObject(const evspace::Vector &vector, PyEVSpace_CAPI *capsule)#

Creates a pyevspace.Vector object as a PyObject*, specifically a PyEVSpace_CAPI.Vector_Type, whose internal state is equal to the internal state of vector. This function returns a new reference owned by the caller, or NULL on error.

Parameters:
  • vector – the vector whose state is used when creating the PyObject

  • capsule – a pointer to the module capsule

Returns:

a new reference to a Vector_Type as a PyObject*

Return values:

NULL – on failure with an appropriate exception set

PyObject *PyEVSpaceMatrix_ToObject(const evspace::Matrix &matrix, PyEVSpace_CAPI *capsule)#

Creates a pyevspace.Matrix object as a PyObject*, specifically a PyEVSpace_CAPI.Matrix_Type, whose internal state is equal to the internal state of matrix. This function returns a new reference owned by the caller, or NULL on error.

Parameters:
  • matrix – the matrix whose state is used when creating the PyObject

  • capsule – a pointer to the module capsule

Returns:

a new reference to a Matrix_Type as a PyObject*

Return values:

NULL – on failure with an appropriate exception set

PyObject *PyEVSpaceAngles_ToObject(const evspace::EulerAngles &angles, PyEVSpace_CAPI *capsule)#

Creates a pyevspace.EulerAngles object as a PyObject*, specifically a PyEVSpace_CAPI.EulerAngles_Type, whose internal state is equal to the internal state of angles. This function returns a new reference owned by the caller, or NULL on error.

Parameters:
  • angles – the angles whose state is used when creating the PyObject

  • capsule – a pointer to the module capsule

Returns:

a new reference to a EulerAngles_Type as a PyObject*

Return values:

NULL – on failure with an appropriate exception set

ReferenceFrame Components#

int PyEVSpaceFrame_ToAngles(PyObject *obj, evspace::EulerAngles &angles, PyEVSpace_CAPI *capsule)#

Retrieve the rotation angles state from a pyevspace.ReferenceFrame object as a PyObject*, by setting the state of angles equal to the angles state in obj. Returns 0 on success, -1 on failure.

Parameters:
  • obj – must be a PyObject* with the same type as PyEVSpace_CAPI.ReferenceFrame_Type

  • angles – output variable to set equal to the obj angles state

  • capsule – a pointer to the module capsule

Return values:
  • 0 – on success

  • -1 – on failure with an appropriate exception set

int PyEVSpaceFrame_ToOffset(PyObject *obj, evspace::Vector &offset, PyEVSpace_CAPI *capsule)#

Retrive the rotation order state from a pyevspace.ReferenceFrame object as a PyObject*, by setting the state of offset equal to the offset state in obj.

Note

The internal value for pyevspace.ReferenceFrame.offset may be None when no offset is given during construction. Since the state must be returned as a evspace::Vector instance, there is no clean way of signaling when the value is None. Since this value is mathematically analogous to the zero vector, when the offset is None, all offset components will be set to zero.

This function returns 0 on success, -1 on failure.

Parameters:
  • obj – must be a PyObject* with the same type as PyEVSpace_CAPI.ReferenceFrame_Type

  • offset – output variable to set equal to the obj offset state

  • capsule – a pointer to the module capsule

Return values:
  • 0 – on success

  • -1 – on failure with an appropriate exception set

int PyEVSpaceFrame_SetAngles(PyObject *obj, const evspace::EulerAngles &angles, PyEVSpace_CAPI *capsule)#

Set the internal Euler angles state of a pyevspace.ReferenceFrame object as a PyObject* (obj) from a evspace::EulerAngles object. Returns 0 on success, -1 on failure.

Parameters:
  • obj – must be a PyObject* with the same type as PyEVSpace_CAPI.ReferenceFrame_Type

  • angles – angles variable whose state the obj angles state will be set to

  • capsule – a pointer to the module capsule

Return values:
  • 0 – on success

  • -1 – on failure with an appropriate exception set

int PyEVSpaceFrame_SetOffset(PyObject *obj, const evspace::Vector &offset, PyEVSpace_CAPI *capsule)#

Set the internal offset vector state of a pyevspace.ReferenceFrame object as a PyObject* (obj) from a evspace::Vector object. Returns 0 on success, -1 on failure.

Note

There is no clean way to set the internal offset value equal to Py_None. This is mathematically analogous to the zero vector, so all components of offset should be set to 0.0 in this case. Keep in mind, if setting the ReferenceFrame.offset vector using this method, there may be no offset applied, but the returned value is not None as it would be when setting to None during construction.

This function returns 0 on success, -1 on failure.

Parameters:
  • obj – must be a PyObject* with the same type as PyEVSpace_CAPI.ReferenceFrame_Type

  • offset – offset variable whose state the obj offset state will be set to

  • capsule – a pointer to the module capsule

Return values:
  • 0 – on success

  • -1 – on failure with an appropriate exception set