Python & C++ Integration
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
Python and C++ integration is a core architectural pillar of the project, enabling a hybrid environment where performance-critical logic is handled by C++ while high-level scripting, automation, and workbench logic are implemented in Python. This dual-language approach allows the system to remain extensible and user-friendly for scripters without sacrificing the computational efficiency required for 3D geometry processing and complex simulations.
Sources: src/Mod/Draft/coding_conventions.md, src/Mod/Fem/coding_conventions.md
The integration infrastructure includes automated binding generation, shared coding conventions to maintain consistency across the language boundary, and specialized build system macros that embed Python scripts directly into C++ binaries.
Architecture and Build System Integration
The build system utilizes CMake to manage the relationship between C++ source files and Python components. This includes generating C++ implementation files from Python interface definitions (.pyi) and embedding initialization scripts.
Automated Binding Generation
The project employs automated tools to bridge C++ and Python. For example, gen-swig-hpp.py generates SWIG interface files and C++ headers to map complex data structures (like KD-Trees) into Python-accessible types.
The diagram shows the build-time generation of SWIG interfaces and headers used to create the Python-to-C++ runtime bridge.
Sources: src/3rdParty/libkdtree/python-bindings/gen-swig-hpp.py:7-14
Embedding Python in C++
The application core embeds Python scripts to handle initialization and testing. Specific CMake macros are used to transform .py files into C++ headers:
generate_from_py: Creates C++ classes from Python definitions.generate_embed_from_py: Embeds scripts likeFreeCADInit.pyandFreeCADTest.pyinto headers for internal execution.
Sources: src/App/CMakeLists.txt:100-117
Data Transfer and Mapping
Mapping between languages involves converting C++ primitive and complex types into Python objects. The integration uses typemaps to handle specific data structures, such as tuples and lists.
| C++ Type/Structure | Python Representation | Mapping Mechanism |
|---|---|---|
std::vector<RECORD_...> | PyList | PyList_New and PyList_SetItem |
record_t (Struct) | PyTuple | PyArg_ParseTuple and PyTuple_SetItem |
| Coordinate Vectors | Python Tuples | Py_BuildValue with format strings (e.g., "(f)") |
Sources: src/3rdParty/libkdtree/python-bindings/gen-swig-hpp.py:31-90
KD-Tree Record Mapping Flow
The conversion of a C++ KD-Tree record to a Python tuple follows a specific sequence to ensure data integrity during the handoff:
The sequence diagram illustrates the step-by-step conversion of C++ record data into a Python-compatible tuple structure.
Sources: src/3rdParty/libkdtree/python-bindings/gen-swig-hpp.py:65-88
Coding Conventions and Standards
To maintain a cohesive codebase across two languages, the project enforces specific naming and formatting rules. While C++ generally uses CamelCase, Python follows PEP 8 standards with some modifications.
Cross-Language Naming Policies
| Component | Python Style | C++ Style |
|---|---|---|
| Modules/Files | snake_case_names.py | CamelCaseNames.cpp |
| Classes | CamelCaseClass | CamelCaseClass |
| Functions | functions_without_capitals() | CamelCaseFunctions() |
| Internal/Auxiliary | Starts with _underscore | - |
Sources: src/Mod/Draft/coding_conventions.md:50-65, src/Mod/Fem/coding_conventions.md:120-125
Interface Separation
Coding conventions dictate that GUI-specific Python code (using FreeCADGui) must be guarded by if FreeCAD.GuiUp: to ensure that headless or console-only functions remain separate from their graphical implementations. This is critical for the "Headless Batch Jobs" feature.
Sources: src/Mod/Draft/coding_conventions.md:43-48, src/Mod/CAM/Roadmap/Functionality/Scripting and automation.md:19-21
Practical Applications
CAM Postprocessing
The CAM workbench demonstrates advanced integration where postprocessors are refactored into an Object-Oriented (OO) Python structure. This allows them to inherit from shared C++ or Python base classes (like the PostProcessor class in Processor.py) to reduce code duplication while maintaining customizability.
Sources: src/Mod/CAM/Roadmap/Epics/ImprovePostprocessors.md:75-85
Documentation and Wiki Generation
The examplePy2wiki.py tool automates the transformation of Python comments and code blocks into MediaWiki-formatted text, facilitating the documentation of integrated C++/Python APIs.
Sources: src/Tools/examplePy2wiki.py:10-25
Conclusion
The integration of Python and C++ is characterized by a structured build process that embeds scripts, generates bindings for complex types like KD-Trees, and enforces strict coding standards. This architecture supports the project's goals of providing an extensible scripting interface while maintaining high-performance core functionality. Future development aims to further object-orient the shared logic in Python to improve customizability for specialized tasks like CAM postprocessing.