Skip to content

External aerodynamics example: Mesh decimation has no effect in decimate_mesh (derived arrays not updated) #51

@jak-sch

Description

@jak-sch

Bug description

The decimate_mesh function in the external aerodynamics example pipeline does not apply any effective mesh decimation. Although the function calls PyVista’s decimation methods, the final output in data.surface_polydata remains identical to the input mesh. As a consequence, all downstream surface arrays (surface_mesh_centers, surface_areas, surface_normals, surface_fields) also remain unchanged, and the exported files have exactly the same size before and after decimation.

Affected code:

def decimate_mesh(
data: ExternalAerodynamicsExtractedDataInMemory,
algo: str = None,
reduction: float = 0.0,
**kwargs,
) -> ExternalAerodynamicsExtractedDataInMemory:
"""Decimate mesh using pyvista."""
if reduction < 0:
logger.error(f"Reduction must be >= 0: {reduction}")
return data
if not algo or reduction == 0:
return data
mesh = data.surface_polydata
# Need point_data to interpolate target mesh node values.
mesh = mesh.cell_data_to_point_data()
# Decimation algos require tri-mesh.
mesh = mesh.triangulate()
match algo:
case "decimate_pro":
mesh = mesh.decimate_pro(reduction, **kwargs)
case "decimate":
if mesh.n_points > 400_000:
warnings.warn("decimate algo may hang on meshes of size more than 400K")
mesh = mesh.decimate(
reduction,
attribute_error=True,
scalars=True,
vectors=True,
**kwargs,
)
case _:
logger.error(f"Unsupported decimation algo {algo}")
return data
# Compute cell data.
data.surface_polydata = mesh.point_data_to_cell_data()
# Update metadata
data.metadata.decimation_algo = algo
data.metadata.decimation_reduction = reduction
return data

Root cause

After decimating the mesh, the function assigns:

data.surface_polydata = mesh.point_data_to_cell_data()

but does not recompute any of the dependent surface arrays stored inside ExternalAerodynamicsExtractedDataInMemory. These arrays are still based on the pre-decimation mesh. Because the writer exports these arrays instead of re-deriving them from the modified mesh, the resulting output files remain unchanged.

How to reproduce

  1. Run any external aerodynamics ETL config with:
preprocessing:
  decimation_algo: decimate_pro
  decimation_reduction: 0.8
  1. Compare the size of the generated surface .vtp or downstream data.
  2. The file size and number of cells remain exactly the same before and after decimation.

Suggested fix

After decimation, recompute all surface‑related arrays from the actual decimated mesh, not from the original mesh.

The key missing logic is roughly:

# After mesh decimation
mesh = mesh.point_data_to_cell_data()
data.surface_polydata = mesh

# Recompute derived arrays
data.surface_mesh_centers = mesh.cell_centers().points.astype(np.float32)
data.surface_areas = np.asarray(mesh.compute_cell_sizes().cell_data["Area"], dtype=np.float32)
data.surface_normals = np.asarray(mesh.compute_normals(cell_normals=True).cell_data["Normals"], dtype=np.float32)

# Reconstruct surface_fields based on metadata and available cell_data
...

I can open a PR with the fix if desired.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions