Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/source/params.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ Params
.. autoclass:: FFDParameters
:members:
:private-members:

.. autoclass:: RBFParameters
:members:
:private-members:
99 changes: 94 additions & 5 deletions pygem/params.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Utilities for reading and writing parameters files to perform the Free Form Deformation (FFD)
Utilities for reading and writing parameters files to perform the desired geometrical morphing.
"""
import os
import ConfigParser
Expand Down Expand Up @@ -268,13 +268,11 @@ def print_info(self):
"""
print 'conversion_unit = ' + str(self.conversion_unit) + '\n'
print '(lenght_box_x, lenght_box_y, lenght_box_z) = (' + str(self.lenght_box_x) + \
', ' + str(self.lenght_box_y) + ', ' + \
str(self.lenght_box_z) + ')'
', ' + str(self.lenght_box_y) + ', ' + str(self.lenght_box_z) + ')'
print 'origin_box = ' + str(self.origin_box)
print 'n_control_points = ' + str(self.n_control_points)
print '(rot_angle_x, rot_angle_y, rot_angle_z) = (' + str(self.rot_angle_x) + \
', ' + str(self.rot_angle_y) + ', ' + \
str(self.rot_angle_z) + ')'
', ' + str(self.rot_angle_y) + ', ' + str(self.rot_angle_z) + ')'
print '\narray_mu_x ='
print self.array_mu_x
print '\narray_mu_y ='
Expand All @@ -297,3 +295,94 @@ def print_info(self):
print self.position_vertex_3



class RBFParameters(object):
"""
Class that handles the Radial Basis Functions parameters in terms of RBF control points and
basis functions.

:cvar string basis: name of the basis functions to use in the transformation. The functions
implemented so far are: gaussian spline, multi quadratic biharmonic spline,
inv multi quadratic biharmonic spline, thin plate spline, beckert wendland c2 basis.
For a comprehensive list with details see the class :class:`~pygem.radialbasis.RBF`.
The default value is None.
:cvar float radius: is the scaling parameter r that affects the shape of the basis functions.
For details see the class :class:`~pygem.radialbasis.RBF`. The default value is None.
:cvar int n_control_points: total number of control points.
:cvar numpy.ndarray original_control_points: it is an `n_control_points`-by-3 array with the
coordinates of the original interpolation control points before the deformation. The
default value is None.
:cvar numpy.ndarray deformed_control_points: it is an `n_control_points`-by-3 array with the
coordinates of the interpolation control points after the deformation. The default value
is None.
"""
def __init__(self):
self.basis = None
self.radius = None
self.n_control_points = None
self.original_control_points = None
self.deformed_control_points = None


def read_parameters(self, filename='parameters.prm'):
"""
Reads in the parameters file and fill the self structure.

:param string filename: parameters file to be read in.
"""
if not isinstance(filename, basestring):
raise TypeError('filename must be a string')

# Checks if the parameters file exists. If not it writes the default class into filename.
# It consists in the vetices of a cube of side one with a vertex in (0, 0, 0) and opposite one
# in (1, 1, 1).
if not os.path.isfile(filename):
self.basis = 'gaussian_spline'
self.radius = 0.5
self.n_control_points = 8
self.original_control_points = np.array([0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 0., \
0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1.]).reshape((8, 3))
self.deformed_control_points = np.array([0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 0., \
0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1.]).reshape((8, 3))
#self.write_parameters(filename)
return

config = ConfigParser.RawConfigParser()
config.read(filename)

self.basis = config.get('Radial Basis Functions', 'basis function')
self.radius = config.getfloat('Radial Basis Functions', 'radius')

ctrl_points = config.get('Control points', 'original control points')
lines = ctrl_points.split('\n')
self.n_control_points = len(lines)
self.original_control_points = np.zeros((self.n_control_points, 3))
for line, i in zip(lines, range(0, self.n_control_points)):
values = line.split()
self.original_control_points[i] = np.array([float(values[0]), float(values[1]), float(values[2])])

mod_points = config.get('Control points', 'deformed control points')
lines = mod_points.split('\n')

if len(lines) != self.n_control_points:
raise TypeError("The number of control points must be equal both in the 'original control points'" + \
" and in the 'deformed control points' section of the parameters file ({0!s})".format(filename))

self.deformed_control_points = np.zeros((self.n_control_points, 3))
for line, i in zip(lines, range(0, self.n_control_points)):
values = line.split()
self.deformed_control_points[i] = np.array([float(values[0]), float(values[1]), float(values[2])])


def print_info(self):
"""
This method prints all the RBF parameters on the screen. Its purpose is for debugging.
"""
print 'basis function = ' + str(self.basis)
print 'radius = ' + str(self.radius)
print 'n_control_points = ' + str(self.n_control_points)
print '\noriginal_control_points ='
print self.original_control_points
print '\ndeformed_control_points ='
print self.deformed_control_points

8 changes: 4 additions & 4 deletions pygem/stlhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import numpy as np
from mpl_toolkits import mplot3d
from matplotlib import pyplot
from stl import mesh
from stl import mesh, Mode
import pygem.filehandler as fh


Expand Down Expand Up @@ -49,9 +49,9 @@ def parse(self, filename):

def write(self, mesh_points, filename, write_bin=False):
"""
Writes a unv file, called filename, copying all the lines from self.filename but
Writes a stl file, called filename, copying all the lines from self.filename but
the coordinates. mesh_points is a matrix that contains the new coordinates to
write in the unv file.
write in the stl file.

:param numpy.ndarray mesh_points: it is a `n_points`-by-3 matrix containing
the coordinates of the points of the mesh.
Expand All @@ -75,7 +75,7 @@ def write(self, mesh_points, filename, write_bin=False):
data['vectors'][i][j] = mesh_points[3*i + j]

if not write_bin:
stl_mesh.save(self.outfile, mode=1, update_normals=True)
stl_mesh.save(self.outfile, mode=Mode.ASCII, update_normals=True)
else:
stl_mesh.save(self.outfile, update_normals=True)

Expand Down
37 changes: 37 additions & 0 deletions tests/test_datasets/parameters_rbf_bugged_01.prm
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

[Radial Basis Functions]
# This section describes the radial basis functions shape.

# basis funtion is the name of the basis functions to use in the transformation. The functions
# implemented so far are: gaussian_spline, multi_quadratic_biharmonic_spline,
# inv_multi_quadratic_biharmonic_spline, thin_plate_spline, beckert_wendland_c2_basis.
# For a comprehensive list with details see the class RBF.
basis function: gaussian_spline

# radius is the scaling parameter r that affects the shape of the basis functions. See the documentation
# of the class RBF for details.
radius: 0.5

[Control points]
# This section describes the RBF control points.

# original control points collects the coordinates of the interpolation control points before the deformation.
original control points: 0.0 0.0 0.0
0.0 0.0 1.0
0.0 1.0 0.0
1.0 0.0 0.0
0.0 1.0 1.0
1.0 0.0 1.0
1.0 1.0 0.0
1.0 1.0 1.0

# deformed control points collects the coordinates of the interpolation control points after the deformation.
deformed control points: 0.0 0.0 0.0
0.0 0.0 1.0
0.0 1.0 0.0
1.0 0.0 0.0
0.0 1.0 1.0
1.0 0.0 1.0
1.0 1.0 0.0
1.0 1.0 1.0
0.5 0.5 0.5
36 changes: 36 additions & 0 deletions tests/test_datasets/parameters_rbf_bugged_02.prm
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

[Radial Basis Functions]
# This section describes the radial basis functions shape.

# basis funtion is the name of the basis functions to use in the transformation. The functions
# implemented so far are: gaussian_spline, multi_quadratic_biharmonic_spline,
# inv_multi_quadratic_biharmonic_spline, thin_plate_spline, beckert_wendland_c2_basis.
# For a comprehensive list with details see the class RBF.
basis function: gaussian_splines

# radius is the scaling parameter r that affects the shape of the basis functions. See the documentation
# of the class RBF for details.
radius: 0.5

[Control points]
# This section describes the RBF control points.

# original control points collects the coordinates of the interpolation control points before the deformation.
original control points: 0.0 0.0 0.0
0.0 0.0 1.0
0.0 1.0 0.0
1.0 0.0 0.0
0.0 1.0 1.0
1.0 0.0 1.0
1.0 1.0 0.0
1.0 1.0 1.0

# deformed control points collects the coordinates of the interpolation control points after the deformation.
deformed control points: 0.0 0.0 0.0
0.0 0.0 1.0
0.0 1.0 0.0
1.0 0.0 0.0
0.0 1.0 1.0
1.0 0.0 1.0
1.0 1.0 0.0
1.0 1.0 1.0
36 changes: 36 additions & 0 deletions tests/test_datasets/parameters_rbf_default.prm
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

[Radial Basis Functions]
# This section describes the radial basis functions shape.

# basis funtion is the name of the basis functions to use in the transformation. The functions
# implemented so far are: gaussian_spline, multi_quadratic_biharmonic_spline,
# inv_multi_quadratic_biharmonic_spline, thin_plate_spline, beckert_wendland_c2_basis.
# For a comprehensive list with details see the class RBF.
basis function: gaussian_spline

# radius is the scaling parameter r that affects the shape of the basis functions. See the documentation
# of the class RBF for details.
radius: 0.5

[Control points]
# This section describes the RBF control points.

# original control points collects the coordinates of the interpolation control points before the deformation.
original control points: 0.0 0.0 0.0
0.0 0.0 1.0
0.0 1.0 0.0
1.0 0.0 0.0
0.0 1.0 1.0
1.0 0.0 1.0
1.0 1.0 0.0
1.0 1.0 1.0

# deformed control points collects the coordinates of the interpolation control points after the deformation.
deformed control points: 0.0 0.0 0.0
0.0 0.0 1.0
0.0 1.0 0.0
1.0 0.0 0.0
0.0 1.0 1.0
1.0 0.0 1.0
1.0 1.0 0.0
1.0 1.0 1.0
File renamed without changes.
86 changes: 86 additions & 0 deletions tests/test_rbfparams.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@

from unittest import TestCase
import unittest
import pygem.params as rbfp
import numpy as np
import filecmp
import os


class TestFFDParameters(TestCase):


def test_class_members_default_basis(self):
params = rbfp.RBFParameters()
assert params.basis == None


def test_class_members_default_radius(self):
params = rbfp.RBFParameters()
assert params.radius == None


def test_class_members_default_n_control_points(self):
params = rbfp.RBFParameters()
assert params.n_control_points == None


def test_class_members_default_original_control_points(self):
params = rbfp.RBFParameters()
assert params.original_control_points == None


def test_class_members_default_deformed_control_points(self):
params = rbfp.RBFParameters()
assert params.deformed_control_points == None


def test_read_parameters_basis(self):
params = rbfp.RBFParameters()
params.read_parameters('tests/test_datasets/parameters_rbf_default.prm')
assert params.basis == 'gaussian_spline'


def test_read_parameters_radius(self):
params = rbfp.RBFParameters()
params.read_parameters('tests/test_datasets/parameters_rbf_default.prm')
assert params.radius == 0.5


def test_read_parameters_n_control_points(self):
params = rbfp.RBFParameters()
params.read_parameters('tests/test_datasets/parameters_rbf_default.prm')
assert params.n_control_points == 8


def test_read_parameters_original_control_points(self):
params = rbfp.RBFParameters()
params.read_parameters('tests/test_datasets/parameters_rbf_default.prm')
original_control_points_exact = np.array([0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 0., \
0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1.]).reshape((8, 3))
np.testing.assert_array_almost_equal(params.original_control_points, original_control_points_exact)


def test_read_parameters_deformed_control_points(self):
params = rbfp.RBFParameters()
params.read_parameters('tests/test_datasets/parameters_rbf_default.prm')
deformed_control_points_exact = np.array([0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 0., \
0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1.]).reshape((8, 3))
np.testing.assert_array_almost_equal(params.deformed_control_points, deformed_control_points_exact)


def test_read_parameters_failing_filename_type(self):
params = rbfp.RBFParameters()
with self.assertRaises(TypeError):
params.read_parameters(3)


def test_read_parameters_failing_number_deformed_control_points(self):
params = rbfp.RBFParameters()
with self.assertRaises(TypeError):
params.read_parameters('tests/test_datasets/parameters_rbf_bugged_01.prm')


def test_print_info(self):
params = rbfp.RBFParameters()
params.print_info()