Supported File Formats
NURBS-Python supports several input and output formats for importing and exporting B-Spline/NURBS curves and surfaces. Please note that NURBS-Python uses right-handed notation on input and output files.
Text Files
NURBS-Python provides a simple way to import and export the control points and the evaluated control points as ASCII text files. The details of the file format for curves and surfaces is described below:
Comma-Separated (CSV)
You may use export_csv()
and import_csv()
functions to save/load control points and/or evaluated
points as a CSV file. This function works with both curves and surfaces.
OBJ Format
You may use export_obj()
function to export a NURBS surface as a Wavefront .obj file.
Example 1
The following example demonstrates saving surfaces as .obj files:
1# ex_bezier_surface.py
2from geomdl import BSpline
3from geomdl import utilities
4from geomdl import exchange
5
6# Create a BSpline surface instance
7surf = BSpline.Surface()
8
9# Set evaluation delta
10surf.delta = 0.01
11
12# Set up the surface
13surf.degree_u = 3
14surf.degree_v = 2
15control_points = [[0, 0, 0], [0, 1, 0], [0, 2, -3],
16 [1, 0, 6], [1, 1, 0], [1, 2, 0],
17 [2, 0, 0], [2, 1, 0], [2, 2, 3],
18 [3, 0, 0], [3, 1, -3], [3, 2, 0]]
19surf.set_ctrlpts(control_points, 4, 3)
20surf.knotvector_u = utilities.generate_knot_vector(surf.degree_u, 4)
21surf.knotvector_v = utilities.generate_knot_vector(surf.degree_v, 3)
22
23# Evaluate surface
24surf.evaluate()
25
26# Save surface as a .obj file
27exchange.export_obj(surf, "bezier_surf.obj")
Example 2
The following example combines shapes
module together with exchange
module:
1from geomdl.shapes import surface
2from geomdl import exchange
3
4# Generate cylindirical surface
5surf = surface.cylinder(radius=5, height=12.5)
6
7# Set evaluation delta
8surf.delta = 0.01
9
10# Evaluate the surface
11surf.evaluate()
12
13# Save surface as a .obj file
14exchange.export_obj(surf, "cylindirical_surf.obj")
STL Format
Exporting to STL files works in the same way explained in OBJ Files section. To export a NURBS surface as a .stl file,
you may use export_stl()
function. This function saves in binary format by default but there is an option to
change the save file format to plain text. Please see the documentation for details.
Object File Format (OFF)
Very similar to exporting as OBJ and STL formats, you may use export_off()
function to export a NURBS surface
as a .off file.
Custom Formats (libconfig, YAML, JSON)
NURBS-Python provides several custom formats, such as libconfig, YAML and JSON, for importing and exporting complete NURBS shapes (i.e. degrees, knot vectors and control points of single and multi curves/surfaces).
libconfig
libconfig is a lightweight library for processing configuration files and
it is often used on C/C++ projects. The library doesn’t define a format but it defines a syntax for the files it can
process. NURBS-Python uses export_cfg()
and import_cfg()
functions to exporting and importing
shape data which can be processed by libconfig-compatible libraries. Although exporting does not require any external
libraries, importing functionality depends on libconf module, which is a pure
Python library for parsing libconfig-formatted files.
YAML
YAML is a data serialization format and it is supported by the major programming languages.
NURBS-Python uses ruamel.yaml package as an external dependency for its YAML
support since the package is well-maintained and compatible with the latest YAML standards.
NURBS-Python supports exporting and importing NURBS data to YAML format with the functions export_yaml()
and import_yaml()
, respectively.
JSON
JSON is also a serialization and data interchange format and it is natively supported
by Python via json
module. NURBS-Python supports exporting and importing NURBS data to JSON format with the
functions export_json()
and import_json()
, respectively.
Format Definition
Curve
The following example illustrates a 2-dimensional NURBS curve. 3-dimensional NURBS curves are also supported and they can be generated by updating the control points.
1shape:
2 type: curve # type of the geometry
3 count: 1 # number of curves in "data" list (optional)
4 data:
5 - rational: True # rational or non-rational (optional)
6 dimension: 2 # spatial dimension of the curve (optional)
7 degree: 2
8 knotvector: [0, 0, 0, 0.25, 0.25, 0.5, 0.5, 0.75, 0.75, 1, 1, 1]
9 control_points:
10 points: # cartesian coordinates of the control points
11 - [0.0, -1.0] # each control point is defined as a list
12 - [-1.0, -1.0]
13 - [-1.0, 0.0]
14 - [-1.0, 1.0]
15 - [0.0, 1.0]
16 - [1.0, 1.0]
17 - [1.0, 0.0]
18 - [1.0, -1.0]
19 - [0.0, -1.0]
20 weights: # weights vector (required if rational)
21 - 1.0
22 - 0.707
23 - 1.0
24 - 0.707
25 - 1.0
26 - 0.707
27 - 1.0
28 - 0.707
29 - 1.0
30 delta: 0.01 # evaluation delta
Shape section: This section contains the single or multi NURBS data.
type
anddata
sections are mandatory.Type section: This section defines the type of the NURBS shape. For NURBS curves, it should be set to curve.
Data section: This section defines the NURBS data, i.e. degrees, knot vectors and control_points.
weights
anddelta
sections are optional.
Surface
The following example illustrates a NURBS surface:
1shape:
2 type: surface # type of the geometry
3 count: 1 # number of surfaces in "data" list (optional)
4 data:
5 - rational: True # rational or non-rational (optional)
6 dimension: 3 # spatial dimension of the surface (optional)
7 degree_u: 1 # degree of the u-direction
8 degree_v: 2 # degree of the v-direction
9 knotvector_u: [0.0, 0.0, 1.0, 1.0]
10 knotvector_v: [0.0, 0.0, 0.0, 0.25, 0.25, 0.5, 0.5, 0.75, 0.75, 1.0, 1.0, 1.0]
11 size_u: 2 # number of control points on the u-direction
12 size_v: 9 # number of control points on the v-direction
13 control_points:
14 points: # cartesian coordinates (x, y, z) of the control points
15 - [1.0, 0.0, 0.0] # each control point is defined as a list
16 - [1.0, 1.0, 0.0]
17 - [0.0, 1.0, 0.0]
18 - [-1.0, 1.0, 0.0]
19 - [-1.0, 0.0, 0.0]
20 - [-1.0, -1.0, 0.0]
21 - [0.0, -1.0, 0.0]
22 - [1.0, -1.0, 0.0]
23 - [1.0, 0.0, 0.0]
24 - [1.0, 0.0, 1.0]
25 - [1.0, 1.0, 1.0]
26 - [0.0, 1.0, 1.0]
27 - [-1.0, 1.0, 1.0]
28 - [-1.0, 0.0, 1.0]
29 - [-1.0, -1.0, 1.0]
30 - [0.0, -1.0, 1.0]
31 - [1.0, -1.0, 1.0]
32 - [1.0, 0.0, 1.0]
33 weights: # weights vector (required if rational)
34 - 1.0
35 - 0.7071
36 - 1.0
37 - 0.7071
38 - 1.0
39 - 0.7071
40 - 1.0
41 - 0.7071
42 - 1.0
43 - 1.0
44 - 0.7071
45 - 1.0
46 - 0.7071
47 - 1.0
48 - 0.7071
49 - 1.0
50 - 0.7071
51 - 1.0
52 delta:
53 - 0.05 # evaluation delta of the u-direction
54 - 0.05 # evaluation delta of the v-direction
55 trims: # define trim curves (optional)
56 count: 3 # number of trims in the "data" list (optional)
57 data:
58 - type: spline # type of the trim curve
59 rational: False # rational or non-rational (optional)
60 dimension: 2 # spatial dimension of the trim curve (optional)
61 degree: 2 # degree of the 1st trim
62 knotvector: [ ... ] # knot vector of the 1st trim curve
63 control_points:
64 points: # parametric coordinates of the 1st trim curve
65 - [u1, v1] # expected to be 2-dimensional, corresponding to (u,v)
66 - [u2, v2]
67 - ...
68 reversed: 0 # 0: trim inside, 1: trim outside (optional, default is 0)
69 - type: spline # type of the 2nd trim curve
70 rational: True # rational or non-rational (optional)
71 dimension: 2 # spatial dimension of the trim curve (optional)
72 degree: 1 # degree of the 2nd trim
73 knotvector: [ ... ] # knot vector of the 2nd trim curve
74 control_points:
75 points: # parametric coordinates of the 2nd trim curve
76 - [u1, v1] # expected to be 2-dimensional, corresponding to (u,v)
77 - [u2, v2]
78 - ...
79 weights: # weights vector of the 2nd trim curve (required if rational)
80 - 1.0
81 - 1.0
82 - ...
83 delta: 0.01 # evaluation delta (optional)
84 reversed: 1 # 0: trim inside, 1: trim outside (optional, default is 0)
85 - type: freeform # type of the 3rd trim curve
86 dimension: 2 # spatial dimension of the trim curve (optional)
87 points: # parametric coordinates of the 3rd trim curve
88 - [u1, v1] # expected to be 2-dimensional, corresponding to (u,v)
89 - [u2, v2]
90 - ...
91 name: "my freeform curve" # optional
92 reversed: 1 # 0: trim inside, 1: trim outside (optional, default is 0)
93 - type: container # type of the 4th trim curve
94 dimension: 2 # spatial dimension of the trim curve (optional)
95 data: # a list of freeform and/or spline geometries
96 - ...
97 - ...
98 name: "my trim curves" # optional
99 reversed: 1 # 0: trim inside, 1: trim outside (optional, default is 0)
Shape section: This section contains the single or multi NURBS data.
type
anddata
sections are mandatory.Type section: This section defines the type of the NURBS shape. For NURBS curves, it should be set to surface.
Data section: This section defines the NURBS data, i.e. degrees, knot vectors and control_points.
weights
anddelta
sections are optional.
Surfaces can also contain trim curves. These curves can be stored in 2 geometry types inside the surface:
spline
corresponds to a spline geometry, which is defined by a set of degrees, knot vectors and control pointscontainer
corresponds to a geometry containerfreeform
corresponds to a freeform geometry; defined by a set of points
Volume
The following example illustrates a B-spline volume:
1shape:
2 type: volume # type of the geometry
3 count: 1 # number of volumes in "data" list (optional)
4 data:
5 - rational: False # rational or non-rational (optional)
6 degree_u: 1 # degree of the u-direction
7 degree_v: 2 # degree of the v-direction
8 degree_w: 1 # degree of the w-direction
9 knotvector_u: [0.0, 0.0, 1.0, 1.0]
10 knotvector_v: [0.0, 0.0, 0.0, 0.25, 0.25, 0.5, 0.5, 0.75, 0.75, 1.0, 1.0, 1.0]
11 knotvector_w: [0.0, 0.0, 1.0, 1.0]
12 size_u: 2 # number of control points on the u-direction
13 size_v: 9 # number of control points on the v-direction
14 size_w: 2 # number of control points on the w-direction
15 control_points:
16 points: # cartesian coordinates (x, y, z) of the control points
17 - [x1, y1, x1] # each control point is defined as a list
18 - [x2, y2, z2]
19 - ...
20 delta:
21 - 0.25 # evaluation delta of the u-direction
22 - 0.25 # evaluation delta of the v-direction
23 - 0.10 # evaluation delta of the w-direction
The file organization is very similar to the surface example. The main difference is the parametric 3rd dimension, w
.
Example: Reading .cfg Files with libconf
The following example illustrates reading the exported .cfg file with libconf module as a reference for libconfig-based systems in different programming languages.
1# Assuming that you have already installed 'libconf'
2import libconf
3
4# Skipping export steps and assuming that we have already exported the data as 'my_nurbs.cfg'
5with open("my_nurbs.cfg", "r") as fp:
6 # Open the file and parse using libconf module
7 ns = libconf.load(fp)
8
9# 'count' shows the number of shapes loaded from the file
10print(ns['shape']['count']
11
12# Traverse through the loaded shapes
13for n in ns['shape']['data']:
14 # As an example, we get the control points
15 ctrlpts = n['control_points']['points']
NURBS-Python exports data in the way that allows processing any number of curves or surfaces with a simple for loop. This approach simplifies implementation of file reading routines for different systems and programming languages.
Using Templates
NURBS-Python v5.x supports Jinja2 templates with the following functions:
To import files formatted as Jinja2 templates, an additional jinja2=True
keyword argument should be passed to the
functions. For instance:
1from geomdl import exchange
2
3# Importing a .yaml file formatted as a Jinja2 template
4data = exchange.import_yaml("surface.yaml", jinja2=True)
NURBS-Python also provides some custom Jinja2 template functions for user convenience. These are:
knot_vector(d, np)
: generates a uniform knot vector. d: degree, np: number of control pointssqrt(x)
: square root of xcubert(x)
: cube root of xpow(x, y)
: x to the power of y
Please see ex_cylinder_tmpl.py
and ex_cylinder_tmpl.cptw
files in the Examples repository
for details on using Jinja2 templates with control point text files.