Skip to content

Commit

Permalink
BUG: Fixes issue where any component shape was allowed for ComputeTri…
Browse files Browse the repository at this point in the history
…angleGeometrySizes (#1134)

* BUG: Fixes issue where any component shape were allowed for ComputeTriangleGeometrySizes.cpp
* Fix all instances of "Face Labels" are only allowed to use 2 component input arrays
* ComputeTriangleGeomVolumes - fix possible walking off the end of the array.
	A negative value for the face label when used as an index will cast into an unsigned value and bad things are going to happen.
* BUG: Fixes negative volumes produced from calculations

---------

Signed-off-by: Michael Jackson <[email protected]>
  • Loading branch information
imikejackson committed Nov 28, 2024
1 parent b358403 commit f36ca6c
Show file tree
Hide file tree
Showing 16 changed files with 123 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Parameters ComputeTriangleGeomShapesFilter::parameters() const
GeometrySelectionParameter::AllowedTypes{IGeometry::Type::Triangle}));
params.insertSeparator(Parameters::Separator{"Input Triangle Face Data"});
params.insert(std::make_unique<ArraySelectionParameter>(k_FaceLabelsArrayPath_Key, "Face Labels", "The DataPath to the FaceLabels values.", DataPath{},
ArraySelectionParameter::AllowedTypes{nx::core::DataType::int32}));
ArraySelectionParameter::AllowedTypes{nx::core::DataType::int32}, ArraySelectionParameter::AllowedComponentShapes{{2}}));

params.insertSeparator(Parameters::Separator{"Input Face Feature Data"});
params.insert(std::make_unique<DataGroupSelectionParameter>(k_FeatureAttributeMatrixPath_Key, "Face Feature Attribute Matrix",
Expand Down
4 changes: 2 additions & 2 deletions src/Plugins/SimplnxCore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ set(FilterList
ComputeBiasedFeaturesFilter
ComputeBoundaryCellsFilter
ComputeBoundaryElementFractionsFilter
ComputeTriangleGeomSizesFilter
ComputeTriangleGeomVolumesFilter
FlyingEdges3DFilter
CreateColorMapFilter
IdentifySampleFilter
Expand Down Expand Up @@ -188,7 +188,7 @@ set(AlgorithmList
ComputeBiasedFeatures
ComputeBoundaryCells
FindNRingNeighbors
ComputeTriangleGeomSizes
ComputeTriangleGeomVolumes
FlyingEdges3D
CreateColorMap
InitializeData
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ Labels_ array. The volume of any generic polyhedron can be computed using the fo
4. Compute the signed volume of each tetrahedron
5. Sum the signed tetrahedra volumes to obtain the volume of the enclosing polyhedron

This computation is _not_ the same as the Find Feature Sizes for **Triangle Geometries**, which computes the sum of the
unit element sizes for a set of **Features** (thus, the Find Feature Sizes would compute the _area_
of **Features** in a **Triangle Geometry**, whereas this **Filter** is specialized to compute the enclosed volumes of **
Features** in a surface mesh).

% Auto generated parameter table will be inserted here

## Example Pipelines
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "ComputeTriangleGeomSizes.hpp"
#include "ComputeTriangleGeomVolumes.hpp"

#include "simplnx/DataStructure/DataArray.hpp"
#include "simplnx/DataStructure/DataGroup.hpp"
Expand Down Expand Up @@ -38,8 +38,8 @@ T FindTetrahedronVolume(const std::array<usize, 3>& vertIds, const AbstractDataS
} // namespace

// -----------------------------------------------------------------------------
ComputeTriangleGeomSizes::ComputeTriangleGeomSizes(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel,
ComputeTriangleGeomSizesInputValues* inputValues)
ComputeTriangleGeomVolumes::ComputeTriangleGeomVolumes(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel,
ComputeTriangleGeomVolumesInputValues* inputValues)
: m_DataStructure(dataStructure)
, m_InputValues(inputValues)
, m_ShouldCancel(shouldCancel)
Expand All @@ -48,16 +48,16 @@ ComputeTriangleGeomSizes::ComputeTriangleGeomSizes(DataStructure& dataStructure,
}

// -----------------------------------------------------------------------------
ComputeTriangleGeomSizes::~ComputeTriangleGeomSizes() noexcept = default;
ComputeTriangleGeomVolumes::~ComputeTriangleGeomVolumes() noexcept = default;

// -----------------------------------------------------------------------------
const std::atomic_bool& ComputeTriangleGeomSizes::getCancel()
const std::atomic_bool& ComputeTriangleGeomVolumes::getCancel()
{
return m_ShouldCancel;
}

// -----------------------------------------------------------------------------
Result<> ComputeTriangleGeomSizes::operator()()
Result<> ComputeTriangleGeomVolumes::operator()()
{
using MeshIndexType = IGeometry::MeshIndexType;
using SharedVertexListType = AbstractDataStore<IGeometry::SharedVertexList::value_type>;
Expand Down Expand Up @@ -85,28 +85,35 @@ Result<> ComputeTriangleGeomSizes::operator()()
auto& featAttrMat = m_DataStructure.getDataRefAs<AttributeMatrix>(m_InputValues->FeatureAttributeMatrixPath);
featAttrMat.resizeTuples(tDims);
auto& volumes = m_DataStructure.getDataAs<Float32Array>(m_InputValues->VolumesArrayPath)->getDataStoreRef();
volumes.fill(0.0f); // Initialize all volumes to ZERO

std::array<usize, 3> faceVertexIndices = {0, 0, 0};

for(MeshIndexType i = 0; i < numTriangles; i++)
{
triangleGeom.getFacePointIds(i, faceVertexIndices);
if(faceLabels[2 * i + 0] == -1)
int32 faceLabel0 = faceLabels[2 * i + 0];
int32 faceLabel1 = faceLabels[2 * i + 1];

if(faceLabel0 < 0 && faceLabel1 >= 0)
{
std::swap(faceVertexIndices[2], faceVertexIndices[1]);
volumes[faceLabels[2 * i + 1]] += FindTetrahedronVolume(faceVertexIndices, vertexCoords);
volumes[faceLabel1] += FindTetrahedronVolume(faceVertexIndices, vertexCoords);
}
else if(faceLabels[2 * i + 1] == -1)
else if(faceLabel1 < 0 && faceLabel0 >= 0)
{
volumes[faceLabels[2 * i + 0]] += FindTetrahedronVolume(faceVertexIndices, vertexCoords);
volumes[faceLabel0] += FindTetrahedronVolume(faceVertexIndices, vertexCoords);
}
else
{
volumes[faceLabels[2 * i + 0]] += FindTetrahedronVolume(faceVertexIndices, vertexCoords);
volumes[faceLabel0] += FindTetrahedronVolume(faceVertexIndices, vertexCoords);
std::swap(faceVertexIndices[2], faceVertexIndices[1]);
volumes[faceLabels[2 * i + 1]] += FindTetrahedronVolume(faceVertexIndices, vertexCoords);
volumes[faceLabel1] += FindTetrahedronVolume(faceVertexIndices, vertexCoords);
}
}

for(size_t i = 0; i < tDims[0]; i++)
{
volumes[i] = std::abs(volumes[i]);
}
return {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include "SimplnxCore/SimplnxCore_export.hpp"

#include "simplnx/DataStructure/DataPath.hpp"
#include "simplnx/DataStructure/DataStructure.hpp"
#include "simplnx/Filter/IFilter.hpp"

namespace nx::core
{

struct SIMPLNXCORE_EXPORT ComputeTriangleGeomVolumesInputValues
{
DataPath TriangleGeometryPath;
DataPath FaceLabelsArrayPath;
DataPath FeatureAttributeMatrixPath;
DataPath VolumesArrayPath;
};

/**
* @class
*/
class SIMPLNXCORE_EXPORT ComputeTriangleGeomVolumes
{
public:
ComputeTriangleGeomVolumes(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, ComputeTriangleGeomVolumesInputValues* inputValues);
~ComputeTriangleGeomVolumes() noexcept;

ComputeTriangleGeomVolumes(const ComputeTriangleGeomVolumes&) = delete;
ComputeTriangleGeomVolumes(ComputeTriangleGeomVolumes&&) noexcept = delete;
ComputeTriangleGeomVolumes& operator=(const ComputeTriangleGeomVolumes&) = delete;
ComputeTriangleGeomVolumes& operator=(ComputeTriangleGeomVolumes&&) noexcept = delete;

Result<> operator()();

const std::atomic_bool& getCancel();

private:
DataStructure& m_DataStructure;
const ComputeTriangleGeomVolumesInputValues* m_InputValues = nullptr;
const std::atomic_bool& m_ShouldCancel;
const IFilter::MessageHandler& m_MessageHandler;
};

} // namespace nx::core
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Parameters ComputeTriangleGeomCentroidsFilter::parameters() const
GeometrySelectionParameter::AllowedTypes{IGeometry::Type::Triangle}));
params.insertSeparator(Parameters::Separator{"Input Triangle Face Data"});
params.insert(std::make_unique<ArraySelectionParameter>(k_FaceLabelsArrayPath_Key, "Face Labels", "The DataPath to the FaceLabels values.", DataPath{},
ArraySelectionParameter::AllowedTypes{nx::core::DataType::int32}));
ArraySelectionParameter::AllowedTypes{nx::core::DataType::int32}, ArraySelectionParameter::AllowedComponentShapes{{2}}));
params.insertSeparator(Parameters::Separator{"Input Face Feature Data"});
params.insert(std::make_unique<DataGroupSelectionParameter>(k_FeatureAttributeMatrixPath_Key, "Face Feature Attribute Matrix",
"The DataPath to the AttributeMatrix that holds feature data for the faces", DataPath({"TriangleDataContainer", "Face Feature Data"}),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "ComputeTriangleGeomSizesFilter.hpp"
#include "ComputeTriangleGeomVolumesFilter.hpp"

#include "SimplnxCore/Filters/Algorithms/ComputeTriangleGeomSizes.hpp"
#include "SimplnxCore/Filters/Algorithms/ComputeTriangleGeomVolumes.hpp"

#include "simplnx/Common/Types.hpp"
#include "simplnx/DataStructure/AttributeMatrix.hpp"
Expand All @@ -16,45 +16,45 @@ using namespace nx::core;
namespace nx::core
{
//------------------------------------------------------------------------------
std::string ComputeTriangleGeomSizesFilter::name() const
std::string ComputeTriangleGeomVolumesFilter::name() const
{
return FilterTraits<ComputeTriangleGeomSizesFilter>::name.str();
return FilterTraits<ComputeTriangleGeomVolumesFilter>::name.str();
}

//------------------------------------------------------------------------------
std::string ComputeTriangleGeomSizesFilter::className() const
std::string ComputeTriangleGeomVolumesFilter::className() const
{
return FilterTraits<ComputeTriangleGeomSizesFilter>::className;
return FilterTraits<ComputeTriangleGeomVolumesFilter>::className;
}

//------------------------------------------------------------------------------
Uuid ComputeTriangleGeomSizesFilter::uuid() const
Uuid ComputeTriangleGeomVolumesFilter::uuid() const
{
return FilterTraits<ComputeTriangleGeomSizesFilter>::uuid;
return FilterTraits<ComputeTriangleGeomVolumesFilter>::uuid;
}

//------------------------------------------------------------------------------
std::string ComputeTriangleGeomSizesFilter::humanName() const
std::string ComputeTriangleGeomVolumesFilter::humanName() const
{
return "Compute Feature Volumes from Triangle Geometry";
}

//------------------------------------------------------------------------------
std::vector<std::string> ComputeTriangleGeomSizesFilter::defaultTags() const
std::vector<std::string> ComputeTriangleGeomVolumesFilter::defaultTags() const
{
return {className(), "Generic", "Morphological", "SurfaceMesh", "Statistics", "Triangle"};
}

//------------------------------------------------------------------------------
Parameters ComputeTriangleGeomSizesFilter::parameters() const
Parameters ComputeTriangleGeomVolumesFilter::parameters() const
{
Parameters params;
// Create the parameter descriptors that are needed for this filter
params.insert(std::make_unique<GeometrySelectionParameter>(k_TriGeometryDataPath_Key, "Triangle Geometry", "The complete path to the Geometry for which to calculate the normals", DataPath{},
GeometrySelectionParameter::AllowedTypes{IGeometry::Type::Triangle}));
params.insertSeparator(Parameters::Separator{"Input Triangle Face Data"});
params.insert(std::make_unique<ArraySelectionParameter>(k_FaceLabelsArrayPath_Key, "Face Labels", "The DataPath to the FaceLabels values.", DataPath{},
ArraySelectionParameter::AllowedTypes{nx::core::DataType::int32}));
ArraySelectionParameter::AllowedTypes{DataType::int32}, ArraySelectionParameter::AllowedComponentShapes{{2}}));
params.insertSeparator(Parameters::Separator{"Input Face Feature Data"});
params.insert(std::make_unique<DataGroupSelectionParameter>(k_FeatureAttributeMatrixPath_Key, "Face Feature Attribute Matrix",
"The DataPath to the AttributeMatrix that holds feature data for the faces", DataPath({"TriangleDataContainer", "Face Feature Data"}),
Expand All @@ -66,20 +66,20 @@ Parameters ComputeTriangleGeomSizesFilter::parameters() const
}

//------------------------------------------------------------------------------
IFilter::VersionType ComputeTriangleGeomSizesFilter::parametersVersion() const
IFilter::VersionType ComputeTriangleGeomVolumesFilter::parametersVersion() const
{
return 1;
}

//------------------------------------------------------------------------------
IFilter::UniquePointer ComputeTriangleGeomSizesFilter::clone() const
IFilter::UniquePointer ComputeTriangleGeomVolumesFilter::clone() const
{
return std::make_unique<ComputeTriangleGeomSizesFilter>();
return std::make_unique<ComputeTriangleGeomVolumesFilter>();
}

//------------------------------------------------------------------------------
IFilter::PreflightResult ComputeTriangleGeomSizesFilter::preflightImpl(const DataStructure& dataStructure, const Arguments& filterArgs, const MessageHandler& messageHandler,
const std::atomic_bool& shouldCancel) const
IFilter::PreflightResult ComputeTriangleGeomVolumesFilter::preflightImpl(const DataStructure& dataStructure, const Arguments& filterArgs, const MessageHandler& messageHandler,
const std::atomic_bool& shouldCancel) const
{
auto pFaceLabelsArrayPath = filterArgs.value<DataPath>(k_FaceLabelsArrayPath_Key);
auto pFeatureAttributeMatrixPath = filterArgs.value<DataPath>(k_FeatureAttributeMatrixPath_Key);
Expand Down Expand Up @@ -112,17 +112,17 @@ IFilter::PreflightResult ComputeTriangleGeomSizesFilter::preflightImpl(const Dat
}

//------------------------------------------------------------------------------
Result<> ComputeTriangleGeomSizesFilter::executeImpl(DataStructure& dataStructure, const Arguments& filterArgs, const PipelineFilter* pipelineNode, const MessageHandler& messageHandler,
const std::atomic_bool& shouldCancel) const
Result<> ComputeTriangleGeomVolumesFilter::executeImpl(DataStructure& dataStructure, const Arguments& filterArgs, const PipelineFilter* pipelineNode, const MessageHandler& messageHandler,
const std::atomic_bool& shouldCancel) const
{
ComputeTriangleGeomSizesInputValues inputValues;
ComputeTriangleGeomVolumesInputValues inputValues;
inputValues.TriangleGeometryPath = filterArgs.value<DataPath>(k_TriGeometryDataPath_Key);
inputValues.FaceLabelsArrayPath = filterArgs.value<DataPath>(k_FaceLabelsArrayPath_Key);
inputValues.FeatureAttributeMatrixPath = filterArgs.value<DataPath>(k_FeatureAttributeMatrixPath_Key);

auto volumesArrayNameValue = filterArgs.value<DataObjectNameParameter::ValueType>(k_VolumesArrayName_Key);
inputValues.VolumesArrayPath = inputValues.FeatureAttributeMatrixPath.createChildPath(volumesArrayNameValue);

return ComputeTriangleGeomSizes(dataStructure, messageHandler, shouldCancel, &inputValues)();
return ComputeTriangleGeomVolumes(dataStructure, messageHandler, shouldCancel, &inputValues)();
}
} // namespace nx::core
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ namespace nx::core
* @class ComputeTriangleGeomSizesFilter
* @brief This filter will ....
*/
class SIMPLNXCORE_EXPORT ComputeTriangleGeomSizesFilter : public IFilter
class SIMPLNXCORE_EXPORT ComputeTriangleGeomVolumesFilter : public IFilter
{
public:
ComputeTriangleGeomSizesFilter() = default;
~ComputeTriangleGeomSizesFilter() noexcept override = default;
ComputeTriangleGeomVolumesFilter() = default;
~ComputeTriangleGeomVolumesFilter() noexcept override = default;

ComputeTriangleGeomSizesFilter(const ComputeTriangleGeomSizesFilter&) = delete;
ComputeTriangleGeomSizesFilter(ComputeTriangleGeomSizesFilter&&) noexcept = delete;
ComputeTriangleGeomVolumesFilter(const ComputeTriangleGeomVolumesFilter&) = delete;
ComputeTriangleGeomVolumesFilter(ComputeTriangleGeomVolumesFilter&&) noexcept = delete;

ComputeTriangleGeomSizesFilter& operator=(const ComputeTriangleGeomSizesFilter&) = delete;
ComputeTriangleGeomSizesFilter& operator=(ComputeTriangleGeomSizesFilter&&) noexcept = delete;
ComputeTriangleGeomVolumesFilter& operator=(const ComputeTriangleGeomVolumesFilter&) = delete;
ComputeTriangleGeomVolumesFilter& operator=(ComputeTriangleGeomVolumesFilter&&) noexcept = delete;

// Parameter Keys
static inline constexpr StringLiteral k_FaceLabelsArrayPath_Key = "face_labels_array_path";
Expand Down Expand Up @@ -104,4 +104,4 @@ class SIMPLNXCORE_EXPORT ComputeTriangleGeomSizesFilter : public IFilter
};
} // namespace nx::core

SIMPLNX_DEF_FILTER_TRAITS(nx::core, ComputeTriangleGeomSizesFilter, "a979bd9b-834e-4497-84b0-ab7a8add341a");
SIMPLNX_DEF_FILTER_TRAITS(nx::core, ComputeTriangleGeomVolumesFilter, "a979bd9b-834e-4497-84b0-ab7a8add341a");
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Parameters FeatureFaceCurvatureFilter::parameters() const
params.insertSeparator(Parameters::Separator{"Input Triangle Face Data"});
params.insert(std::make_unique<AttributeMatrixSelectionParameter>(k_FaceAttribMatrixPath_Key, "Face Attribute Matrix", "The AttributeMatrix that holds the triangle face data.", DataPath()));
params.insert(std::make_unique<ArraySelectionParameter>(k_FaceLabelsPath_Key, "Face Labels", "The DataPath to the 'Face Labels' DataArray", DataPath(),
ArraySelectionParameter::AllowedTypes{DataType::int32}, ArraySelectionParameter::AllowedComponentShapes{IArray::ShapeType{2}}));
ArraySelectionParameter::AllowedTypes{DataType::int32}, ArraySelectionParameter::AllowedComponentShapes{{2}}));
params.insert(std::make_unique<ArraySelectionParameter>(k_FeatureFaceIdsPath_Key, "Feature Face Ids", "The DataPath to the 'FeatureIds' DataArray", DataPath(),
ArraySelectionParameter::AllowedTypes{DataType::int32}, ArraySelectionParameter::AllowedComponentShapes{IArray::ShapeType{1}}));
params.insert(std::make_unique<ArraySelectionParameter>(k_FaceNormalsPath_Key, "Face Normals", "The DataPath to the 'Feature Normals' DataArray", DataPath(),
Expand Down
Loading

0 comments on commit f36ca6c

Please sign in to comment.