- mmcore
mmcore is a modern CAD engine written in Python with performance-critical parts implemented in Cython. The main goal is to make advanced CAD capabilities as accessible and easy to use as popular scientific computing libraries.
The library provides a comprehensive set of geometric modeling tools, numerical algorithms, and optimization methods specifically designed for CAD applications. It features efficient implementations of NURBS geometry, surface analysis, intersection algorithms, and more.
Note: mmcore is under active development and does not currently guarantee backwards compatibility. The API may change significantly between versions.
-
Geometric Modeling
- Complete NURBS curves and surfaces implementation
- Advanced surface analysis with fundamental forms
- Comprehensive intersection algorithms
- Implicit geometry support with boolean operations
- Primitive shapes and surface analysis tools
-
Numerical Methods
- General purpose optimization algorithms (Newton method, divide-and-conquer)
- Robust numerical integration (RK45 and alternatives)
- Interval arithmetic support
- Advanced intersection algorithms for curves and surfaces
- CAD-specific computational geometry algorithms
-
Performance Optimization
- Critical algorithms implemented in C/C++/Cython
- Fastest NURBS implementation in python.
- BVH (Bounding Volume Hierarchy) for efficient spatial queries
- Vectorized operations outperforming numpy for 2D-4D cases
python3 -m pip install --user --force-reinstall git+https://github.com/contextmachine/mmcore.git@tiny
pypy3 -m pip install --user --force-reinstall git+https://github.com/contextmachine/mmcore.git@tiny
docker pull ghcr.io/contextmachine/mmcore.git:tiny
-
mmcore.geom: Geometric primitives and operations
nurbs.pyx/pxd
: NURBS curves and surfaces implementationimplicit
: Implicit geometry with boolean operationsbvh
: Spatial acceleration structures
-
mmcore.numeric: Algorithms and computations
algorithms
: Optimization and fundamental CAD algorithmsintegrate
: Numerical integration (RK45 and others)interval
: Interval arithmetic implementationintersections
: Comprehensive intersection algorithms (curve x curve, curve x surface, surface x surface)vectors
: High-performance vector operations
-
mmcore.construction: Construction operations
ruled
: Implements a fabric function to construct Ruled NURBSSurface from a two NURBSCurve.
- mmcore.api: High-level interface for common operations (WIP)
- mmcore.renderer: Visualization capabilities (WIP)
- mmcore.topo: Topological operations and mesh handling (WIP)
-
Start with short introduction in the Implementation Examples
-
Check the basic examples in
examples/
:surface_closest_points.py
: Surface analysis and optimizationprimitives/
: Basic geometric shape creationssx/
: Surface-surface intersection examplesimplicit_intersections.py
: Working with implicit geometry
-
Check the short introduction in the Implementation Examples:
- surface_closest_point.md: Detailed algorithm explanations
- Additional implementation examples and best practices
We recommend using NURBS as parametric representations, Although procedural parametric representations are also supported for many operations, due to their properties NURBS representations can be used in algorithms requiring strict robustness.
from mmcore.geom.nurbs import NURBSCurve,NURBSSurface
This creates a simple NURBS curve of degree 3 on 10 control points:
import numpy as np
from mmcore.geom.nurbs import NURBSCurve
curve = NURBSCurve(np.random.random((10,3))) # This
from mmcore.geom.nurbs import NURBSCurve
from mmcore.construction.ruled import ruled
# Create forming curves
curve1=NURBSCurve(...)
curve2=NURBSCurve(...)
# Create a ruled surface
surface = ruled(curve1,curve2)
This example demonstrates such a base operation as closest point on surface
import numpy as np
from mmcore.numeric.closest_point import closest_point_on_surface_batched
# Surface construction
surface=...
# Create a random 3d points
points = np.random.random((100,3))
# Find closest points on surface:
closest_points = closest_point_on_surface_batched(surface, points)
You can find a detailed algorithm explanation here surface_closest_point.md
Algorithms for finding all intersections are fundamental in CAD. In mmcore there are robust implementations for parametric NURBS objects:
- CCX (Curve Curve Intersection)
- CSX (Curve Surface Intersection)
- SSX (Surface Surface Intersection)
Also in experimental mode there are implementations for implicit and procedural objects. However, at the moment it is not guaranteed to find all intersections in the general case (we are working on it).
from mmcore.numeric.intersection.ssx import ssx
# Surfaces construction
surface1=...
surface2=...
# Perform Surface and Surface Intersection
result = ssx(surface1,surface2,tol=0.001)
You can find full examples at examples/ssx/nurbs_nurbs_intersection_1.py and examples/ssx/nurbs_nurbs_intersection_2.py. To display the output of the algorithm install the viewer plugin with:
git clone https://github.com/contextmachine/[email protected]
cd mmcore
python3 -m venv venv
source venv/bin/activate
pip install ".[renderer]"
or
git clone https://github.com/contextmachine/[email protected]
cd mmcore
python3 -m venv venv
source venv/bin/activate
pip install ".[all]"
Implicit representations are less common in commercial frame systems, but like parametric representations have long been well developed in computer graphics. General implicits are implemented in mmcore. It means that the algorithms are suitable for working with any implicits and not only with such widespread implicit forms as SDF.
To create your own implicit object class, all you need to do is inherit from one of the base classes and override the implicit(self,point)
and bounds(self)
methods:
from mmcore.geom.implicit import Implicit2D
class Circle(Implicit2D):
def __init__(self, center, radius):
super().__init__()
self.center = center
self.radius = radius
def bounds(self):
return self.center-self.radius,self.center+self.radius # min point , max point
def implicit(self, xy:'ndarray[float, (2,)] | ndarray[float, (3,)]'):
x, y = xy
return (x - self.center[0])**2 + (y - self.center[1])**2 - self.radius**2 # circle implicit equation
When these methods are implemented, all other methods will be generated automatically.
An example of applying the standard algorithm for finding the intersection curve between two implicits to an implicit cylinder and a custom implicit based on a point cloud:
Closest point, intersections, and others algorithms are also available for implicits in both 2d and 3d cases. Intersection algorithms in 3D are particularly interesting because they show good accuracy and performance, in some cases surpassing commercial packages.
Performance Benchmarks:
Comparison with Rhino 8 for intersection curves computation between solid tubes:
Task Size | CPU Cores | Rhino 8 (sec.) | mmcore (sec.) | Speed Ratio |
---|---|---|---|---|
1 | 1 | 0.027 | 0.033 | 0.82x |
100 | 1 | 2.685 | 1.571 | 1.71x |
100 | 10 | 0.938 | 0.275 | 3.41x |
1000 | 10 | 13.4 | 2.313 | 5.79x |
In mmcore we use implicit representations, in Rhino tubes are represented by BReps.
Results show mmcore excels particularly in parallel processing and batch operations.
Figure: Visualization of tube intersection test case
At the same time, I would like to remind you that these algorithms are currently not guaranteed in the general case and are under active development.
You can find the full code for this example here examples/ssx/implicit_intersections.py
- Python >= 3.9
- numpy
- scipy
- earcut
- pyquaternion
- more-itertools
- steputils
- Development: Cython
- Visualization: plotly, kaleido, pyopengl, pyrr, glfw
- Interactive: IPython
- Use
mmcore.numeric.vectors
instead ofmmcore.geom.vec
for vector operations - Prefer
NURBSCurve
overNURBSSpline
for better algorithms and serialization - For curve-surface intersection, use
mmcore/numeric/intersections/csx/_ncsx.py
- Surface-surface intersection (SSX) implementation is currently reliable only for NURBS surfaces
Contributions are welcome! Please note:
- The project is under active development
- Breaking changes may occur between versions
- Test all changes thoroughly before submitting
- Follow the existing code style and documentation patterns
Licensed under the Apache License, Version 2.0 - see LICENSE for details.