Python N-Dimensional Bezier, RationalBezier, BSpline and NURBS library with C++ Backend.
Project description
splinepy
splinepy is a python library for splines of arbitrary dimensions and degrees. The library supports Bezier, Rational Bezier, BSpline and NURBS with fast and easy-to-use APIs.
Install guide
splinepy wheels are available for python3.6+ for MacOS, Linux, and Windows:
pip install --upgrade pip
pip install splinepy
It is also possible to install current development version using pip
. It requires a compiler that supports C++17 or higher (C++20 for debug mode - tested with gcc-10.3 and clang-12). Here are two variants:
- Fast build - minimal and debug mode
SPLINEPY_MINIMAL_DEBUG_BUILD=True pip install git+https://github.com/tataratat/splinepy.git@main -vvv
- Same build as in PyPI - full set of splines and optimized build
pip install git+https://github.com/tataratat/splinepy.git@main -vvv
-vvv
is not necessary, but we suggest using it, since you can see the build progress. Full build (the second option) may take a while.
Of course, you can install directly from the source.
In addition to aforementioned compilers, this requires a cmake3.16+. If you don't have cmake, easiest way to install it would be: pip install cmake
.
git clone git@github.com:tataratat/splinepy.git
cd splinepy
git submodule update --init --recursive
python3 setup.py install
For visualization and extended functionalities, please take a look at gustaf!
Quick start
import splinepy
import numpy as np
# Initialize bspline with any array-like input
bspline = splinepy.BSpline(
degrees=[2, 1],
knot_vectors=[
[0.0, 0.0, 0.0, 1.0, 1.0, 1.0],
[0.0, 0.0, 1.0, 1.0],
],
control_points=[
[0.0, 0.0], # [0, 0] (control grid index)
[0.5, 0.0], # [1, 0]
[1.0, 0.0], # [2, 0]
[0.0, 1.0], # [0, 1]
[0.5, 1.0], # [1, 1]
[1.0, 1.0], # [2, 1]
],
)
# We always store control points in 2D arrays with shape
# (total_number_of_control_points, physical_dimension).
# The indexing of the control grid is defined by iterating
# lower-indexed dimensions first. But if you prefer a
# grid-like structure, try
multi_index = bspline.multi_index
grid_cps = np.empty(bspline.control_points.shape)
grid_cps[multi_index[0, 0]] = [0.0, 0.0]
grid_cps[multi_index[1, 0]] = [0.5, 0.0]
grid_cps[multi_index[2, 0], 0] = 1.0
# which also supports ranges
grid_cps[multi_index[:, 0], 1] = 0.0
grid_cps[multi_index[:, 1], 1] = 1.0
grid_cps[multi_index[:, 1], 0] = [0.0, 0.5, 1.0]
assert np.allclose(bspline.control_points, grid_cps)
# Evaluate spline mapping.
# First, let's form parametric coordinate queries
queries = [
[0.1, 0.2], # first query
[0.4, 0.5], # second query
[0.1156, 0.9091], # third query
]
physical_coords = bspline.evaluate(queries)
# we can also execute this in parallel using multithread
# executions on c++ side (for heavy multi-queries scenarios)
physical_coords_parallel = bspline.evaluate(queries, nthreads=2)
# this holds
assert np.allclose(physical_coords, physical_coords_parallel)
Feature Summary
For details, please take a look at the documentation. Most of the functions are vectorized and capable of multithread executions.
Common features
Method | Description |
---|---|
evaluate() | Given parametric coordinates, returns physical (i.e., mapped / evaluated) coordinate |
derivative() | Given parametric cooridnates and order of partial derivatives, returns physical derivatives |
jacobian() | Given a number of query points, returns the jacobian of the geometry or field |
sample() | Given number of sampling points per parametric dimension, returns evaluated physical coordinates, which are equally distributed in parametric space. |
basis_and_support() | Given parametric coordinates, returns basis function values and their support. Satisfies partition of unity. |
basis_derivative_and_support() | Given parametric coordinates and order of partial derivatives, returns basis function derivative values. |
proximities() | Given physical coordinates, returns parametric coordinates that maps to the nearest physical coordinate. Often referred as "point inversion". |
elevate_degrees() | Elevates Spline degrees along specified parametric dimensions |
extract_boundaries() | Given boundary ids, returns extracted boundary splines. |
BSpline, NURBS
Method | Description |
---|---|
reduce_degrees() | Reduces spline degrees along specified parametric dimensionans, as long as the spline stays under given tolerance |
insert_knots() | Insert knots at given locations |
remove_knots() | Removes knots at given locations, as long as the spline stays under given tolerance |
extract_bezier_patches() | Extracts each knot spans as a Bezier spline |
Bezier, Rational Bezier
Method | Description |
---|---|
multiply (*) | Given two Beziers a and b , returns a Bezier c that satisfies: c.evaluate(query) = a.evalute(query) * b.evaluate(query) |
add (+) | Given two Beziers a and b , returns a Bezier c that satisfies: c.evaluate(query) = a.evaluate(query) + b.evaluate(query) |
derivative_spline() | Given order or partial derivatives, returns a bezier c that satisfies: c.derivative(query, orders) = a.derivative_spline(orders).evaluate(query) |
split() | Splits Bezier into multiple patches at defined locations |
extract_dim() | Extract a single physical dimension |
compose() | Given an inner function spline a and an outer function spline b , it returns their functional composition that satisfies c.evaluate(query) = b.evaluate(a.evaluate(query)) |
composition_derivative() | Given an outer function a , an inner function b and its derivative b' with respect to some variable s , it returns the derivative with respect to the same variable s of the composition a(b) by applying the chain-rule |
Multipatch
Splinepy offers a common interface for multipatch geometries, i.e., geometries consisting of multiple, individual splines of arbitrary types. This concept is both used for complex geometries as for Isogeometric Analysis. Multipatch objects have the following functionalities:
- determine patch-interfaces automatically
- identification of boundary faces
- boundary assignement using different techniques, relying either on the boundary position or on the continuity inbetween patches
- Boundary extraction
IO
Available in splinepy.io
.
Formats | Description |
---|---|
iges | Loads/Exports splines from an IGES file |
irit | IRIT compatible format |
json | (Custom) easy-to-read format, supports base64 encoding |
mfem | MFEM compatible .mesh format. Supports structured multi-patch splines in controlpoints_cartesian and 2D single-patch splines |
gismo | GISMO compatible .xml format |
npz | Based on np.savez() |
xml | RWTH CATS spline format |
BSpline fitting
Implements fitting routines from the The NURBS Book. Available as BSpline's classmethod.
- interpolate_curve()
- approximate_curve()
- interpolate_surface()
- approximate_surface()
Dependencies
Followings are direct dependencies for splinepy. Please feel free to check out the repositories linked in the following.
Dependency | Usage | |
---|---|---|
C++ | ||
pybind11 | Binding between C++ Backend and Python frontend | |
SplineLib | Backend for BSplines and NURBS | |
bezman | Backend for (rational) Beziers | |
napf | Used for KD-Trees, wrapper for nanoflann | |
Python | ||
numpy | Used for data storage and data manipulation | |
scipy (optional) | Used for sparse matrices, where applicable | |
Build process | ||
cmake | Platform independent build system for Backend | |
setuptools | ||
wheel |
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for splinepy-0.0.24-cp311-cp311-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 412382ab65ebde4d825098fd8c5219d73198ade830f8def894ebe1e5307e5268 |
|
MD5 | c988baaa2e9fde9d99afd5ec891a8990 |
|
BLAKE2b-256 | 79324f16360357f58ed9d9dc94a65e6eb6657170631990e87cea0ed6949becc1 |
Hashes for splinepy-0.0.24-cp311-cp311-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 85492209ce72003acadd258f38ad8c332314123e0ea1489885343fcf27d658da |
|
MD5 | 2355593bad08048b270b9d34469042a5 |
|
BLAKE2b-256 | ef2fcef7e36ad91004a7c3c5700e869e175f889296e4341c3891a939a54f0b1b |
Hashes for splinepy-0.0.24-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7756463a56b00720a9508f32fb4355384ce2105ca39e7d334b659ff18bc3ac88 |
|
MD5 | d42244fcce84eb2924ab24b8ae6df42d |
|
BLAKE2b-256 | b32c35cbe9be50f2a1dfaada4866ee2e4ee032fa049e6cb3bac181f6a3692899 |
Hashes for splinepy-0.0.24-cp311-cp311-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 41f98485b6bb353e8d985f47c22afd9a7cf5b6dae2ad9ec429117cc9f3494123 |
|
MD5 | 4a2b97891a33e015b46f1c4e78c02fb3 |
|
BLAKE2b-256 | 812749bbf14daaf44c23f3677879511163f821049fe30af5e144fae0a190a34c |
Hashes for splinepy-0.0.24-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e82b9cc07613557bdf419ea5c1a71a454abc0b358b93e72fac23cd90e5e37357 |
|
MD5 | 07c995882250d1a522907841e601b259 |
|
BLAKE2b-256 | 4490dff76227b316ab970922c16fc0e47294bfbf4b412dd4deda0c451da93a3a |
Hashes for splinepy-0.0.24-cp310-cp310-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | cb16ff21707eabac9c34eb83fb41085b9a04e1a2ef7ea6a9e03a4a9501520aeb |
|
MD5 | 0c349790cce3d01719575e2afbcb4a97 |
|
BLAKE2b-256 | 3b6e9935e6575c0a59c6c284e9b8364da973fa992d8f6bb6fa9afb0d77794d7f |
Hashes for splinepy-0.0.24-cp310-cp310-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b23daf818bf7a5ccfdbcdf0ee2f04894100e0300d3dc0730495c812430a1160e |
|
MD5 | c4529cc13afe1a7480e8d0d662c1ae1c |
|
BLAKE2b-256 | cde87a1e146336616047af9a0786c0e74548f9648c34a6352a986b8670c4c2c9 |
Hashes for splinepy-0.0.24-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | aeec2100980dede3cf55e64ff7f5fca29ca6c8040d943ca1a36164e9d0329f1e |
|
MD5 | 9d32643013de1272a03bfe8caafd7e67 |
|
BLAKE2b-256 | eb23e87a8930fe0dd807a52f1b249ffbebc3a588d54ba1a556289f2c35d8ea76 |
Hashes for splinepy-0.0.24-cp310-cp310-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0e704e7dcef122c4a7de1cf4e0f53c8f14cfb088ec66d79b114aa474d1b306c1 |
|
MD5 | c1c7237d969c9754ee9297456525c9ba |
|
BLAKE2b-256 | f054f229c2915835c58cb9a332640fdf70a89dcb97482a541f25d448a1035d6c |
Hashes for splinepy-0.0.24-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b6d31b505a2d7154afd739e974a97bccda134250d254f9fefd2ec107aeffe273 |
|
MD5 | a097eea46d88cfb4434c0af1fd1be724 |
|
BLAKE2b-256 | bd1c4ab5c95aa1d6870c02b1989b4e2e2cc88623fbbebbad06d06291c6875266 |
Hashes for splinepy-0.0.24-cp39-cp39-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6cbfe0caeec321b2d8f6b4df25d2b0c03451c1de33d3a1511ab50fe5b056171b |
|
MD5 | 50dafd74fa267c33875d30084d47a593 |
|
BLAKE2b-256 | b50a7deac5adfaa1598ea3de226f2580bfe4f14605badd96f1451bcb8c0407c8 |
Hashes for splinepy-0.0.24-cp39-cp39-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 38f6829585611aa2a938f18498646c924f69b0e24d18f784895736f31e4cd2a0 |
|
MD5 | cda90edbac290f23dd8dcb76091e9326 |
|
BLAKE2b-256 | 1eb5f8bc1b274c3b72acfbe121673632120209a495fc0700e7821e410665f22b |
Hashes for splinepy-0.0.24-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7ff29c3f22b03cd1133ee0602949a32c5f12869e53895e84f142d46608c14909 |
|
MD5 | 2ba16c2e932f1609cc204d83764f29b3 |
|
BLAKE2b-256 | f7e8ac0d779723459beefc3858a8188f5e9f3d5bee2ccfc5929f8c735833326d |
Hashes for splinepy-0.0.24-cp39-cp39-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6dcf4e0629cc8fff1fb6acb4989672baad495104e82cd976dae6cf98c90941a3 |
|
MD5 | bc6aa92f57ef91f9275c316311f3ea96 |
|
BLAKE2b-256 | ca4e7526bb61788f43b90ad9734263462259ea0d008c5045ec1a70d809b56bc3 |
Hashes for splinepy-0.0.24-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 205e6b24fc67620db37f39fd9519e9f155842678e8378f3eed24244d5f6f4247 |
|
MD5 | af05c30adcfd72ff22b7f2514bb762b1 |
|
BLAKE2b-256 | b6d956f578d5e9d0b1d325816022760582dce154f5e172c0c928f0c85b1aac43 |
Hashes for splinepy-0.0.24-cp38-cp38-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 95da297e26696fce414d1014ca53c5f259c3440124a5d17e19339f9ffda08d4f |
|
MD5 | 7d02eaf9cf8ac491e0bbc78c36b58085 |
|
BLAKE2b-256 | 09b7b3f371536cab2b5c297b34427a7c7bc64bca883f9f0b92b7fddc7e563ce0 |
Hashes for splinepy-0.0.24-cp38-cp38-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5d5b312c0542fc113164ce19af7213425694dcd0a7b1024fb6bf623655eef3a4 |
|
MD5 | d69d7e0396aa8c0f2de6097620f5847e |
|
BLAKE2b-256 | f9509d59a48e7236c12e339b86a79068abd8e4e4d54982fdcb323b546cc6d358 |
Hashes for splinepy-0.0.24-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 11f840241f95edbbf27bd47a05fc0ee8dd62b0484fa8ddcb714a0f68ae6f1cf4 |
|
MD5 | b2e21fb871e5cf273158c85b98822fae |
|
BLAKE2b-256 | fbbe8635f7f7de78a4c964a44c41b281e9db8c60e2f4924f0fc1d033d40100a6 |
Hashes for splinepy-0.0.24-cp38-cp38-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 75c0d2ceec4003c7ccb0ff1fabc2d170de31bf828988754a247716b77c46f211 |
|
MD5 | 9206d6da0bf9094eff66e4ac1f0ad494 |
|
BLAKE2b-256 | 2b29d3d220e4aa72894acd35bc30592fd950d1922f2cf12c6e773f46127d0547 |
Hashes for splinepy-0.0.24-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fda8f58555925b36c56b3e3d63bf2f2f1dd7cf69deee19539ec86f07f61680d5 |
|
MD5 | 808b9c0c955326407a51fc133315b781 |
|
BLAKE2b-256 | e3ccd5058fa1ee1760a5ee4d27837759850ff679a0afc4059ae34c936628ebf3 |
Hashes for splinepy-0.0.24-cp37-cp37m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5a659c859d3d41e709ec10b0059b4d8e601c380a1b4613e37c678c959b111223 |
|
MD5 | 8e60eb309fe07eda473ca9c5a5a0b155 |
|
BLAKE2b-256 | a3b753121217c13f04aa2452df30e6bc0db0327130790aa5e9a21a9c3038888b |
Hashes for splinepy-0.0.24-cp37-cp37m-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4c26e482d4e88e2c07287dcaee437c26825fa3c02ff93c6993d1e1f10747fafa |
|
MD5 | 306dca32bfc573066d55950853b1f51d |
|
BLAKE2b-256 | 7d5add38a9ae39b64cd62ff3510b81e74ee9d817a2594215a1c72f4534290f12 |
Hashes for splinepy-0.0.24-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8e8c432d63cb6f0832d7911a2606c064a42bec10550ae9ef2d746cbd27d2099a |
|
MD5 | 07d0309018d813d08490df4b5a3ac149 |
|
BLAKE2b-256 | 781b95be3369e4d9ee1aed64c9e8801245aed8b8ed650b4b0673d6d5b150e061 |
Hashes for splinepy-0.0.24-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2be924a79615087e13639ee6884c8d9e268231e20e5bfbaa8139aab97246d785 |
|
MD5 | 91bcc78b33eff44942c78087c2c2699c |
|
BLAKE2b-256 | 98e42cf686215ac9813edc8e9ffc483f734e3ac6a1d5479c253aacf6e1719016 |
Hashes for splinepy-0.0.24-cp36-cp36m-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1e57dd4eaa4f7cf80cd7a67919e2ff2a6930521a6f70eae9ebaf5a85d114e74e |
|
MD5 | 78abfa3fbc41a78ded5b718b77e4ce9f |
|
BLAKE2b-256 | ed62bf93dcb0e13e436b8d3e108045fcdcff0cd7da6e5a3b89c4b3821572ede5 |
Hashes for splinepy-0.0.24-cp36-cp36m-win32.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8816b0d07558808bd0308f9f1557d1337929cf31868f30b9071aa9a5b5363b64 |
|
MD5 | dbee342ab793120543d2d0ceb8adc4d5 |
|
BLAKE2b-256 | 69a1d17925ed6fecbbcf7e3fd8eede626191e198aaf2664192aa605cfa11264b |
Hashes for splinepy-0.0.24-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 518c84a08e1ae51ce2a8f71e7b0f624bca49a9fe3c2414a8b9c44f5ca89fbcfb |
|
MD5 | 62a135b6cb1332e7ab34ce21975a4364 |
|
BLAKE2b-256 | b29966a5a7bf10604fddf83f30f6f05e9fa17c95cc061d546bce1bc65409c069 |
Hashes for splinepy-0.0.24-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 21d393f2acb1dbacfab0cc5ddcd012cc42c380dbca67aa001adbda329701a371 |
|
MD5 | e56e0c767114c49041b0de6cd455fdf1 |
|
BLAKE2b-256 | a8b4c1963550c2baa8d060809544f046d364c1e41ce6b2ed4b6996dd2ca77f07 |