Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#include "ErodeDilateBadData.hpp"

#include "simplnx/DataStructure/DataArray.hpp"

Check failure on line 3 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ErodeDilateBadData.cpp

View workflow job for this annotation

GitHub Actions / clang_format_pr

code should be clang-formatted [-Wclang-format-violations]
#include "simplnx/DataStructure/DataGroup.hpp"
#include "simplnx/DataStructure/Geometry/ImageGeom.hpp"
#include "simplnx/Utilities/DataGroupUtilities.hpp"
#include "simplnx/Utilities/MessageHelper.hpp"
#include "simplnx/Utilities/NeighborUtilities.hpp"
#include "simplnx/Utilities/ParallelTaskAlgorithm.hpp"
#include "simplnx/Utilities/DataStoreUtilities.hpp"

using namespace nx::core;
namespace
Expand All @@ -18,7 +19,7 @@
ErodeDilateBadDataTransferDataImpl(const ErodeDilateBadDataTransferDataImpl&) = default;

ErodeDilateBadDataTransferDataImpl(ErodeDilateBadData* filterAlg, usize totalPoints, ChoicesParameter::ValueType operation, const Int32AbstractDataStore& featureIds,
const std::vector<int64>& neighbors, const std::shared_ptr<IDataArray>& dataArrayPtr, MessageHelper& messageHelper)
const Int64AbstractDataStore& neighbors, const std::shared_ptr<IDataArray>& dataArrayPtr, MessageHelper& messageHelper)
: m_FilterAlg(filterAlg)
, m_TotalPoints(totalPoints)
, m_Operation(operation)
Expand Down Expand Up @@ -58,7 +59,7 @@
ErodeDilateBadData* m_FilterAlg = nullptr;
usize m_TotalPoints = 0;
ChoicesParameter::ValueType m_Operation = 0;
std::vector<int64> m_Neighbors;
const Int64AbstractDataStore& m_Neighbors;
const std::shared_ptr<IDataArray> m_DataArrayPtr;
const Int32AbstractDataStore& m_FeatureIds;
MessageHelper& m_MessageHelper;
Expand All @@ -83,13 +84,146 @@
return m_ShouldCancel;
}

// -----------------------------------------------------------------------------
bool shouldSkipData(const ErodeDilateBadDataInputValues* inputValues, int32 neighPointIdx, const std::array<int64, 3>& dims, int64 xIndex, int64 yIndex, int64 zIndex)
{
if(neighPointIdx == 0 && (zIndex == 0 || !inputValues->ZDirOn))
{
return true;
}
if(neighPointIdx == 5 && (zIndex == (dims[2] - 1) || !inputValues->ZDirOn))
{
return true;
}
if(neighPointIdx == 1 && (yIndex == 0 || !inputValues->YDirOn))
{
return true;
}
if(neighPointIdx == 4 && (yIndex == (dims[1] - 1) || !inputValues->YDirOn))
{
return true;
}
if(neighPointIdx == 2 && (xIndex == 0 || !inputValues->XDirOn))
{
return true;
}
if(neighPointIdx == 3 && (xIndex == (dims[0] - 1) || !inputValues->XDirOn))
{
return true;
}

return false;
}

/**
* @brief Parses over the neighbor indices and sets the feature counts to 0 for existing points.
* @param featureIds Feature ID data store for determining neighboring feature IDs.
* @param featureCount Running total of the number of features it neighbors.
* @param neighpoints Pre-created array for determining neighbor indices.
* @param dims Geometry dimentions for determining boundaries.
* @param voxelIndex Array index of the 3D geometry position.
* @param xIndex X index in the geometry position used for determing neighbor validity.
* @param yIndex Y index in the geometry position used for determing neighbor validity.
* @param zIndex Z index in the geometry position used for determing neighbor validity.
*/
void ErodeBadDataPostOp(const Int32AbstractDataStore& featureIds, std::vector<int32>& featureCount, const std::array<int64, 6>& neighpoints, const std::array<int64, 3>& dims, const int64 voxelIndex,
int64 xIndex, int64 yIndex, int64 zIndex)
{
for(int32 neighPointIdx = 0; neighPointIdx < 6; neighPointIdx++)
{
const int64 neighborPoint = voxelIndex + neighpoints[neighPointIdx];
if(neighPointIdx == 0 && zIndex == 0)
{
continue;
}
if(neighPointIdx == 5 && zIndex == (dims[2] - 1))
{
continue;
}
if(neighPointIdx == 1 && yIndex == 0)
{
continue;
}
if(neighPointIdx == 4 && yIndex == (dims[1] - 1))
{
continue;
}
if(neighPointIdx == 2 && xIndex == 0)
{
continue;
}
if(neighPointIdx == 3 && xIndex == (dims[0] - 1))
{
continue;
}

const int32 feature = featureIds[neighborPoint];
featureCount[feature] = 0;
}
}

/**
* @brief
* @param inputValues Algorithm input values
* @param featureIds Feature ID data store.
* @param featureCount Running total of the number of features it neighbors.
* @param neighbors
* @param neighpoints Pre-created array for determining neighbor indices.
* @param dims Geometry dimentions for determining boundaries.
* @param voxelIndex Array index of the 3D geometry position.
* @param xIndex X index in the geometry position used for determing neighbor validity.
* @param yIndex Y index in the geometry position used for determing neighbor validity.
* @param zIndes Z index in the geometry position used for determing neighbor validity.
*/
void erodeDilateBadDataVoxel(const ErodeDilateBadDataInputValues* inputValues, const Int32AbstractDataStore& featureIds, std::vector<int32>& featureCount, Int64AbstractDataStore& neighbors,
const std::array<int64, 6>& neighpoints, const std::array<int64, 3>& dims, int64 voxelIndex, int64 xIndex, int64 yIndex, int64 zIndex)
{
const int32 featureName = featureIds[voxelIndex];
if(featureName == 0)
{
int32 most = 0;
for(int32 neighPointIdx = 0; neighPointIdx < 6; neighPointIdx++)
{
const int64 neighborPoint = voxelIndex + neighpoints[neighPointIdx];
if(shouldSkipData(inputValues, neighPointIdx, dims, xIndex, yIndex, zIndex))
{
continue;
}

const int32 feature = featureIds[neighborPoint];
if(inputValues->Operation == detail::k_DilateIndex && feature > 0)
{
neighbors[neighborPoint] = voxelIndex;
}
if(feature > 0 && inputValues->Operation == detail::k_ErodeIndex)
{
featureCount[feature]++;
const int32 current = featureCount[feature];
if(current > most)
{
most = current;
neighbors[voxelIndex] = neighborPoint;
}
}
}
// Erode operation
if(inputValues->Operation == detail::k_ErodeIndex)
{
ErodeBadDataPostOp(featureIds, featureCount, neighpoints, dims, voxelIndex, xIndex, yIndex, zIndex);
}
}
}

// -----------------------------------------------------------------------------
Result<> ErodeDilateBadData::operator()()
{
const auto& featureIds = m_DataStructure.getDataAs<Int32Array>(m_InputValues->FeatureIdsArrayPath)->getDataStoreRef();
const usize totalPoints = featureIds.getNumberOfTuples();

std::vector<int64> neighbors(totalPoints, -1);
// Update for OOC data sizes
std::shared_ptr<Int64AbstractDataStore> neighborsPtr = DataStoreUtilities::CreateDataStore<int64>({totalPoints}, {1});

Check failure on line 224 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ErodeDilateBadData.cpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, clang++-14)

no matching function for call to 'CreateDataStore'

Check failure on line 224 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ErodeDilateBadData.cpp

View workflow job for this annotation

GitHub Actions / build (windows-2022, v143)

'nx::core::DataStoreUtilities::CreateDataStore': no matching overloaded function found [D:\a\simplnx\simplnx\build\Plugins\SimplnxCore\SimplnxCore.vcxproj]

Check failure on line 224 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ErodeDilateBadData.cpp

View workflow job for this annotation

GitHub Actions / build (ubuntu-22.04, g++-11)

too few arguments to function ‘std::shared_ptr<nx::core::AbstractDataStore<T> > nx::core::DataStoreUtilities::CreateDataStore(const ShapeType&, const ShapeType&, nx::core::IDataAction::Mode, std::string) [with T = long int; nx::core::ShapeType = std::vector<long unsigned int>; std::string = std::__cxx11::basic_string<char>]’

Check failure on line 224 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ErodeDilateBadData.cpp

View workflow job for this annotation

GitHub Actions / build (macos-14)

no matching function for call to 'CreateDataStore'

Check failure on line 224 in src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ErodeDilateBadData.cpp

View workflow job for this annotation

GitHub Actions / build (macos-15)

no matching function for call to 'CreateDataStore'
auto& neighbors = *neighborsPtr.get();
neighbors.fill(-1);

const auto& selectedImageGeom = m_DataStructure.getDataRefAs<ImageGeom>(m_InputValues->InputImageGeometry);

Expand All @@ -101,79 +235,26 @@
static_cast<int64>(udims[2]),
};

usize numFeatures = 0;
for(usize i = 0; i < totalPoints; i++)
{
const int32 featureName = featureIds[i];
if(featureName > numFeatures)
{
numFeatures = featureName;
}
}
usize numFeatures = std::max(0, *(std::max_element(featureIds.begin(), featureIds.end())));

std::array<int64, 6> neighborVoxelIndexOffsets = initializeFaceNeighborOffsets(dims);
std::array<FaceNeighborType, 6> faceNeighborInternalIdx = initializeFaceNeighborInternalIdx();

std::vector<int32> featureCount(numFeatures + 1, 0);

// Iterate over the geometry to handle every voxel
for(int32 iteration = 0; iteration < m_InputValues->NumIterations; iteration++)
{
for(int64 zIdx = 0; zIdx < dims[2]; zIdx++)
for(int64 zIndex = 0; zIndex < dims[2]; zIndex++)
{
const int64 zStride = dims[0] * dims[1] * zIdx;
for(int64 yIdx = 0; yIdx < dims[1]; yIdx++)
const int64 zStride = dims[0] * dims[1] * zIndex;
for(int64 yIndex = 0; yIndex < dims[1]; yIndex++)
{
const int64 yStride = dims[0] * yIdx;
for(int64 xIdx = 0; xIdx < dims[0]; xIdx++)
const int64 yStride = dims[0] * yIndex;
for(int64 xIndex = 0; xIndex < dims[0]; xIndex++)
{
const int64 voxelIndex = zStride + yStride + xIdx;
const int32 featureName = featureIds[voxelIndex];
if(featureName == 0)
{
int32 most = 0;
// Loop over the 6 face neighbors of the voxel
std::array<bool, 6> isValidFaceNeighbor = computeValidFaceNeighbors(xIdx, yIdx, zIdx, dims);
for(const auto& faceIndex : faceNeighborInternalIdx)
{
if(!isValidFaceNeighbor[faceIndex])
{
continue;
}
const int64 neighborPoint = voxelIndex + neighborVoxelIndexOffsets[faceIndex];

const int32 feature = featureIds[neighborPoint];
if(m_InputValues->Operation == detail::k_DilateIndex && feature > 0)
{
neighbors[neighborPoint] = voxelIndex;
}
if(feature > 0 && m_InputValues->Operation == detail::k_ErodeIndex)
{
featureCount[feature]++;
const int32 current = featureCount[feature];
if(current > most)
{
most = current;
neighbors[voxelIndex] = neighborPoint;
}
}
}
if(m_InputValues->Operation == detail::k_ErodeIndex)
{
// Loop over the 6 face neighbors of the voxel
isValidFaceNeighbor = computeValidFaceNeighbors(xIdx, yIdx, zIdx, dims);
for(const auto& faceIndex : faceNeighborInternalIdx)
{
if(!isValidFaceNeighbor[faceIndex])
{
continue;
}
const int64 neighborPoint = voxelIndex + neighborVoxelIndexOffsets[faceIndex];

const int32 feature = featureIds[neighborPoint];
featureCount[feature] = 0;
}
}
}
const int64 voxelIndex = zStride + yStride + xIndex;
erodeDilateBadDataVoxel(m_InputValues, featureIds, featureCount, neighbors, neighborVoxelIndexOffsets, dims, voxelIndex, xIndex, yIndex, zIndex);
}
}
}
Expand Down
Loading