ENH: Ingest ITKIOMeshSTL into Modules/IO#6206
Merged
hjmjohnson merged 98 commits intoInsightSoftwareConsortium:mainfrom May 5, 2026
Merged
ENH: Ingest ITKIOMeshSTL into Modules/IO#6206hjmjohnson merged 98 commits intoInsightSoftwareConsortium:mainfrom
hjmjohnson merged 98 commits intoInsightSoftwareConsortium:mainfrom
Conversation
Added internal copy of points in WritePoints(). Added computation of normal and print out of point coordinates in WriteCells(). Produced first successful write out of the sphere.stl file, and was able to open it with meshlab.
Introduced a templated function to manage the multiple cases of point coordinate types.
Still assuming that points are provided in a right handed order.
The .STL (in capitals) extension is now supported too in the filename.
And corresponding test.
Parsed input file both in ASCII and BINARY, stored points into an std::set.
Added an std::vector to hold, for each cell, the triplet of point Ids corresponding to the vertices of that particular triangle. Related the pointIds to positions in the std::set that de-duplicates points.
Now package the information about point coordinates into a buffer that is passed back to the MeshFileReader. Adjusted the helper data structures that hold the pointIds and the iterators to unique points in the a point set.
Now recomposing the cells information in the buffer that goes back to the MeshFileReader. Still have debugging issues with reading enough cells, and confounding the input points.
After adding a tetrahedron test, debugged the process of reading and consolidating incoming vertices. Fixed the reading of STL files.
Replaced previous hash, with a more consistent compare method.
When transferring points from the Point Map to the points buffer, the points must be stored in the location indicated by the second element of the map pairs. Those are the ordered locations of the points, to which the cell point ids are referring. Now manage to read and write the sphere.stl file.
It was off due to the initial read of the header used to determine whether the input file is ASCII or BINARY.
Added these two classes to the STLMeshIO group.
The STL format assumes little endianness in the files:
http://en.wikipedia.org/wiki/STL_(file_format)#Binary_STL
Here we introduce conversions between System endianness, and little
endianness when reading and writing in BINARY format.
At the end of the test, we now print out the Endianness of the system. This should be helpful when verifying STL files in BINARY format.
Suggested in code review by Arnaud Gelas.
Splitted the WriteCells() method into BINARY and ASCII cases, as suggested by Arnaud Gelas in code review. It makes easier to follow the logic of each individual case.
To make it consistent in all the CMake infrastructure.
That before were used to verify that all cells were triangles.
To address compilation errors from MacOSX-gcc4.2-Release-IOSTL.
As a Remote Module, EXCLUDE_FROM_DEFAULT needs to be added from the module being inadvertently turned on in a fresh build after it was downloaded in a previous build.
"PointValueType" was both the template parmeter of WritePointsTyped() and a typedef of the enclosing class. This was generating errors with GCC on OSX. Renamed the template parameter to "TPointsBuffer" to fix this error. Also added a static_cast to make the conversion to the internal value type explicit. Also made the parameter for WritePointsTyped() a const pointer to const values, to clarify its intended use as an input buffer.
BUG: Add EXCLUDE_FROM_DEFAULT.
BUG: Fix WritePointsTyped() to no longer use conflicting typenames
Member
|
in |
Member
|
In |
hjmjohnson
added a commit
to hjmjohnson/ITK
that referenced
this pull request
May 4, 2026
Five concerns from Greptile's draft review of PR InsightSoftwareConsortium#6206: P1: STL binary spec is UINT32, but read/write paths declared int32_t. The high-bit case decremented through negative values (signed-integer overflow, UB) and SetNumberOfCells silently wrapped to huge unsigned IdentifierType. Switched both call sites to uint32_t and added Read/WriteUInt32AsBinary helpers (int32 helpers kept for source compat). P2: Three unreachable returns after itkExceptionMacro removed. P2: WriteMeshInformation 'Unable to open file' said 'inputFilename=' while opening the OUTPUT stream. Corrected to 'outputFilename='. P2: Test reader->Update() now wrapped in ITK_TRY_EXPECT_NO_EXCEPTION to match writer->Update() and the rest of ITK's tests. P2 (greptile false positive): STLMeshIO::Read() was suggested for an override specifier. MeshIOBase has no virtual Read() to override, so 'virtual void Read();' is correct as-is. Reverted.
hjmjohnson
added a commit
to hjmjohnson/ITK
that referenced
this pull request
May 5, 2026
…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.
Brings IOMeshSTL from a configure-time remote fetch into the ITK source tree at Modules/IO/IOMeshSTL/ using the v4 ingestion pipeline (whitelist filter-repo + per-commit clang-format + black + commit-prefix sanitization). Upstream repo: https://github.com/InsightSoftwareConsortium/ITKIOMeshSTL.git Upstream tip: fb18e5d83415603d977279e0546bb55c1ece623d Ingest date: 2026-05-04 Whitelist: IOMeshSTL.list Per-commit transforms applied across all 89 commits: - filter-repo --paths-from-file (whitelist) - filter-repo --to-subdirectory-filter Modules/IO/IOMeshSTL - clang-format -style=file (ITK main's .clang-format) for *.cxx/.h/.hxx/... - black for *.py - heuristic ITK prefix added to commit subjects without one Merge topology preserved: 44 -> 24 merge(s). Primary author: Luis Ibanez <luis.ibanez@kitware.com> Co-authored-by: Bradley Lowekamp <blowekamp@mail.nih.gov> Co-authored-by: Brian Helba <brian.helba@kitware.com> Co-authored-by: Davis Vigneault <davis.vigneault@gmail.com> Co-authored-by: Dženan Zukić <dzenan.zukic@kitware.com> Co-authored-by: Hans J. Johnson <hans-johnson@uiowa.edu> Co-authored-by: Hans Johnson <hans-johnson@uiowa.edu> Co-authored-by: Hans Johnson <hans.j.johnson@gmail.com> Co-authored-by: Jon Haitz Legarreta <jhlegarreta@vicomtech.org> Co-authored-by: Jon Haitz Legarreta Gorroño <jon.haitz.legarreta@gmail.com> Co-authored-by: Mathew Seng <mathewseng@gmail.com> Co-authored-by: Matt McCormick <matt.mccormick@kitware.com> Co-authored-by: Matt McCormick <matt@mmmccormick.com> Co-authored-by: Tom Birdsong <tom.birdsong@kitware.com> Co-authored-by: Zach Williamson <zachary-williamson@uiowa.edu>
Five concerns from Greptile's draft review of PR InsightSoftwareConsortium#6206: P1: STL binary spec is UINT32, but read/write paths declared int32_t. The high-bit case decremented through negative values (signed-integer overflow, UB) and SetNumberOfCells silently wrapped to huge unsigned IdentifierType. Switched both call sites to uint32_t and added Read/WriteUInt32AsBinary helpers (int32 helpers kept for source compat). P2: Three unreachable returns after itkExceptionMacro removed. P2: WriteMeshInformation 'Unable to open file' said 'inputFilename=' while opening the OUTPUT stream. Corrected to 'outputFilename='. P2: Test reader->Update() now wrapped in ITK_TRY_EXPECT_NO_EXCEPTION to match writer->Update() and the rest of ITK's tests. P2 (greptile false positive): STLMeshIO::Read() was suggested for an override specifier. MeshIOBase has no virtual Read() to override, so 'virtual void Read();' is correct as-is. Reverted.
In-tree, ITK_SOURCE_DIR is always defined, so the 'if(NOT ITK_SOURCE_DIR) ... find_package(ITK) ... else() itk_module_impl()' guard is dead code. Address @dzenanz review comment.
Four .ExternalData_MD5_<hash> files survived the ingest from the
upstream module's local fetch cache. They are not source — ExternalData
re-creates them on demand alongside the .cid sidecars they correspond
to (sphere.{stl,vtk}, tetrahedron.{stl,vtk}). Address @dzenanz review
comment.
fffd214 to
f100c25
Compare
Member
Author
|
Both points addressed in the latest push:
Branch was also rebased onto the latest |
hjmjohnson
added a commit
to hjmjohnson/ITK
that referenced
this pull request
May 5, 2026
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.
hjmjohnson
added a commit
to hjmjohnson/ITK
that referenced
this pull request
May 5, 2026
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.
This was referenced May 5, 2026
Member
|
/azp run ITK.macOS.Python |
dzenanz
approved these changes
May 5, 2026
….txt In-tree, ITK's top-level CMakeLists pins the CMake minimum, so the per-module declaration is dead code. Pre-emptive cleanup matching the v4 ingest-pipeline rule codified in PR InsightSoftwareConsortium#6204 (sanitize-history.py:patch_drop_cmake_minimum_required).
8c008f2
into
InsightSoftwareConsortium:main
14 of 17 checks passed
hjmjohnson
added a commit
to hjmjohnson/ITK
that referenced
this pull request
May 6, 2026
Five concerns from Greptile's draft review of PR InsightSoftwareConsortium#6206: P1: STL binary spec is UINT32, but read/write paths declared int32_t. The high-bit case decremented through negative values (signed-integer overflow, UB) and SetNumberOfCells silently wrapped to huge unsigned IdentifierType. Switched both call sites to uint32_t and added Read/WriteUInt32AsBinary helpers (int32 helpers kept for source compat). P2: Three unreachable returns after itkExceptionMacro removed. P2: WriteMeshInformation 'Unable to open file' said 'inputFilename=' while opening the OUTPUT stream. Corrected to 'outputFilename='. P2: Test reader->Update() now wrapped in ITK_TRY_EXPECT_NO_EXCEPTION to match writer->Update() and the rest of ITK's tests. P2 (greptile false positive): STLMeshIO::Read() was suggested for an override specifier. MeshIOBase has no virtual Read() to override, so 'virtual void Read();' is correct as-is. Reverted.
hjmjohnson
added a commit
to hjmjohnson/ITK
that referenced
this pull request
May 6, 2026
…est-iomeshstl ENH: Ingest ITKIOMeshSTL into Modules/IO
hjmjohnson
added a commit
to hjmjohnson/ITK
that referenced
this pull request
May 7, 2026
…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.
hjmjohnson
added a commit
to hjmjohnson/ITK
that referenced
this pull request
May 7, 2026
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.
hjmjohnson
added a commit
to hjmjohnson/ITK
that referenced
this pull request
May 7, 2026
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ingests
IOMeshSTLfrom the standalone remote module InsightSoftwareConsortium/ITKIOMeshSTL into ITK atModules/IO/IOMeshSTL/. Branch is based directly onupstream/mainand contains no v4-tooling files in its diff — independently mergeable.Local validation:
pre-commit run --all-filesclean;IOMeshSTLTestDriverbuilds; 10/10 IOMeshSTL tests pass locally (afterExternalDatafetches the four.cidcontent links from the IPFS gateway).What this provides
IOMeshSTLadds read/write support for the stereolithography (STL) mesh format in both ASCII and binary encodings — the canonical interchange format for 3D-printing, CAD, and surgical-planning workflows.The flagship classes are
itk::STLMeshIOand theSTLMeshIOFactoryplug-in registration that letsitk::MeshFileReader/itk::MeshFileWriterdiscover STL automatically.Path:
Modules/IO/IOMeshSTL/(preserving upstream module nameIOMeshSTL; renaming toMeshSTLwould break the public CMakefind_package(IOMeshSTL)API for downstream consumers).Pipeline metrics
README.rst → README.mdrewrites initk-module.cmakegit log -- Modules/IO/IOMeshSTLTooling provenance
This PR was produced via the v4 ingestion pipeline (PR #6204) but the v4 scripts are intentionally not included in this PR's diff — they were invoked from a separate worktree. This makes the PR mergeable independently of #6204.
Phase B (upstream archival) is deferred. After this PR merges:
main.Utilities/Maintenance/RemoteModuleIngest/archive-remote-module.sh IOMeshSTL --itk-pr-number <THIS-PR>to push the deletion +MIGRATION_README.md → README.mdpromotion to upstream and fliparchived=true.This PR makes no upstream changes; the upstream
ITKIOMeshSTLrepository remains live until the operator manually runs Phase B.Follow-up commits in this PR
After the merge commit (
ENH: Ingest ITKIOMeshSTL into Modules/IO), the standard cleanup commits land on top:STYLE:Apply gersemi 0.19.3 toModules/IO/IOMeshSTL/src/CMakeLists.txt. The v4 sanitize pass uses gersemi 0.24.0; ITK's pre-commit pins 0.19.3. The post-mergepre-commit run --all-filesgate caught one CMake file where the two versions disagree.DOC:AddModules/IO/IOMeshSTL/README.mdpointing at the archived upstream.COMP:RemoveModules/Remote/IOMeshSTL.remote.cmake(now in-tree).ENH:EnableModule_IOMeshSTL:BOOL=ONinpyproject.tomlconfigure-ci.Note: no manual
itk-module.cmakepatch was needed in this PR — the v4 sanitize pass auto-rewritesfile(READ "${...}/README.rst" DOCUMENTATION)to readREADME.mdinstead, across every historical commit.