Summary
Crop Geometry (Image) carries the entire Feature Attribute Matrix across to the cropped
geometry with its values untouched, even though cropping invalidates essentially all of it. Nothing
in preflight says so. We need a preflight warning and/or a preflight updated value stating plainly
that all Feature data becomes invalid after this filter runs and must be recomputed.
Several other filters share the same defect, listed below.
The precedent already exists in the same filter
CropImageGeometryFilter::preflightImpl() already emits a preflight updated value for exactly this
class of problem — but only for NeighborList objects
(src/Plugins/SimplnxCore/src/SimplnxCore/Filters/CropImageGeometryFilter.cpp:442-450):
preflightUpdatedValues.push_back(
{"Invalidated NeighborLists",
fmt::format("This filter will modify the Cell Level Array(s) '{}' which causes all feature level "
"NeighborLists to become invalid. These NeighborLists will not be copied to the new geometry:{}", ...)});
Meanwhile every ordinary IDataArray in that same Attribute Matrix is recreated on the destination
with the source tuple dimensions and no warning at all (line 435):
auto tDims = srcCellFeatureData.getShape();
...
resultOutputActions.value().appendAction(std::make_unique<CreateArrayAction>(dataType, tDims, std::move(componentShape), dataArrayPath));
So the filter warns about the one thing it drops, and stays silent about everything it preserves
with stale values. The arrays keep their original names and plausible-looking numbers, which makes
the failure silent — a user can take EquivalentDiameters straight from a cropped geometry into a
statistics or synthetic-building pipeline and get quietly wrong results.
What is actually invalid after a crop
NumElements, Volumes, EquivalentDiameters — features clipped by the crop boundary have fewer
cells than they did
Centroids, AxisLengths, AxisEulerAngles, AspectRatios, Omega3s — shape and position of any
clipped feature changed, and centroids are relative to a new origin
SurfaceFeatures — a feature that was interior becomes a surface feature once the crop plane cuts
through it or removes its neighbor
NumNeighbors, SharedSurfaceAreaList — neighbors outside the crop region no longer exist
AvgQuats, AvgEulerAngles, and any other per-feature average — cell membership changed
- Features lying entirely outside the crop region still occupy tuples carrying their original values
Other affected filters
Same pattern — a Renumber Features option, a feature Attribute Matrix copied wholesale, and a
NeighborList-only warning:
| Filter |
Location |
| Resample Geometry (Image) |
Algorithms/../ResampleImageGeomFilter.cpp:292 |
The feature-removal filters have the same underlying defect by a different route. They call
nx::core::RemoveInactiveObjects(), which compacts the Feature Attribute Matrix by copying each
surviving feature's tuple to its new index, carrying the values verbatim:
| Filter |
Location |
| Require Minimum Number of Neighbors |
Algorithms/RequireMinNumNeighbors.cpp:354 |
| Remove Minimum Size Features |
Algorithms/RequireMinimumSizeFeatures.cpp:156 |
| Remove/Extract Flagged Features |
Algorithms/RemoveFlaggedFeatures.cpp |
For those three, NumNeighbors and SurfaceFeatures are always stale because the topology changed.
When Fill-in Removed Features is enabled the surviving features physically grow into the vacated
cells, so every size- and shape-derived quantity is wrong as well.
This list is not necessarily complete. Any filter that changes which cells exist, changes the
sampling, or changes feature membership while a Feature Attribute Matrix persists belongs in the
audit.
Proposed work
- Emit a preflight warning naming the Feature Attribute Matrix and stating that its arrays will
hold pre-operation values afterward and must be recomputed.
- Emit a preflight updated value so the impact is visible in the GUI parameter panel before the
user runs anything — following the existing "Invalidated NeighborLists" pattern, but widened to
cover the whole Attribute Matrix.
- Enumerate the affected Feature arrays by name rather than emitting generic prose, the way the
NeighborList message already does.
- Implement once as a shared helper — next to
NeighborListRemovalPreflightCode() in
src/simplnx/Utilities/DataGroupUtilities.{hpp,cpp} — and call it from every affected filter
instead of duplicating the logic five times.
- Audit the remaining geometry-modifying filters for the same pattern.
Notes
Worth prioritizing relative to V&V scheduling: Require Minimum Number of Neighbors was fully V&V'ed
in #1694, and Remove/Extract Flagged Features is queued for V&V in #1698. A silent
data-invalidation problem of this kind should be resolved before further sign-offs treat these
filters as complete.
Summary
Crop Geometry (Image)carries the entire Feature Attribute Matrix across to the croppedgeometry with its values untouched, even though cropping invalidates essentially all of it. Nothing
in preflight says so. We need a preflight warning and/or a preflight updated value stating plainly
that all Feature data becomes invalid after this filter runs and must be recomputed.
Several other filters share the same defect, listed below.
The precedent already exists in the same filter
CropImageGeometryFilter::preflightImpl()already emits a preflight updated value for exactly thisclass of problem — but only for
NeighborListobjects(
src/Plugins/SimplnxCore/src/SimplnxCore/Filters/CropImageGeometryFilter.cpp:442-450):preflightUpdatedValues.push_back( {"Invalidated NeighborLists", fmt::format("This filter will modify the Cell Level Array(s) '{}' which causes all feature level " "NeighborLists to become invalid. These NeighborLists will not be copied to the new geometry:{}", ...)});Meanwhile every ordinary
IDataArrayin that same Attribute Matrix is recreated on the destinationwith the source tuple dimensions and no warning at all (line 435):
auto tDims = srcCellFeatureData.getShape(); ... resultOutputActions.value().appendAction(std::make_unique<CreateArrayAction>(dataType, tDims, std::move(componentShape), dataArrayPath));So the filter warns about the one thing it drops, and stays silent about everything it preserves
with stale values. The arrays keep their original names and plausible-looking numbers, which makes
the failure silent — a user can take
EquivalentDiametersstraight from a cropped geometry into astatistics or synthetic-building pipeline and get quietly wrong results.
What is actually invalid after a crop
NumElements,Volumes,EquivalentDiameters— features clipped by the crop boundary have fewercells than they did
Centroids,AxisLengths,AxisEulerAngles,AspectRatios,Omega3s— shape and position of anyclipped feature changed, and centroids are relative to a new origin
SurfaceFeatures— a feature that was interior becomes a surface feature once the crop plane cutsthrough it or removes its neighbor
NumNeighbors,SharedSurfaceAreaList— neighbors outside the crop region no longer existAvgQuats,AvgEulerAngles, and any other per-feature average — cell membership changedOther affected filters
Same pattern — a
Renumber Featuresoption, a feature Attribute Matrix copied wholesale, and aNeighborList-only warning:
Algorithms/../ResampleImageGeomFilter.cpp:292The feature-removal filters have the same underlying defect by a different route. They call
nx::core::RemoveInactiveObjects(), which compacts the Feature Attribute Matrix by copying eachsurviving feature's tuple to its new index, carrying the values verbatim:
Algorithms/RequireMinNumNeighbors.cpp:354Algorithms/RequireMinimumSizeFeatures.cpp:156Algorithms/RemoveFlaggedFeatures.cppFor those three,
NumNeighborsandSurfaceFeaturesare always stale because the topology changed.When Fill-in Removed Features is enabled the surviving features physically grow into the vacated
cells, so every size- and shape-derived quantity is wrong as well.
This list is not necessarily complete. Any filter that changes which cells exist, changes the
sampling, or changes feature membership while a Feature Attribute Matrix persists belongs in the
audit.
Proposed work
hold pre-operation values afterward and must be recomputed.
user runs anything — following the existing
"Invalidated NeighborLists"pattern, but widened tocover the whole Attribute Matrix.
NeighborList message already does.
NeighborListRemovalPreflightCode()insrc/simplnx/Utilities/DataGroupUtilities.{hpp,cpp}— and call it from every affected filterinstead of duplicating the logic five times.
Notes
Worth prioritizing relative to V&V scheduling:
Require Minimum Number of Neighborswas fully V&V'edin #1694, and
Remove/Extract Flagged Featuresis queued for V&V in #1698. A silentdata-invalidation problem of this kind should be resolved before further sign-offs treat these
filters as complete.