-
Notifications
You must be signed in to change notification settings - Fork 122
Description
Dear PyGem Team.
Background
I have the following problem. I have a bunch of meshes to which I want to apply some random deformations using the FFD transformer. Basically, I position the vertices of my surface mesh somewhere in space and initialize the FFD object such that the control points lie exactly on the bounding box of the object. In other words, control points are also the bounding box of my mesh.
Presumed bug
I have noticed that points that lie exactly on plane of that bounding box do not deform as they should. The opposite, they do not deform at all. This creates weird looking deformation patterns, as shown in image below.


To Reproduce
Here is a code to reproduce the similar error, but with random points instead. Points marked in orange are the ones that do not deform.
`
# Import modules
import numpy as np
import pyvista as pv
from pygem import FFD
# Define points
num_points = 1000
points = np.random.random(size=(num_points, 3)) * 100
# Get mesh bounding box
mesh_bbox = [
(np.min(points[:, 0]), np.max(points[:, 0])),
(np.min(points[:, 1]), np.max(points[:, 1])),
(np.min(points[:, 2]), np.max(points[:, 2])),
]
mesh_bbox_length = np.asarray(mesh_bbox)[:, 1] - np.asarray(mesh_bbox)[:, 0]
mesh_bbox_origin = np.mean(np.asarray(mesh_bbox), axis=1)
# Control lattice
lattice = [2, 2, 2]
# Free-Form Deformation class
ffd_transformer = FFD(n_control_points=lattice)
# Print info
print(ffd_transformer)
# Center the control lattice
ffd_transformer.box_length = mesh_bbox_length
ffd_transformer.box_origin = mesh_bbox_origin - 0.5 * mesh_bbox_length
# Apply deformations (relative size to between 0-1 of the bbox)
ffd_transformer.array_mu_x[1, 1, 1] = 0.5
ffd_transformer.array_mu_y[1, 1, 1] = 0.5
ffd_transformer.array_mu_z[1, 1, 1] = 0.5
# Apply deformations
deformed_points = ffd_transformer(points)
# Differences
diff = deformed_points - points
zero_ids = np.where(np.linalg.norm(diff, axis=1) == 0)[0]
# Show the mesh
pl = pv.Plotter()
pl.add_points(points, render_points_as_spheres=True, color='blue', opacity=0.5, label='Original Mesh')
pl.add_points(deformed_points, render_points_as_spheres=True, color='red', opacity=0.5, label='Deformed Mesh')
pl.add_points(ffd_transformer.control_points(), render_points_as_spheres=True, color='green', point_size=20, label='Control Points')
# Plot error points
if len(zero_ids) != 0:
pl.add_points(deformed_points[zero_ids, :], render_points_as_spheres=True, color='orange', point_size=20)
# Show everything
pl.add_legend()
pl.show()`
Expected behaviour
I would expect all the points to deform according to some rules defined in the FFD. Am I understanding this wrong, of this this a bug in the code?
Best regards,
Marko