Free-form Deformation

Utilities for performing Free Form Deformation (FFD).

Theoretical Insight

Free Form Deformation is a technique for the efficient, smooth and accurate geometrical parametrization. It has been proposed the first time in Sederberg, Thomas W., and Scott R. Parry. “Free-form deformation of solid geometric models.” ACM SIGGRAPH computer graphics 20.4 (1986): 151-160. It consists in three different step:

  • Mapping the physical domain to the reference one with map \boldsymbol{\psi}. In the code it is named transformation.

  • Moving some control points to deform the lattice with \hat{T}. The movement of the control points is basically the weight (or displacement) \boldsymbol{\mu} we set in the parameters file.

  • Mapping back to the physical domain with map \boldsymbol{\psi}^{-1}. In the code it is named inverse_transformation.

FFD map (T) is the composition of the three maps, that is

T(\cdot, \boldsymbol{\mu}) = (\Psi^{-1} \circ \hat{T} \circ \Psi) (\cdot, \boldsymbol{\mu})

In this way, every point inside the FFD box changes it position according to

\boldsymbol{P} = \boldsymbol{\psi}^{-1} \left( \sum_{l=0}^L \sum_{m=0}^M \sum_{n=0}^N \mathsf{b}_{lmn}(\boldsymbol{\psi}(\boldsymbol{P}_0)) \boldsymbol{\mu}_{lmn} \right)

where \mathsf{b}_{lmn} are Bernstein polynomials. We improve the traditional version by allowing a rotation of the FFD lattice in order to give more flexibility to the tool.

You can try to add more shapes to the lattice to allow more and more involved transformations.

class FFD(n_control_points=None)[source]

Bases: pygem.deformation.Deformation

Class that handles the Free Form Deformation on the mesh points.

Parameters

n_control_points (list) – number of control points in the x, y, and z direction. Default is [2, 2, 2].

Variables
  • box_length (numpy.ndarray) – dimension of the FFD bounding box, in the x, y and z direction (local coordinate system).

  • box_origin (numpy.ndarray) – the x, y and z coordinates of the origin of the FFD bounding box.

  • rot_angle (numpy.ndarray) – rotation angle around x, y and z axis of the FFD bounding box.

  • n_control_points (numpy.ndarray) – the number of control points in the x, y, and z direction.

  • array_mu_x (numpy.ndarray) – collects the displacements (weights) along x, normalized with the box length x.

  • array_mu_y (numpy.ndarray) – collects the displacements (weights) along y, normalized with the box length y.

  • array_mu_z (numpy.ndarray) – collects the displacements (weights) along z, normalized with the box length z.

Example
>>> from pygem import FFD
>>> import numpy as np
>>> ffd = FFD()
>>> ffd.read_parameters(
>>>        'tests/test_datasets/parameters_test_ffd_sphere.prm')
>>> original_mesh_points = np.load(
>>>         'tests/test_datasets/meshpoints_sphere_orig.npy')
>>> new_mesh_points = ffd(original_mesh_points)
property n_control_points

The number of control points in X, Y and Z directions

Return type

numpy.ndarray

property psi

Return the function that map the physical domain to the reference domain.

Return type

callable

property inverse_psi

Return the function that map the reference domain to the physical domain.

Return type

callable

property T

Return the function that deforms the points within the unit cube.

Return type

callable

property rotation_matrix

The rotation matrix (according to rot_angle_x, rot_angle_y, rot_angle_z).

Return type

numpy.ndarray

property position_vertices

The position of the vertices of the FFD bounding box.

Return type

numpy.ndarray

reset_weights()[source]

Set transformation parameters to arrays of zeros.

read_parameters(filename='parameters.prm')[source]

Reads in the parameters file and fill the self structure.

Parameters

filename (string) – parameters file to be read in.

write_parameters(filename='parameters.prm')[source]

This method writes a parameters file (.prm) called filename and fills it with all the parameters class members.

Parameters

filename (string) – parameters file to be written out.

control_points(deformed=True)[source]

Method that returns the FFD control points. If the deformed flag is set to True the method returns the deformed lattice, otherwise it returns the original undeformed lattice.

Parameters

deformed (bool) – flag to select the original or modified FFD control lattice. The default is True.

Returns

the FFD control points (by row).

Return type

numpy.ndarray

reflect(axis=0, in_place=True)[source]

Reflect the lattice of control points along the direction defined by axis. In particular the origin point of the lattice is preserved. So, for instance, the reflection along x, is made with respect to the face of the lattice in the yz plane that is opposite to the origin. Same for the other directions. Only the weights (mu) along the chosen axis are reflected, while the others are preserved. The symmetry plane can not present deformations along the chosen axis. After the refletcion there will be 2n-1 control points along axis, witha doubled box length.

Parameters
  • axis (int) – axis along which the reflection is performed. Default is 0. Possible values are 0, 1, or 2, corresponding to x, y, and z respectively.

  • in_place (bool) – if True, the object attributes are modified in place; if False, a new object is return with the reflected lattice. Default is True.

Returns

a new object with the same parameters and the reflected lattice if in_place is False, otherwise NoneType.

Example
>>> ffd.reflect(axis=0, in_place=True) # irreversible
>>> # or ...
>>> refle_ffd = ffd.reflect(axis=0, in_place=False)
__call__(src_pts)[source]

This method performs the FFD to src_pts and return the deformed points.

Parameters

src_pts (numpy.ndarray) – the array of dimensions (n_points, 3) containing the points to deform. The points have to be arranged by row.

Returns

the deformed points

Return type

numpy.ndarray (with shape = (n_points, 3))