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
1 change: 1 addition & 0 deletions docs/source/code.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ Code Documentation
vtkhandler
unvhandler
igeshandler
utilities

5 changes: 5 additions & 0 deletions docs/source/utilities.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Utilities
=====================

.. automodule:: pygem.utilities
:members:
3 changes: 2 additions & 1 deletion pygem/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

__all__ = ['affine', 'filehandler', 'freeform', 'openfhandler', 'params', 'stlhandler', 'unvhandler', 'vtkhandler', 'igeshandler']
__all__ = ['affine', 'filehandler', 'freeform', 'openfhandler', 'params', 'stlhandler', 'unvhandler', 'vtkhandler', 'igeshandler', 'utilities']

from . import affine
from . import freeform
Expand All @@ -10,3 +10,4 @@
from . import unvhandler
from . import vtkhandler
from . import igeshandler
from . import utilities
86 changes: 86 additions & 0 deletions pygem/utilities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
Auxiliary utilities for PyGeM.
"""

import vtk
import vtk.util.numpy_support as ns
import numpy as np

# TODO: add the connectivity to the ffd control points to visualize the lattice.



def write_bounding_box(parameters, outfile, write_deformed=True):
"""
Method that writes a vtk file containing the FFD lattice. This method
allows to visualize where the FFD control points are located before the geometrical morphing.
If the flag is set to original (default) the method writes out the undeformed lattice,
if it is set to modified it writes out the deformed lattice.

:param FFDParameters parameters: parameters of the Free Form Deformation.
:param string outfile: name of the output file.
:param bool write_deformed: flag to write the original or modified FFD control lattice.
The default is set to deformed.

:Example:

>>> import pygem.utilities as util
>>> import pygem.params as pars
>>> import numpy as np

>>> params = pars.FFDParameters()
>>> params.read_parameters(filename='tests/test_datasets/parameters_test_ffd_sphere.prm')
>>> util.write_bounding_box(params, 'tests/test_datasets/box_test_sphere.vtk')
"""

aux_x = np.linspace(0, parameters.lenght_box_x, parameters.n_control_points[0])
aux_y = np.linspace(0, parameters.lenght_box_y, parameters.n_control_points[1])
aux_z = np.linspace(0, parameters.lenght_box_z, parameters.n_control_points[2])
lattice_y_coords, lattice_x_coords, lattice_z_coords = np.meshgrid(aux_y, aux_x, aux_z)

if write_deformed == False:
box_points = np.array([lattice_x_coords.ravel(), lattice_y_coords.ravel(), lattice_z_coords.ravel()])
if write_deformed == True:
box_points = np.array([lattice_x_coords.ravel() + parameters.array_mu_x.ravel()*parameters.lenght_box_x, \
lattice_y_coords.ravel() + parameters.array_mu_y.ravel()*parameters.lenght_box_y, \
lattice_z_coords.ravel() + parameters.array_mu_z.ravel()*parameters.lenght_box_z])

n_rows = box_points.shape[1]

box_points = np.dot(parameters.rotation_matrix,box_points) + np.transpose(np.tile(parameters.origin_box, (n_rows,1)))

_write_vtk_box(box_points, outfile)


def _write_vtk_box(box_points, filename):
"""
Method that writes a vtk file containing FFD control points.

:param numpy.ndarray box_points: coordinates of the FFD control points.
:param string filename: name of the output file.
"""
# setup points and vertices
points = vtk.vtkPoints()
vertices = vtk.vtkCellArray()

for index in range(0, box_points.shape[1]):
id = points.InsertNextPoint(box_points[0, index], box_points[1, index], box_points[2, index])
vertices.InsertNextCell(1)
vertices.InsertCellPoint(id)

polydata = vtk.vtkPolyData()
polydata.SetPoints(points)
polydata.SetVerts(vertices)

polydata.Modified()
writer = vtk.vtkDataSetWriter()
writer.SetFileName(filename)

if vtk.VTK_MAJOR_VERSION <= 5:
polydata.Update()
writer.SetInput(polydata)
else:
writer.SetInputData(polydata)

writer.Write()

24 changes: 24 additions & 0 deletions tests/test_datasets/box_modified_test_sphere_true_version5.vtk
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# vtk DataFile Version 3.0
vtk output
ASCII
DATASET POLYDATA
POINTS 12 float
-20 -55 -45 -4.37166 -55 43.6327 -42.9398 31.9333 -40.9551
-27.3115 31.9333 47.6776 1.40315 -49.1766 -48.774 17.0315 -49.1766 39.8587
-21.5367 37.7568 -44.729 -5.90834 37.7568 43.9037 52.8929 -77.5023 -149.241
38.4346 -43.3531 36.0848 -0.133524 43.5802 -48.503 15.4948 43.5802 40.1297

VERTICES 12 24
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11

24 changes: 24 additions & 0 deletions tests/test_datasets/box_modified_test_sphere_true_version6.vtk
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# vtk DataFile Version 4.0
vtk output
ASCII
DATASET POLYDATA
POINTS 12 float
-20 -55 -45 -4.37166 -55 43.6327 -42.9398 31.9333 -40.9551
-27.3115 31.9333 47.6776 1.40315 -49.1766 -48.774 17.0315 -49.1766 39.8587
-21.5367 37.7568 -44.729 -5.90834 37.7568 43.9037 52.8929 -77.5023 -149.241
38.4346 -43.3531 36.0848 -0.133524 43.5802 -48.503 15.4948 43.5802 40.1297

VERTICES 12 24
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11

24 changes: 24 additions & 0 deletions tests/test_datasets/box_test_sphere_true_version5.vtk
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# vtk DataFile Version 3.0
vtk output
ASCII
DATASET POLYDATA
POINTS 12 float
-20 -55 -45 -4.37166 -55 43.6327 -42.9398 31.9333 -40.9551
-27.3115 31.9333 47.6776 1.40315 -49.1766 -48.774 17.0315 -49.1766 39.8587
-21.5367 37.7568 -44.729 -5.90834 37.7568 43.9037 22.8063 -43.3531 -52.5479
38.4346 -43.3531 36.0848 -0.133524 43.5802 -48.503 15.4948 43.5802 40.1297

VERTICES 12 24
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11

24 changes: 24 additions & 0 deletions tests/test_datasets/box_test_sphere_true_version6.vtk
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# vtk DataFile Version 4.0
vtk output
ASCII
DATASET POLYDATA
POINTS 12 float
-20 -55 -45 -4.37166 -55 43.6327 -42.9398 31.9333 -40.9551
-27.3115 31.9333 47.6776 1.40315 -49.1766 -48.774 17.0315 -49.1766 39.8587
-21.5367 37.7568 -44.729 -5.90834 37.7568 43.9037 22.8063 -43.3531 -52.5479
38.4346 -43.3531 36.0848 -0.133524 43.5802 -48.503 15.4948 43.5802 40.1297

VERTICES 12 24
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11

68 changes: 68 additions & 0 deletions tests/test_utilities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

from unittest import TestCase
import unittest
import pygem.utilities as util
import pygem.params as pars
import numpy as np
import filecmp
import os


class TestVtkHandler(TestCase):


def test_utilities_write_original_box(self):
params = pars.FFDParameters()
params.read_parameters(filename='tests/test_datasets/parameters_test_ffd_sphere.prm')

outfilename = 'tests/test_datasets/box_test_sphere.vtk'

util.write_bounding_box(params, outfilename, False)
os.remove(outfilename)


def test_utilities_write_modified_box(self):
params = pars.FFDParameters()
params.read_parameters(filename='tests/test_datasets/parameters_test_ffd_sphere.prm')

outfilename = 'tests/test_datasets/box_test_sphere.vtk'

util.write_bounding_box(params, outfilename)
os.remove(outfilename)


def test_utilities_check_vtk_original_box(self):
import vtk

params = pars.FFDParameters()
params.read_parameters(filename='tests/test_datasets/parameters_test_ffd_sphere.prm')

outfilename = 'tests/test_datasets/box_test_sphere.vtk'
if vtk.VTK_MAJOR_VERSION <= 5:
outfilename_expected = 'tests/test_datasets/box_test_sphere_true_version5.vtk'
else:
outfilename_expected = 'tests/test_datasets/box_test_sphere_true_version6.vtk'

util.write_bounding_box(params, outfilename, False)

self.assertTrue(filecmp.cmp(outfilename, outfilename_expected))
os.remove(outfilename)


def test_utilities_check_vtk_modified_box(self):
import vtk

params = pars.FFDParameters()
params.read_parameters(filename='tests/test_datasets/parameters_test_ffd_sphere.prm')

outfilename = 'tests/test_datasets/box_test_sphere.vtk'
if vtk.VTK_MAJOR_VERSION <= 5:
outfilename_expected = 'tests/test_datasets/box_modified_test_sphere_true_version5.vtk'
else:
outfilename_expected = 'tests/test_datasets/box_modified_test_sphere_true_version6.vtk'

util.write_bounding_box(params, outfilename)

self.assertTrue(filecmp.cmp(outfilename, outfilename_expected))
os.remove(outfilename)