Types¤
Type Conversion¤
Matching C++/Python types often takes the most of the time and requires careful attention. When implementing C++/Python bindings, follow these key patterns from the existing files or implement your own. If there are specific types you want to implement, review the nanobind tests . Ask questions in discussion section for nanobind typing or follow previous issues. Current implementation provides examples for the following types:
- C++:
- Use
Eigen::Reffor matrix parameters, e.g. to transfer mesh vertex coordinates. - Return complex data as
std::tuple<type, ...>types. - Use
std::vector<type>for list copies otherwise useconst std::vector<type> &. -
Use Eigen Matrix types in vectors
const std::vector<Eigen::Matrix<type, ...>> &instead of reference typeconst std::vector<Eigen::Ref<...>> &. -
Python:
- Use
float64for vertices andint32for faces in numpy arrays - Enforce row-major (C-contiguous) order for matrices
Type Conversion Patterns¤
When implementing C++/Python bindings, follow these established patterns:
Matrix Operations¤
Use Eigen::Ref for efficient matrix passing:
void my_function(const Eigen::Ref<const RowMatrixXd>& vertices,
const Eigen::Ref<const RowMatrixXi>& faces);
Return complex mesh data as tuples:
Enforce proper numpy array types using float64 and int32 in C-contiguous order:
import numpy as np
from compas_cgal.compas_cgal_ext import my_submodule
# Convert mesh vertices and faces to proper numpy arrays
vertices1 = np.asarray(mesh1.vertices, dtype=np.float64)
faces1 = np.asarray(mesh1.faces, dtype=np.int32)
# Pass to C++ function
V, F = my_submodule.my_function(vertices1, faces1)
Vector Types¤
For list data, choose between std::vector for value copies,
const std::vector& for references, and
std::vector<Eigen::Matrix<type, ...>> for matrix vectors.
Bind vector types explicitly:
Access in Python:
# Get vector result
vector_result = my_function()
# Access elements by index
x, y, z = vector_result[0], vector_result[1], vector_result[2]
Follow existing patterns: booleans.cpp: Matrix and tuple handling,
measure.cpp: Array type validation, reconstruction.cpp: Complex data
structures, skeletonization.cpp: Point cloud data, slicer.cpp:
Geometry validation
Type Conversion Best Practices¤
When implementing new functionality:
- Matrix Operations:
// GOOD: Use Eigen::Ref for matrix parameters
void my_function(Eigen::Ref<const RowMatrixXd> vertices);
// BAD: Don't use raw matrices
void my_function(Eigen::MatrixXd vertices);
- Return Types:
// GOOD: Return complex data as tuples
std::tuple<RowMatrixXd, RowMatrixXi> my_mesh_operation();
// BAD: Don't use output parameters
void my_mesh_operation(RowMatrixXd& out_vertices);
- Vector Handling:
// GOOD: Use const references for input vectors
void my_function(const std::vector<double>& input);
// GOOD: Return vectors by value
std::vector<double> MyOperation();
// BAD: Don't use non-const references
void my_function(std::vector<double>& input);
- Matrix Vectors:
// GOOD: Use Matrix types in vectors
std::vector<Eigen::Matrix<double, 3, 1>> points;
// BAD: Don't use Ref types in vectors
std::vector<Eigen::Ref<Eigen::Vector3d>> points;
- Python Integration:
# GOOD: Enforce proper types
vertices = np.array(points, dtype=np.float64)
faces = np.array(indices, dtype=np.int32)
# BAD: Don't rely on automatic conversion
vertices = points # type not enforced
faces = indices # type not enforced
- Error Handling: