Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
bc246a2
ENH: Add out-of-core (OOC) storage architecture for simplnx
joeykleingers Jun 1, 2026
52e6ef6
REFACTOR: Rename algorithm files for OOC dispatch preparation
joeykleingers Mar 31, 2026
a55ec2b
PERF: Out-of-core (OOC) optimized algorithms for SimplnxCore and Orie…
joeykleingers Apr 8, 2026
a0e4c4b
FIX: Resolve OOC store format in tests and fix ComputeAvgOrientations…
joeykleingers Apr 14, 2026
923bfe8
DOCS: Add comprehensive Doxygen and inline documentation for OOC-opti…
joeykleingers Apr 14, 2026
6c48a2d
COMP: Fix compile error in Windows
imikejackson Apr 17, 2026
ba68dfa
PERF: OOC-optimize WritePoleFigure per-element input reads and image …
joeykleingers Apr 20, 2026
cc2e7d4
TEST: Register exemplar archives for OOC-optimized filter tests
joeykleingers Apr 21, 2026
d6cbacd
PERF: Optimize CropImageGeometry with Z-slab batching for OOC
joeykleingers Apr 22, 2026
924fc47
PERF: Optimize RequireMinimumSizeFeatures memory and I/O patterns
joeykleingers Apr 22, 2026
42623a2
PERF: Optimize ExtractInternalSurfacesFromTriangleGeometry for OOC
joeykleingers Apr 22, 2026
e2c670b
PERF: Optimize ApplyTransformationToGeometry for out-of-core data
joeykleingers Apr 22, 2026
1eb10d1
PERF: Optimize ComputeTriangleAreas with chunked bulk vertex loads
joeykleingers Apr 22, 2026
e6bd327
PERF: Increase ComputeFeatureSizes chunk size for multi-billion-voxel…
joeykleingers Apr 22, 2026
ef357e8
DOC: Expand CropImageGeometry algorithm documentation
joeykleingers Apr 22, 2026
76f3dd1
DOC: Expand RequireMinimumSizeFeatures algorithm documentation
joeykleingers Apr 22, 2026
3c9988f
DOC: Add ExtractInternalSurfacesFromTriangleGeometry algorithm section
joeykleingers Apr 22, 2026
329cd23
DOC: Add ApplyTransformationToGeometry algorithm section
joeykleingers Apr 22, 2026
ac18714
DOC: Add ComputeTriangleAreas algorithm section
joeykleingers Apr 22, 2026
b4d7519
DOC: Expand ComputeFeatureSizes algorithm documentation
joeykleingers Apr 22, 2026
b569dd9
ENH: Apply PR #1590 to OOC dispatch variants and fix bool-mask bulk I/O
joeykleingers Apr 27, 2026
36f508b
ENH: Unify CreateDataStore and CreateListStore through format resolver
joeykleingers Apr 29, 2026
831d2ad
ENH: Register OOC format from DataIOCollection ctor; fix in-core Data…
joeykleingers May 29, 2026
4a79e61
PERF: Split ComputeFeatureSizes into in-core and out-of-core variants
joeykleingers Jun 5, 2026
ffafa15
COMP: Honor SIMPLNX_TEST_ALGORITHM_PATH=Both in in-core builds
joeykleingers Jun 5, 2026
5f397b3
BUG: Honor compression in the OOC streaming write path
joeykleingers Jun 5, 2026
214bfad
TEST: Assert recovery store type from preferences, not hardcoded in-core
joeykleingers Jun 5, 2026
d74c1c3
ENH: Machine-aware memory budget cap in MemoryBudgetManager
jmarquisbq Jun 5, 2026
e1c6976
REFACTOR: decouple out-of-core from core via runtime resolver + IO hooks
joeykleingers Jun 8, 2026
8ea1237
ENH: Memory-safety defensive programming (preflight -271 warning + ba…
jmarquisbq Jun 8, 2026
518466b
FIX: Add /bigobj to the simplnx MSVC build for Dream3dIO.cpp
jmarquisbq Jun 9, 2026
46dad94
REFACTOR: Name the built-in data-store-format display labels
jmarquisbq Jun 9, 2026
5ee6a6a
COMP: List two unlisted headers and group unit-test sources for the IDE
jmarquisbq Jun 9, 2026
0e423b9
COMP: add zlib as a direct simplnx vcpkg dependency
joeykleingers Jun 9, 2026
2a0adae
ENH: Record plugin unit-test targets on a global property
joeykleingers Jun 10, 2026
6753ada
PERF: Optimize ComputeFeaturePhases for out-of-core data
joeykleingers Jun 10, 2026
05011b7
Fix data archive hashes
jmarquisbq Jun 11, 2026
92a3a21
Revert "Fix data archive hashes"
joeykleingers Jun 11, 2026
5bb693e
REV: Integrate EbsdLib 3.0.0 V&V changes with OOC branch APIs post-re…
joeykleingers Jun 12, 2026
9dfa85f
BUG: Clamp default memory budget to the machine cap on low-RAM systems
joeykleingers Jun 12, 2026
150c244
PERF: Cache OOC feature/ensemble arrays in ComputeGBPDMetricBased
joeykleingers Jun 23, 2026
53f07d1
DOC: Drop OOC-implementation references from OOC-agnostic core comments
joeykleingers Jun 26, 2026
8dc467a
REV: Integrate develop V&V of ComputeAvgOrientations, ComputeFeatureN…
joeykleingers Jul 7, 2026
655be6a
PERF: Use scanline CCL as the sole segmentation algorithm
joeykleingers Jul 8, 2026
1d61fb9
REFACTOR: Rename CopyFeatureArrayToElementArray algorithm for OOC dis…
joeykleingers Jul 9, 2026
812b65f
PERF: Add out-of-core scanline path for CopyFeatureArrayToElementArray
joeykleingers Jul 9, 2026
2b51cfe
ENH: Let RemoveInactiveObjects skip the FeatureIds renumber when done…
joeykleingers Jul 9, 2026
218d985
PERF: Optimize RequireMinimumSizeFeatures out-of-core convergence and…
joeykleingers Jul 9, 2026
79327a0
PERF: OOC-optimize ComputeShapes feature-moment cell scan
joeykleingers Jul 9, 2026
127ea62
ENH: Add cancel checking to ConvertOrientations OOC workers; drop dea…
joeykleingers Jul 9, 2026
e740afb
PERF: OOC-optimize RequireMinNumNeighbors with fused feature-id renumber
joeykleingers Jul 9, 2026
9a1d53b
ENH: Optimize Compute Feature Shapes (Triangles) via per-feature face…
joeykleingers Jul 10, 2026
83cec8e
REFACTOR: Rename ComputeKMeans algorithm to ComputeKMeansDirect for O…
joeykleingers Jul 10, 2026
11898ae
REFACTOR: Remove old ComputeKMeans.{hpp,cpp} paths completing the Com…
joeykleingers Jul 10, 2026
4cf7e98
ENH: Optimize Compute Array Histogram (Feature) to single-pass binning
joeykleingers Jul 10, 2026
9830292
ENH: Optimize Resample Rectilinear Grid to Image Geom with buffered b…
joeykleingers Jul 10, 2026
836a4ad
PERF: OOC-optimize ComputeKMeans via DispatchAlgorithm<Direct, Scanline>
joeykleingers Jul 10, 2026
f2067e0
REFACTOR: Rename RemoveFlaggedFeatures algorithm to RemoveFlaggedFeat…
joeykleingers Jul 10, 2026
9bbcabd
PERF: Out-of-core (OOC) optimized RemoveFlaggedFeatures via Direct/Sc…
joeykleingers Jul 10, 2026
79bfc65
ENH: Optimize Compute Attribute Array Statistics to single-pass per-f…
joeykleingers Jul 10, 2026
63318f9
ENH: Optimize Resample Data (Image Geometry) with buffered bulk I/O
joeykleingers Jul 10, 2026
3411e7c
ENH: Optimize Extract Vertex Geometry with chunked bulk I/O
joeykleingers Jul 10, 2026
45aa338
ENH: Optimize Flying Edges 3D input reads with slice-buffered bulk I/O
joeykleingers Jul 10, 2026
40171c8
ENH: Reduce Attribute Array Calculator OOC per-voxel I/O with bulk ch…
joeykleingers Jul 10, 2026
93742c3
ENH: Optimize Sample Triangle Geometry on Uncertain Regular Grid for OOC
joeykleingers Jul 10, 2026
e16809b
ENH: Optimize Convert Orientations To Vertex Geometry with chunked st…
joeykleingers Jul 10, 2026
b5f46a2
ENH: Optimize Verify Triangle Winding seed search to a single pass
joeykleingers Jul 10, 2026
d895609
ENH: Optimize Write Abaqus Hexahedron with single-pass grain bucketing
joeykleingers Jul 10, 2026
f87722b
ENH: Optimize Write STL Files via per-group triangle buckets
joeykleingers Jul 10, 2026
1e7e021
ENH: Optimize Create AM Scan Paths via per-region/slice edge buckets
joeykleingers Jul 10, 2026
a116af5
ENH: Optimize Compute Vertex to Triangle Distances with pruned RTree …
joeykleingers Jul 10, 2026
0374bf0
PERF: Remove O(n_cells) mask buffer from Extract Vertex Geometry via …
joeykleingers Jul 10, 2026
f027837
PERF: Remove O(n_cells) neighbor buffer from RemoveFlaggedFeatures Sc…
joeykleingers Jul 10, 2026
1c65443
PERF: Streaming-RPN evaluation removes O(n_cells) buffers from Attrib…
joeykleingers Jul 10, 2026
283c5b6
PERF: Fuse OOC feature validation into counting pass
joeykleingers Jul 13, 2026
698e628
PERF: Add bounded OOC paths for data-intensive filters
joeykleingers Jul 13, 2026
ee6b370
BUG: Update DREAM3D preflight test for unified empty stores
joeykleingers Jul 13, 2026
b4e9965
PERF: Optimize six filters for in-core and OOC storage
joeykleingers Jul 13, 2026
86e5948
ENH: Add IDataStore::getPlannedStoreType() for placeholder-aware stor…
jmarquisbq Jul 14, 2026
9d33c5e
PERF: Optimize eight filters for in-core and OOC storage
joeykleingers Jul 14, 2026
469a78e
PERF: Stream OOC filter data in bounded chunks
joeykleingers Jul 14, 2026
9f5a240
PERF: Stream OOC I/O filters with bounded buffers
joeykleingers Jul 14, 2026
9df3e39
BUG: Fix preflight crash reading .dream3d files that contain a String…
jmarquisbq Jul 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
27 changes: 27 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ option(SIMPLNX_DOWNLOAD_TEST_FILES "Download the test files" ON)
# ------------------------------------------------------------------------------
option(SIMPLNX_WRITE_TEST_OUTPUT "Write unit test output files" OFF)

# ------------------------------------------------------------------------------
# Controls which algorithm paths are exercised by dual-dispatch unit tests.
# 0 (Both) - tests run with forceOoc=false AND forceOoc=true (default)
# 1 (OocOnly) - tests run with forceOoc=true only (use for OOC builds)
# 2 (InCoreOnly) - tests run with forceOoc=false only (quick validation)
# ------------------------------------------------------------------------------
set(SIMPLNX_TEST_ALGORITHM_PATH "0" CACHE STRING "Algorithm paths to test: 0=Both, 1=OocOnly, 2=InCoreOnly")

# ------------------------------------------------------------------------------
# Is the SimplnxCore Plugin enabled [DEFAULT=ON]
# ------------------------------------------------------------------------------
Expand Down Expand Up @@ -245,6 +253,9 @@ if(MSVC)
target_compile_options(simplnx
PRIVATE
/MP
# Dream3dIO.cpp exceeds the default COMDAT section limit (C1128) in Debug
# after the out-of-core resolver refactor; /bigobj raises the limit.
/bigobj
)
endif()

Expand All @@ -269,6 +280,7 @@ if(SIMPLNX_ENABLE_MULTICORE)
target_link_libraries(simplnx PUBLIC TBB::tbb)
endif()


target_link_libraries(simplnx
PUBLIC
fmt::fmt
Expand Down Expand Up @@ -301,6 +313,11 @@ if(SIMPLNX_ENABLE_LINK_FILESYSTEM)
endif()

set(SIMPLNX_GENERATED_DIR ${simplnx_BINARY_DIR}/generated)

configure_file(
${simplnx_SOURCE_DIR}/cmake/SimplnxConfig.hpp.in
${SIMPLNX_GENERATED_DIR}/simplnx/Common/SimplnxConfig.hpp
@ONLY)
set(SIMPLNX_GENERATED_HEADER_DIR ${simplnx_BINARY_DIR}/generated/simplnx)
set(SIMPLNX_EXPORT_HEADER ${SIMPLNX_GENERATED_HEADER_DIR}/simplnx_export.hpp)

Expand Down Expand Up @@ -359,6 +376,7 @@ set(SIMPLNX_HDRS
${SIMPLNX_SOURCE_DIR}/Common/Constants.hpp
${SIMPLNX_SOURCE_DIR}/Common/DataTypeUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Common/DataVector.hpp
${SIMPLNX_SOURCE_DIR}/Common/Extent.hpp
${SIMPLNX_SOURCE_DIR}/Common/EulerAngle.hpp
${SIMPLNX_SOURCE_DIR}/Common/Filesystem.hpp
${SIMPLNX_SOURCE_DIR}/Common/IteratorUtility.hpp
Expand Down Expand Up @@ -388,6 +406,8 @@ set(SIMPLNX_HDRS
${SIMPLNX_SOURCE_DIR}/DataStructure/IO/Generic/DataIOCollection.hpp
${SIMPLNX_SOURCE_DIR}/DataStructure/IO/Generic/IDataFactory.hpp
${SIMPLNX_SOURCE_DIR}/DataStructure/IO/Generic/IDataIOManager.hpp
${SIMPLNX_SOURCE_DIR}/DataStructure/IO/Generic/IDataStoreFormatResolver.hpp
${SIMPLNX_SOURCE_DIR}/DataStructure/IO/Generic/InMemoryFormatResolver.hpp
${SIMPLNX_SOURCE_DIR}/DataStructure/IO/Generic/IOConstants.hpp

${SIMPLNX_SOURCE_DIR}/DataStructure/IO/HDF5/DataIOManager.hpp
Expand Down Expand Up @@ -473,6 +493,7 @@ set(SIMPLNX_HDRS
${SIMPLNX_SOURCE_DIR}/DataStructure/DynamicListArray.hpp
${SIMPLNX_SOURCE_DIR}/DataStructure/EmptyDataStore.hpp
${SIMPLNX_SOURCE_DIR}/DataStructure/EmptyListStore.hpp
${SIMPLNX_SOURCE_DIR}/DataStructure/EmptyStringStore.hpp
${SIMPLNX_SOURCE_DIR}/DataStructure/IArray.hpp
${SIMPLNX_SOURCE_DIR}/DataStructure/IDataArray.hpp
${SIMPLNX_SOURCE_DIR}/DataStructure/IDataStore.hpp
Expand Down Expand Up @@ -548,12 +569,14 @@ set(SIMPLNX_HDRS
${SIMPLNX_SOURCE_DIR}/Plugin/PluginLoader.hpp

${SIMPLNX_SOURCE_DIR}/Utilities/ArrayCreationUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/SliceBufferedTransfer.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/AlignSections.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/ArrayThreshold.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/DataArrayUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/DataGroupUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/DataObjectUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/DataStoreUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/AlgorithmDispatch.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/FilePathGenerator.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/ColorTableUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/FileUtilities.hpp
Expand All @@ -564,6 +587,7 @@ set(SIMPLNX_HDRS
${SIMPLNX_SOURCE_DIR}/Utilities/HistogramUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/MaskCompareUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/MemoryUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/MemoryBudgetManager.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/MessageHelper.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/StringUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/StringInterpretationUtilities.hpp
Expand All @@ -576,6 +600,7 @@ set(SIMPLNX_HDRS
${SIMPLNX_SOURCE_DIR}/Utilities/SamplingUtils.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/SegmentFeatures.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/TimeUtilities.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/UnionFind.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/TooltipGenerator.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/TooltipRowItem.hpp
${SIMPLNX_SOURCE_DIR}/Utilities/OStreamUtilities.hpp
Expand Down Expand Up @@ -648,6 +673,7 @@ set(SIMPLNX_SRCS

${SIMPLNX_SOURCE_DIR}/DataStructure/IO/Generic/DataIOCollection.cpp
${SIMPLNX_SOURCE_DIR}/DataStructure/IO/Generic/IDataIOManager.cpp
${SIMPLNX_SOURCE_DIR}/DataStructure/IO/Generic/IDataStoreFormatResolver.cpp
${SIMPLNX_SOURCE_DIR}/DataStructure/IO/Generic/CoreDataIOManager.cpp

${SIMPLNX_SOURCE_DIR}/DataStructure/IO/HDF5/DataIOManager.cpp
Expand Down Expand Up @@ -779,6 +805,7 @@ set(SIMPLNX_SRCS
${SIMPLNX_SOURCE_DIR}/Utilities/DataStoreUtilities.cpp
${SIMPLNX_SOURCE_DIR}/Utilities/MaskCompareUtilities.cpp
${SIMPLNX_SOURCE_DIR}/Utilities/MemoryUtilities.cpp
${SIMPLNX_SOURCE_DIR}/Utilities/MemoryBudgetManager.cpp
${SIMPLNX_SOURCE_DIR}/Utilities/MessageHelper.cpp
${SIMPLNX_SOURCE_DIR}/Utilities/IParallelAlgorithm.cpp
${SIMPLNX_SOURCE_DIR}/Utilities/ParallelDataAlgorithm.cpp
Expand Down
6 changes: 6 additions & 0 deletions cmake/Plugin.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,11 @@ function(create_simplnx_plugin_unit_test)
${${ARGS_PLUGIN_NAME}UnitTest_SRCS}
)

# Record every plugin unit-test target on a global property so consumer builds
# (which include simplnx via add_subdirectory) can attach additional sources or
# settings to the test executables without simplnx knowing about the consumer.
set_property(GLOBAL APPEND PROPERTY SIMPLNX_UNIT_TEST_TARGETS ${UNIT_TEST_TARGET})

target_link_libraries(${UNIT_TEST_TARGET}
PRIVATE
simplnx
Expand Down Expand Up @@ -389,6 +394,7 @@ function(create_simplnx_plugin_unit_test)
target_compile_definitions(${UNIT_TEST_TARGET}
PRIVATE
SIMPLNX_BUILD_DIR="$<TARGET_FILE_DIR:simplnx_test>"
SIMPLNX_TEST_ALGORITHM_PATH=${SIMPLNX_TEST_ALGORITHM_PATH}
)

target_compile_options(${UNIT_TEST_TARGET}
Expand Down
12 changes: 12 additions & 0 deletions cmake/SimplnxConfig.hpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

// This header is generated from cmake/SimplnxConfig.hpp.in by configure_file().
// It carries compile-time configuration into every translation unit that links
// simplnx, including MOC, via simplnx's PUBLIC generated include directory.
// Delivering values through a header (not per-target compile definitions) keeps
// them identical across all consumers, which is required for ODR safety when a
// macro gates inline code in public headers.
//
// Out-of-core support is no longer a compile-time switch in core simplnx; OOC is
// provided at runtime by a registered IO manager (see DataIOCollection). This
// header is retained for future compile-time configuration values.
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ Result<OutputActions> DataCheck(const DataStructure& dataStructure, const DataPa
const auto& inputArray = dataStructure.getDataRefAs<IDataArray>(inputArrayPath);
const auto& inputDataStore = inputArray.getIDataStoreRef();

if(!inputArray.getDataFormat().empty())
if(inputArray.getStoreType() == IDataStore::StoreType::OutOfCore)
{
return MakeErrorResult<OutputActions>(Constants::k_OutOfCoreDataNotSupported,
fmt::format("Input Array '{}' utilizes out-of-core data. This is not supported within ITK filters.", inputArrayPath.toString()));
Expand All @@ -862,7 +862,7 @@ Result<detail::ITKFilterFunctorResult_t<FilterCreationFunctorT>> Execute(DataStr

using ResultT = detail::ITKFilterFunctorResult_t<FilterCreationFunctorT>;

if(!inputArray.getDataFormat().empty())
if(inputArray.getStoreType() == IDataStore::StoreType::OutOfCore)
{
return MakeErrorResult(Constants::k_OutOfCoreDataNotSupported, fmt::format("Input Array '{}' utilizes out-of-core data. This is not supported within ITK filters.", inputArrayPath.toString()));
}
Expand Down
44 changes: 2 additions & 42 deletions src/Plugins/ITKImageProcessing/test/ITKTestBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ std::string ComputeMD5HashTyped(const IDataArray& outputDataArray)
usize arraySize = dataArray.getSize();

MD5 md5;
if(outputDataArray.getDataFormat().empty())
if(outputDataArray.getIDataStoreRef().getStoreType() != IDataStore::StoreType::OutOfCore)
{
const T* dataPtr = dataArray.template getIDataStoreRefAs<DataStore<T>>().data();
md5.update(reinterpret_cast<const uint8*>(dataPtr), arraySize * sizeof(T));
Expand Down Expand Up @@ -135,47 +135,7 @@ namespace ITKTestBase
bool IsArrayInMemory(DataStructure& dataStructure, const DataPath& outputDataPath)
{
const auto& outputDataArray = dataStructure.getDataRefAs<IDataArray>(outputDataPath);
DataType outputDataType = outputDataArray.getDataType();

switch(outputDataType)
{
case DataType::float32: {
return dynamic_cast<const DataArray<float32>&>(outputDataArray).getDataFormat().empty();
}
case DataType::float64: {
return dynamic_cast<const DataArray<float64>&>(outputDataArray).getDataFormat().empty();
}
case DataType::int8: {
return dynamic_cast<const DataArray<int8>&>(outputDataArray).getDataFormat().empty();
}
case DataType::uint8: {
return dynamic_cast<const DataArray<uint8>&>(outputDataArray).getDataFormat().empty();
}
case DataType::int16: {
return dynamic_cast<const DataArray<int16>&>(outputDataArray).getDataFormat().empty();
}
case DataType::uint16: {
return dynamic_cast<const DataArray<uint16>&>(outputDataArray).getDataFormat().empty();
}
case DataType::int32: {
return dynamic_cast<const DataArray<int32>&>(outputDataArray).getDataFormat().empty();
}
case DataType::uint32: {
return dynamic_cast<const DataArray<uint32>&>(outputDataArray).getDataFormat().empty();
}
case DataType::int64: {
return dynamic_cast<const DataArray<int64>&>(outputDataArray).getDataFormat().empty();
}
case DataType::uint64: {
return dynamic_cast<const DataArray<uint64>&>(outputDataArray).getDataFormat().empty();
}
case DataType::boolean: {
[[fallthrough]];
}
default: {
return {};
}
}
return outputDataArray.getIDataStoreRef().getStoreType() != IDataStore::StoreType::OutOfCore;
}
//------------------------------------------------------------------------------
std::string ComputeMd5Hash(DataStructure& dataStructure, const DataPath& outputDataPath)
Expand Down
12 changes: 9 additions & 3 deletions src/Plugins/OrientationAnalysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ else()
endif()



# ------------------------------------------------------------------------------
# EbsdLib needs install rules for creating packages
# ------------------------------------------------------------------------------
Expand Down Expand Up @@ -173,6 +174,8 @@ set(filter_algorithms
AlignSectionsMisorientation
AlignSectionsMutualInformation
BadDataNeighborOrientationCheck
BadDataNeighborOrientationCheckScanline
BadDataNeighborOrientationCheckWorklist
CAxisSegmentFeatures
ComputeAvgCAxes
ComputeAvgOrientations
Expand All @@ -187,12 +190,17 @@ set(filter_algorithms
ComputeFZQuaternions
ComputeGBCD
ComputeGBCDMetricBased
ComputeGBCDPoleFigure
ComputeGBCDPoleFigureDirect
ComputeGBCDPoleFigureScanline
ComputeGBPDMetricBased
ComputeIPFColors
ComputeIPFColorsDirect
ComputeIPFColorsScanline
ComputeKernelAvgMisorientations
ComputeMisorientations
ComputeQuaternionConjugate
ComputeQuaternionConjugateDirect
ComputeQuaternionConjugateScanline
ComputeSchmids
ComputeShapes
ComputeShapesTriangleGeom
Expand Down Expand Up @@ -455,5 +463,3 @@ if(${PLUGIN_NAME}_INSTALL_DATA_FILES)
COMPONENT Applications
)
endif()


Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ In this new structure, what follows is what the created structures represent:
In previous versions a file would have been produced instead. If you wish to recreate this, you can write the Attribute Matrix as a CSV/Text file.


## Algorithm

### In-Core Path

For each pair of adjacent Z-sections, the algorithm computes the misorientation between voxels across the section boundary. It tests candidate X-Y shifts to find the shift that minimizes the total misorientation between the two sections. All voxel comparisons use direct array indexing with `operator[]`.

### Out-of-Core Path

Reads pairs of adjacent Z-slices into local memory buffers using `copyIntoBuffer()`. All misorientation comparisons for a given slice pair operate entirely on the in-memory buffers. This converts what would otherwise be random cross-slice element access into sequential bulk reads, avoiding chunk thrashing when data is stored on disk in compressed chunks.

### Performance

The OOC optimization matters most for large datasets that exceed available RAM. By reading entire Z-slices in bulk rather than accessing individual voxels across slice boundaries, the algorithm avoids repeatedly decompressing the same disk chunks. For in-memory datasets, the two paths produce identical results with negligible overhead difference.

% Auto generated parameter table will be inserted here

## Example Pipelines
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ In this new structure, what follows is what the created structures represent:

In previous versions a file would have been produced instead. If you wish to recreate this, you can write the Attribute Matrix as a CSV/Text file.

## Algorithm

### In-Core Path

Aligns Z-sections by maximizing the mutual information of orientation data between adjacent slices. The algorithm segments each slice into temporary features, bins the orientations, and computes joint and marginal histograms to evaluate mutual information at each candidate shift position. All orientation and feature ID data is accessed through direct array indexing with `operator[]`.

### Out-of-Core Path

Reads the orientation and phase data for each pair of adjacent Z-slices into local memory buffers using `copyIntoBuffer()` before computing histograms. This eliminates per-voxel out-of-core reads during the histogram binning and mutual information calculation, replacing them with two sequential bulk reads per slice pair.

### Performance

The OOC optimization matters most for large datasets that exceed available RAM. Histogram computation requires visiting every voxel in both slices multiple times (once per candidate shift), so eliminating per-element OOC access prevents repeated decompression of the same disk chunks. For in-memory datasets, the two paths produce identical results with negligible overhead difference.

% Auto generated parameter table will be inserted here

## References
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,32 @@ The filter allocates a temporary `int32` neighbor-count array sized to the total
(4 bytes per voxel). For a 1-billion-voxel dataset, that is approximately 4 GB of additional
working memory during execution. This memory is released when the filter finishes.

### Implementation Notes

The filter selects between two implementations at runtime based on how the input arrays are stored.

#### In-Core Path (BadDataNeighborOrientationCheckWorklist)

When all arrays reside in contiguous in-memory storage, the algorithm uses a two-phase worklist approach:

1. **Phase 1 (Initial count)**: A single linear scan counts matching good face-neighbors for every bad voxel, storing the count in a per-voxel array (the neighbor-count array described under *Memory Considerations*).
2. **Phase 2 (Worklist propagation)**: For each level, a deque is seeded with all bad voxels meeting the threshold. As each voxel is flipped, its still-bad neighbors' counts are incremented. If a neighbor's count now meets the threshold, it is enqueued. This breadth-first flood-fill processes each voxel at most once per level, achieving O(flipped) amortized cost.

#### Out-of-Core Path (BadDataNeighborOrientationCheckScanline)

When any of the quaternion, mask, or phase arrays are backed by chunked (OOC) disk storage, the algorithm uses a 3-slice rolling window over the Z axis:

1. Three Z-slices of quaternions, phases, and mask data are maintained in memory (previous, current, next).
2. For each bad voxel in the current slice, the count of matching good face-neighbors is recomputed on-the-fly using the rolling window buffers.
3. If a voxel is flipped, the mask change is written back to the OOC store per-slice via `copyFromBuffer()`.
4. The window shifts forward one Z-slice at a time, with only one new slice loaded per step.

This approach trades recomputation (no persistent neighbor-count array) for strictly sequential I/O that avoids the random-access chunk thrashing that would occur with the worklist variant's BFS pattern.

#### Performance

The in-core worklist variant is significantly faster for datasets that fit in RAM because each voxel is processed at most once per level (O(flipped) cost vs. O(N * passes) for the scanline variant). The OOC scanline variant is slower in absolute terms but avoids catastrophic performance degradation on disk-backed datasets where the worklist's random access pattern would trigger continuous chunk load/evict cycles. Memory usage is O(N) for the worklist variant vs. O(3 * sliceSize) for the scanline variant.

## Example Data

| Example Input Image | Example Output Image |
Expand Down
16 changes: 16 additions & 0 deletions src/Plugins/OrientationAnalysis/docs/CAxisSegmentFeaturesFilter.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,22 @@ is to still use the 6 face neighbors ("Face Only") in order to stay consistent w
|:--:|:--:|
| ![Shared Edges & Points With Disconnected Region - "Face Only"](Images/SegmentFeatures/combination_face_only.png) | ![Shared Edges & Points With Disconnected Region - "All Connected"](Images/SegmentFeatures/combination_all_connected.png) |

## Algorithm

This filter segments voxels into features based on c-axis alignment, targeting hexagonal crystal systems. Voxels whose c-axes (the <001> crystallographic direction) are aligned within a user-defined tolerance are grouped into the same feature.

### In-Core Path

Uses a BFS-style flood fill where seed voxels are compared to their neighbors by computing the c-axis misalignment via direct array access with `operator[]`. Neighbors within tolerance are added to the current feature and queued for further expansion.

### Out-of-Core Path

Adapted to use sequential data access through the `SegmentFeatures` base class OOC support. The base class manages bulk I/O so that the flood-fill algorithm can proceed without triggering per-voxel OOC reads across chunk boundaries.

### Performance

The OOC optimization matters most for large datasets that exceed available RAM. Flood-fill naturally exhibits random access patterns as it grows regions across Z-slices, which can cause severe chunk thrashing with compressed on-disk storage. The OOC path mitigates this by leveraging the base class sequential access strategy. For in-memory datasets, the two paths produce identical results with negligible overhead difference.

% Auto generated parameter table will be inserted here

## Example Pipelines
Expand Down
Loading