Skip to content

ENH: Ingest ITKSubdivisionQuadEdgeMeshFilter into Modules/Filtering (v4, stacks on #6204)#6229

Merged
hjmjohnson merged 61 commits intoInsightSoftwareConsortium:mainfrom
hjmjohnson:ingest-SubdivisionQuadEdgeMeshFilter
May 7, 2026
Merged

ENH: Ingest ITKSubdivisionQuadEdgeMeshFilter into Modules/Filtering (v4, stacks on #6204)#6229
hjmjohnson merged 61 commits intoInsightSoftwareConsortium:mainfrom
hjmjohnson:ingest-SubdivisionQuadEdgeMeshFilter

Conversation

@hjmjohnson
Copy link
Copy Markdown
Member

@hjmjohnson hjmjohnson commented May 7, 2026

Ingest the standalone remote module
InsightSoftwareConsortium/itkSubdivisionQuadEdgeMeshFilter
into Modules/Filtering/SubdivisionQuadEdgeMeshFilter/ via the v4
ingestion pipeline
introduced in #6204. Triangle/edge-based
QuadEdgeMesh subdivision filters (Loop, Modified Butterfly, Square
Three, Linear) are now in-tree under EXCLUDE_FROM_DEFAULT.

Stacked on #6204 (do not merge until #6204 lands). Closes the
consolidation work of issue #6060 for this module.

Note: The original revision of this PR used the v3 driver
(ingest-remote-module.sh). It has been redone on the v4 pipeline
(ingest-module-v4.sh + sanitize-history.py) so each historical
commit is independently formatted and ghostflow-clean. The PR now
stacks on #6204; the visible diff includes #6204's commits until
that PR merges.

Ingest results (v4)
Aspect Value
Whitelist Utilities/Maintenance/RemoteModuleIngest/whitelists/SubdivisionQuadEdgeMeshFilter.list
Upstream commits → after sanitize 98 → 50
Merge commits preserved (post-sanitize) 30 → 12 (no linearization)
Final tree merge count 13 (incl. ingest merge)
Whitelisted files 55 (include/, test/, CMakeLists.txt, itk-module.cmake)
Content-links 1 .cid, 0 .md5, 0 .shaNNN
Raw binaries in test/ None
examples/ directory Auto-excluded; remains in archived upstream
License Apache-2.0
git blame Walks back to original upstream contributors (Arnaud Gelas 2014, Hans Johnson 2020)
Sanitize-history.py counters
commits walked:        66
prefix auto-prepended: 24
subjects truncated:    3
blank lines inserted:  15
exec-bits cleared:     0
README.rst->.md fixes: 2
dynamic DESCRIPTION rm:5
standalone-guard rm:   4
cmake_min_required rm: 4
blobs scanned:         433
blobs reformatted:     226
by-kind sniff:         cxx=413 py=0 cmake=16 text=3 skip=1

Every commit subject in the rewritten history carries a valid ITK
prefix; ghostflow's only unfixable error remains the upstream root
commit (intrinsic to every remote module).

Local validation
  • pre-commit run --all-files: clean
  • cmake -DModule_SubdivisionQuadEdgeMeshFilter:BOOL=ON .: configures clean
  • ninja SubdivisionQuadEdgeMeshFilter-all: builds clean
  • ctest -R SubdivisionQuadEdgeMeshFilter: 37/37 tests pass

No manual itk-module.cmake fix was needed — v4's sanitize step
auto-converts the upstream file(READ README.rst DESCRIPTION) pattern
to a static set(DOCUMENTATION ...) block.

Commits at PR tip (top → bottom, above #6204's tip `c7768a5377`)
  1. ENH: Enable Module_SubdivisionQuadEdgeMeshFilter in configure-ci
  2. COMP: Remove SubdivisionQuadEdgeMeshFilter .remote.cmake (in-tree)
  3. DOC: Add SubdivisionQuadEdgeMeshFilter README pointing at upstream
  4. ENH: Ingest ITKSubdivisionQuadEdgeMeshFilter into Modules/Filtering
    (merge commit --no-ff --allow-unrelated-histories to whitelisted +
    sanitized filter-repo'd upstream history; preserves 12 upstream
    merges and git blame to original authors)
  5. ENH: Add v4 whitelist for SubdivisionQuadEdgeMeshFilter ingest
Phase B (post-merge) — upstream archival

After this PR merges, run Phase B from a fresh worktree:

Utilities/Maintenance/RemoteModuleIngest/archive-remote-module.sh \
    SubdivisionQuadEdgeMeshFilter

Phase B publishes the upstream removal commit, promotes
MIGRATION_README.md to README.md so the GitHub landing page
renders the migration notice (per the
ingest-archive-readme rule), and flips
archived=true. No upstream side-effects happen until that step.

Refs: #6060, #6204

@github-actions github-actions Bot added type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Enhancement Improvement of existing methods or implementation area:Python wrapping Python bindings for a class type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct area:Filtering Issues affecting the Filtering module area:Remotes Issues affecting the Remote module labels May 7, 2026
@hjmjohnson hjmjohnson force-pushed the ingest-SubdivisionQuadEdgeMeshFilter branch from c1d39ce to 1ffc1f2 Compare May 7, 2026 13:13
@hjmjohnson hjmjohnson changed the title ENH: Ingest ITKSubdivisionQuadEdgeMeshFilter into Modules/Filtering ENH: Ingest ITKSubdivisionQuadEdgeMeshFilter into Modules/Filtering (v4, stacks on #6204) May 7, 2026
hjmjohnson and others added 22 commits May 7, 2026 09:01
Splits the v3 single-driver flow into two independent phases so the
upstream-archival publish step never runs on a working tree that
filter-repo has rewritten:

  - Phase A (ingest-module-v4.sh): local, throwaway clone; rewrites
    history into Modules/<Group>/<Module>; never touches the upstream
    remote.

  - Phase B (archive-remote-module.sh): fresh shallow clone; pushes
    one removal commit + promotes MIGRATION_README.md to README.md;
    flips archived=true.  Gated on the Phase A PR being merged.

The shared sanitize-history.py walks the rewritten branch and applies
the same hooks ITK's .pre-commit-config.yaml enforces:

  - clang-format on every C/C++ blob (content sniff)
  - black on every Python blob (content sniff)
  - gersemi on every CMake blob using ITK's .gersemi.config
  - trailing-whitespace, end-of-file-fixer, mixed-line-ending on
    every text-classified blob
  - VTK / SVG / hash-content sidecar files are skipped intact
  - Every commit subject without an ITK prefix gets one heuristically
    auto-prepended; decisions are logged for operator audit

filter-repo's blob_callback is filename-blind by design, so excludes
are approximated via content sniffing.  IOMeshSTL whitelist is the
first concrete example; smoke-tested via --dry-run successfully
(143->89 commits, 44->24 merges preserved, 108/149 blobs reformatted).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The whitelist admits whole directories (test/, wrapping/, ...) but
some upstream remote modules place CI / packaging scaffolding inside
those (e.g. test/Docker/, .github/, azure-pipelines/).  Without a
deny-pass after the whitelist filter, those leak into ITK history.

Mirrors v3's --invert-paths --path-glob pass; discovered missing on
the first Cuberille v4 ingest (test/Docker/{Dockerfile,build,run,test}.sh
leaked).
Fixes the four classes of ghostflow errors that surfaced on the first
Cuberille v4 ingest (PR InsightSoftwareConsortium#6205) — the only allowable remaining error
should be the unavoidable upstream root commit.

  - Strip *.orig / *.rej / *.BACKUP.* / *.LOCAL.* / *.REMOTE.* /
    *.BASE.* merge-conflict-artifact files from history (catches
    leftover-conflict-marker errors like the .h.orig on Cuberille).
  - sanitize-history.py: cap every commit subject at 78 chars (ghostflow
    / kw-commit-msg rule); excess words move into the body.
  - sanitize-history.py: insert a blank line between subject and body
    when the original commit message lacked one (two-line subject error).
  - sanitize-history.py: clear the executable bit (mode 100755 -> 100644)
    on text-file extensions so root-commit "executable permissions but
    file does not look executable" stops firing.
Many ITK remote modules' itk-module.cmake reads
  file(READ "${MY_CURRENT_DIR}/README.rst" DOCUMENTATION)
to populate the CMake DESCRIPTION variable from the upstream README.

The v4 whitelist intentionally excludes the upstream README (the
operator ships a new README.md as part of the ingest PR), so without
this rewrite every commit's CMakeLists fails to configure post-ingest
until the operator manually patches itk-module.cmake.

sanitize-history.py now rewrites the file(READ ... README.rst ...)
reference to README.md as part of the cmake-blob transform, so every
historical commit on the rewritten branch is independently buildable.

Surfaced on the IOMeshSTL ingest (PR following PR InsightSoftwareConsortium#6204).
…terns

Add a 'Known artifacts at PR-review time' section to capture two
things future ingest operators need to expect but that v3/v4 do not
fix automatically:

  - The single ghostflow-check-main 'root commit not allowed' error
    that every Mode-A merge produces.  Maintainers override at merge.
    Calling it out keeps operators from chasing a non-fix.

  - A short table of code-level patterns Greptile has flagged
    post-ingest on multiple modules (IOMeshSTL InsightSoftwareConsortium#6206, RLEImage InsightSoftwareConsortium#6208):
    signed-vs-unsigned size types, missing override, dead return after
    itkExceptionMacro, stray test args, external-friend declarations,
    GetBuffer-const correctness, and allocator-init invariants.

The table is the durable channel for cross-ingest review knowledge —
extend it as new recurring patterns surface.
ExternalData stores resolved fetched content as .ExternalData_<algo>_<hash>
files alongside the .cid / .md5 sidecars they correspond to.  These
are local fetch cache, not source — ExternalData regenerates them on
demand at consumer-time.  Upstream remote modules sometimes commit
them inadvertently from a CTest run inside their working tree (e.g.
ITKIOMeshSTL had four such files in test/Baseline/, flagged by
@dzenanz on PR InsightSoftwareConsortium#6206).

Add **/.ExternalData_* to the scaffolding deny-pass so they never
enter ITK history.
Upstream remote modules wrap their top-level CMakeLists.txt in

    if(NOT ITK_SOURCE_DIR)
      find_package(ITK REQUIRED)
      list(APPEND CMAKE_MODULE_PATH ${ITK_CMAKE_DIR})
      include(ITKModuleExternal)
    else()
      itk_module_impl()
    endif()

so the same file works both as a fetched remote module and as a
stand-alone CMake project.  In an in-tree ingested module
ITK_SOURCE_DIR is always defined, so the if-branch is dead code;
@dzenanz flagged it on PR InsightSoftwareConsortium#6206 (IOMeshSTL).

Add patch_standalone_build_guard() that detects the idiom (allowing
2- or 4-space indent variants) and replaces it with a bare
itk_module_impl() before gersemi formatting runs.  Track count via
sanitizer.standalone_guard_patches and print it in the run summary.
The 'Greptile post-ingest patterns' table mixed mechanical artifacts
(strippable in Phase A) with semantic concerns (require human
judgment).  Split into two sections so the operator's checklist
shrinks as the sanitizer learns more rules.

Promote .ExternalData_* and the standalone-build CMake guard to the
auto-sanitized table now that the previous two commits handle them.
Upstream remote modules typically begin their top-level CMakeLists.txt
with their own cmake_minimum_required(VERSION X.Y.Z) declaration, often
3.10.2 or earlier.  ITK's top-level CMakeLists pins a higher minimum,
so the per-module line is redundant and frequently *lower* than ITK's
floor.  @dzenanz flagged it on every ingest with the comment 'Version
behind, not needed.' — most recently on PR InsightSoftwareConsortium#6215 (IOFDF).

Add patch_drop_cmake_minimum_required() that detects the idiom and
removes the matching line via a multiline regex.  Track count via
sanitizer.cmake_min_required_drops and print it in the run summary.
Apply alongside patch_standalone_build_guard() in the cmake-blob
branch of blob_callback.
…cmake

Archival README.md files contain semicolons and bracket characters.
CMake's foreach(arg \${ARGN}) splits on semicolons, so reading them
into a DESCRIPTION argument produces CMake (dev) configure warnings
for every module ingested via v4 (observed: RLEImage, SplitComponents,
IOFDF, IOMeshMZ3, IOMeshSTL).

Add patch_dynamic_description() to sanitize-history.py to strip the
get_filename_component/file(READ README.md) preamble and replace
DESCRIPTION "\${DOCUMENTATION}" with a static one-liner during history
rewrite.  Document the pattern in INGESTION_STRATEGY_v4.md.
hjmjohnson and others added 19 commits May 7, 2026 09:01
This check replaces default bodies of special member functions with
= default;. The explicitly defaulted function declarations enable more
opportunities in optimization, because the compiler might treat
explicitly defaulted functions as trivial.

Additionally, the C++11 use of = default more clearly expreses the
intent for the special member functions.
The mission of NumFOCUS is to promote open
practices in research, data, and scientific
computing.

https://numfocus.org
The iterative subdivision, conditional subdivision, and
criteria classes provided by this module are templated
over some subset of the provided subdivision filters (rather
than simply being templated over the QuadEdgeMesh type).
The current wrappers provide incorrect template arguments to
these classes, causing a failure of compilation when the wrapping
is enabled.  This patch corrects these errors, allowing the
build to compile.
The Delaunay Conforming filter in the testing suite is causing
a number of test failures.  This patch disables the Delaunay
Conforming filter temporarily while the bug is investigated, and
adds a FIXME comment explaining the change.
This patch expands test coverage, modernizes test syntax, and prefers the use
of ITK testing macros to manual testing.  Line coverage is improved from 83.9%
to 88.6%.  Function coverage is improved from 62.7% to 80.8%.
Currently, any CellData in the input mesh is not passed to the
subdivided output mesh.  This patch checks if any CellData exists,
and if so, passes that data into the child cells of the subdivided
output mesh.  This patch creates a new method, PassCellData, which
is called immediately following each call to AddFaceTriangle.  Moreover,
the interfaces to SplitTriangleFromOneEdge, SplitTriangleFromTwoEdges,
and SplitTriangleFromThreeEdges have all been extended to take the
cell identifier of the input cell, so that it will be available to pass to
the PassCellData method.  This has also required that the class for
iterative subdivision (IterativeCellSubdivisionQuadEdgeMeshFilter) be
updated.
1. Test an untested branch of itkTriangleCellSubdivisionQuadEdgeMeshFilterTest
   so as to exercise AddSubdividedCellId().
2. Add assertions to check the functionality of SetCellsToBeSubdivided()
   and AddSubdividedCellId().
3. Reduce redundancy in the CMakeLists.txt file for the testing suite by
   using foreach loops as appropriate.
4. Minimal improvement in testing coverage.
     Line coverage: 88.9% => 89.6%
     Function coverage: 81.2% => 84.0%
This patch addresses warnings due to:

1. Unused local typedefs.
2. Comparison of strings with string literals.

Warnings were emitted on g++ 9.3.0 when compiling with
Wall, Wextra, Wmissing-braces.
Fixes changes made in InsightSoftwareConsortium#2053. ITK_DISALLOW_COPY_AND_ASSIGN will be used if ITK_FUTURE_LEGACY_REMOVE=OFF.
The ability to include either .h or .hxx files as
header files required recursively reading the
.h files twice.  The added complexity is
unnecessary, costly, and can confuse static
analysis tools that monitor header guardes (due
to reaching the maximum depth of recursion
limits for nested #ifdefs in checking).
When preparing for the future with ITK by setting
ITK_FUTURE_LEGACY_REMOVE:BOOL=ON
ITK_LEGACY_REMOVEBOOL=ON

The future preferred macro should be used
│ -  itkTypeMacro
│ +  itkOverrideGetNameOfClassMacro
For the sake of code readability, a new 'CoordinateType' alias is added for
each nested 'CoordRepType' alias. The old 'CoordRepType' aliases will still be
available with ITK 6.0, but it is recommended to use 'CoordinateType' instead.
The 'CoordRepType' aliases will be removed when 'ITK_FUTURE_LEGACY_REMOVE' is
enabled. Similarly, 'InputCoordinateType', 'OutputCoordinateType', and
'ImagePointCoordinateType' replace 'InputCoordRepType', 'OutputCoordRepType',
and 'ImagePointCoordRepType', respectively.
@hjmjohnson hjmjohnson force-pushed the ingest-SubdivisionQuadEdgeMeshFilter branch from 1ffc1f2 to 58da70a Compare May 7, 2026 14:02
@hjmjohnson hjmjohnson marked this pull request as ready for review May 7, 2026 16:07
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 7, 2026

Greptile Summary

This PR ingests the itkSubdivisionQuadEdgeMeshFilter remote module into Modules/Filtering/SubdivisionQuadEdgeMeshFilter/ using the new v4 ingestion pipeline (filter-repo + sanitize-history.py), replacing the remote .cmake fetch entry. Three pre-existing upstream bugs enter the in-tree codebase that warrant fixing before or alongside merging.

  • The LoopTriangleCellSubdivisionQuadEdgeMeshFilter non-uniform smoothing path inserts cell IDs into smoothedPointSet instead of point IDs, silently disabling vertex smoothing in adaptive Loop subdivision.
  • Both TriangleCellSubdivisionQuadEdgeMeshFilter::GenerateOutputCells() and SquareThreeTriangleCellSubdivisionQuadEdgeMeshFilter::GenerateOutputCells() use continue without first advancing the cellIt iterator, causing an infinite loop whenever the input mesh contains any non-triangle cell.
  • The v4 tooling (sanitize-history.py, ingest-module-v4.sh, archive-remote-module.sh) looks well-structured; the module declaration, CMake wiring, and test coverage are correct.

Confidence Score: 3/5

Safe to merge only for pure-triangle meshes; mixed-cell meshes will hang and adaptive Loop subdivision produces wrong vertex positions.

Three defects carried in from upstream: one causes incorrect (silently wrong) output for adaptive Loop subdivision, and two cause infinite loops on any mesh that mixes triangle cells with other cell types. The all-triangle venus.vtk test data masks all three at CI time, so they would reach users undetected.

itkLoopTriangleCellSubdivisionQuadEdgeMeshFilter.hxx (wrong smoothedPointSet population), itkTriangleCellSubdivisionQuadEdgeMeshFilter.hxx and itkSquareThreeTriangleCellSubdivisionQuadEdgeMeshFilter.hxx (continue-without-advance infinite loop).

Important Files Changed

Filename Overview
Modules/Filtering/SubdivisionQuadEdgeMeshFilter/include/itkLoopTriangleCellSubdivisionQuadEdgeMeshFilter.hxx Two defects: wrong ID type inserted into smoothedPointSet (cell ID instead of point ID), and a large dead commented-out block from a prior refactor.
Modules/Filtering/SubdivisionQuadEdgeMeshFilter/include/itkTriangleCellSubdivisionQuadEdgeMeshFilter.hxx GenerateOutputCells() uses continue without advancing cellIt; any non-triangle cell in the input mesh causes an infinite loop.
Modules/Filtering/SubdivisionQuadEdgeMeshFilter/include/itkSquareThreeTriangleCellSubdivisionQuadEdgeMeshFilter.hxx GenerateOutputCells() has the same continue-without-advance infinite loop as itkTriangleCellSubdivisionQuadEdgeMeshFilter.hxx.
Modules/Filtering/SubdivisionQuadEdgeMeshFilter/itk-module.cmake New module declaration with correct DEPENDS on ITKQuadEdgeMesh/ITKQuadEdgeMeshFiltering, EXCLUDE_FROM_DEFAULT, and test dependencies; no issues.
Utilities/Maintenance/RemoteModuleIngest/sanitize-history.py New v4 ingestion script; CID file detection regex matches only hex hashes (not base32 CIDv1), so .cid files receive text-only whitespace normalization rather than being skipped entirely — harmless in practice.
Utilities/Maintenance/RemoteModuleIngest/ingest-module-v4.sh New Phase A driver shell script; uses set -euo pipefail, proper argument parsing, and preflight checks for required tools.
Modules/Remote/SubdivisionQuadEdgeMeshFilter.remote.cmake Correctly removed — the in-tree module replaces the remote fetch entry.
Modules/Filtering/SubdivisionQuadEdgeMeshFilter/test/CMakeLists.txt Test driver and parametric test entries look correct; covers cell- and edge-based methods plus criterion-driven tests.
pyproject.toml Adds -DModule_SubdivisionQuadEdgeMeshFilter:BOOL=ON to the CI configure command; correct and expected for an in-tree module.

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
    class SubdivisionQuadEdgeMeshFilter {
        +GenerateOutputPoints()
        +GenerateOutputCells()
        +GenerateData()
        #m_EdgesPointIdentifier
    }
    class TriangleCellSubdivisionQuadEdgeMeshFilter {
        +GenerateOutputPoints()
        +GenerateOutputCells()
        +SetCellsToBeSubdivided()
        +AddSubdividedCellId()
        #m_CellsToBeSubdivided
        #m_Uniform
    }
    class TriangleEdgeCellSubdivisionQuadEdgeMeshFilter {
        +GenerateOutputPoints()
        +GenerateOutputCells()
    }
    class ConditionalSubdivisionQuadEdgeMeshFilter {
        +SetCriterion()
    }
    class LoopTriangleCellSubdivisionQuadEdgeMeshFilter {
        +AddNewCellPoints()
        +CopyInputMeshToOutputMeshPoints()
        +SmoothingPoint()
    }
    class SquareThreeTriangleCellSubdivisionQuadEdgeMeshFilter {
        +AddNewCellPoints()
        +GenerateOutputCells()
    }
    SubdivisionQuadEdgeMeshFilter <|-- TriangleCellSubdivisionQuadEdgeMeshFilter
    SubdivisionQuadEdgeMeshFilter <|-- TriangleEdgeCellSubdivisionQuadEdgeMeshFilter
    TriangleCellSubdivisionQuadEdgeMeshFilter <|-- ConditionalSubdivisionQuadEdgeMeshFilter
    TriangleCellSubdivisionQuadEdgeMeshFilter <|-- LoopTriangleCellSubdivisionQuadEdgeMeshFilter
    TriangleCellSubdivisionQuadEdgeMeshFilter <|-- SquareThreeTriangleCellSubdivisionQuadEdgeMeshFilter
Loading

Reviews (1): Last reviewed commit: "ENH: Enable Module_SubdivisionQuadEdgeMe..." | Re-trigger Greptile

hjmjohnson added 4 commits May 7, 2026 12:33
In the non-uniform adaptive path of LoopTriangleCellSubdivisionQuadEdgeMeshFilter,
the inner loop was inserting *it (the OutputCellIdentifier from m_CellsToBeSubdivided)
instead of *pter (the InputPointIdentifier from the cell's PointIds iterator) into
smoothedPointSet. The set is later checked by point index via
smoothedPointSet.count(ptIt->Index()), so cell IDs and point IDs ended up compared
across types — the smoothing step was silently skipped for nearly every vertex it
should have moved.

Caught by Greptile review on PR InsightSoftwareConsortium#6229 ingest of ITKSubdivisionQuadEdgeMeshFilter.
A regression test that constructs a small in-memory mesh and exercises the
non-uniform adaptive Loop path follows in a subsequent commit.
In TriangleCellSubdivisionQuadEdgeMeshFilter::GenerateOutputCells() and
SquareThreeTriangleCellSubdivisionQuadEdgeMeshFilter::GenerateOutputCells(),
the guard branch that skips non-triangle / null cells used `continue` to
restart the while-loop body, but the `++cellIt` lived at the bottom of the
loop. The first non-triangle (or null) cell encountered caused an infinite
loop on the same iterator.

Existing tests pass because the venus.vtk regression mesh is purely
triangular, but any input with a mixed cell topology hangs both filters.
Caught by Greptile review on PR InsightSoftwareConsortium#6229. Regression test follows in a
subsequent commit.
…t helper

The non-uniform adaptive Loop path retained a 44-line commented-out block
of the original inline neighborhood-smoothing computation. The live code
beneath it now delegates to the SmoothingPoint() helper that encodes the
identical algorithm; the comment was a refactor artifact, not an
alternative implementation. Caught by Greptile review on PR InsightSoftwareConsortium#6229.
Adds itkSubdivisionQuadEdgeMeshFilterRegressionTest covering the three
regressions caught by Greptile review on PR InsightSoftwareConsortium#6229's ingest:

  1. Loop non-uniform adaptive smoothing — constructs a 4-point, 2-cell
     mesh, sets CellsToBeSubdivided = {0}, asserts that all three vertices
     of cell 0 (point IDs 0, 1, 2) are smoothed. Before the fix the
     smoothedPointSet contained {0} (the cell ID), so only the
     coincidentally-indexed point ever moved.

  2. TriangleCellSubdivision termination — injects a 4-point polygon cell
     into the cells container alongside the triangles and runs
     LinearTriangleCellSubdivisionQuadEdgeMeshFilter. The CTest TIMEOUT
     of 30 seconds catches the infinite-loop regression.

  3. SquareThreeTriangleCellSubdivision termination — same shape, runs
     SquareThreeTriangleCellSubdivisionQuadEdgeMeshFilter on the same
     mixed-cell mesh.

The existing venus.vtk-driven tests cannot trigger any of these because
that mesh is purely triangular and is exercised only through the
uniform-subdivide-all path.
@hjmjohnson hjmjohnson merged commit e18a952 into InsightSoftwareConsortium:main May 7, 2026
19 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Filtering Issues affecting the Filtering module area:Python wrapping Python bindings for a class area:Remotes Issues affecting the Remote module type:Enhancement Improvement of existing methods or implementation type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants