Skip to content

Points on bounding box not deforming #272

@MarkoLeskovar

Description

@MarkoLeskovar

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.
point_deformation
point_deformation_2

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions