Skip to content

Commit

Permalink
FILTER: Label Triangle Geometry and Remove Flagged Triangles Filters (#…
Browse files Browse the repository at this point in the history
…842)

Signed-off-by: Michael Jackson <[email protected]>
Co-authored-by: Matthew Marine <[email protected]>
Co-authored-by: Michael Jackson <[email protected]>
  • Loading branch information
3 people authored Feb 2, 2024
1 parent c265d60 commit d512fa2
Show file tree
Hide file tree
Showing 27 changed files with 1,229 additions and 52 deletions.
6 changes: 5 additions & 1 deletion src/Plugins/SimplnxCore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ set(FilterList
IterativeClosestPointFilter
KMeansFilter
KMedoidsFilter
LabelTriangleGeometryFilter
LaplacianSmoothingFilter
MapPointCloudToRegularGridFilter
MinNeighbors
Expand All @@ -98,6 +99,7 @@ set(FilterList
ReadVolumeGraphicsFileFilter
RegularGridSampleSurfaceMeshFilter
RemoveFlaggedFeaturesFilter
RemoveFlaggedTrianglesFilter
RemoveFlaggedVertices
RemoveMinimumSizeFeaturesFilter
RenameDataObject
Expand Down Expand Up @@ -173,6 +175,7 @@ set(AlgorithmList
ImageContouring
KMeans
KMedoids
LabelTriangleGeometry
LaplacianSmoothing
NearestPointFuseRegularGrids
PartitionGeometry
Expand All @@ -185,6 +188,7 @@ set(AlgorithmList
ReadVolumeGraphicsFile
RegularGridSampleSurfaceMesh
RemoveFlaggedFeatures
RemoveFlaggedTriangles
ReplaceElementAttributesWithNeighborValues
ResampleImageGeom
ResampleRectGridToImageGeom
Expand Down Expand Up @@ -428,7 +432,7 @@ if(EXISTS "${DREAM3D_DATA_DIR}" AND SIMPLNX_DOWNLOAD_TEST_FILES)

download_test_data(DREAM3D_DATA_DIR ${DREAM3D_DATA_DIR}
ARCHIVE_NAME STL_Models.tar.gz
SHA512 14d5bbb1dcc241a5ad9b17e7647144926f22fca9af5e426798c2ed423d8d3b5d89d8c66ce9e6854bfcdbaea7f72b69980477ab837498e3dca89b5cd2870e2cff
SHA512 6a17caa1c5b60740a18d30732b10139b5864e12abd5009ce482972f4070f86e1762a3bf2bbceb8f178187b4d70bedbde1516f32397c3d4424404557b320dde9d
INSTALL
COPY_DATA
)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions src/Plugins/SimplnxCore/docs/LabelTriangleGeometryFilter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Label Triangle Geometry

## Group (Subgroup)

Surface Meshing (Geometry)

## Description

This **Filter** accepts a **Triangle Geometry** and checks the connectivity of **Triangles** and assigns them **region ID**s in a mask accordingly as well as providing a count for the number of **Triangles** in each **Region**.

Note: Our connectivity is different from other connectivity algorithms, in that it is dependent on the dimensionality of the geometry it is run on. A triangle geometry is two dimensional thus it must share one edge with another triangle to be considered connected. Only one shared vertex will not be enough to count triangles as connected. See the following image for reference:

![Connectivity Image](Images/connectivity_image.png)

The image in question demonstrates what geometric shapes would be considered connected according to matching color scheme. The colors are relative to the shapes dimensionality. Thus the fact there is a yellow triangle and a yellow cube does not mean they are related.

- 1D Geometry: Two edges are considered connected if they share a vertex.
- 2D Geometry: Triangle and Quad Geometries are considered connected if they share an entire edge. As shown in the image above, Triangles 1 & 2 are connected while triangles 2 & 3 are **not** connected.
- 3D Geometry: Hexahedron/Tetrahedron: In the image above the hexahedrons 4,5, and 6 are **not** considered connected while 6 & 7 are considered connected.

## Example Output

The image below shows a single STL file that contains 12 different geometries. This filter labeled each geometry with a unique "Region ID" and the visualization is colored by those "Region Ids"

![Filter Output](Images/LabelTriangleGeometry_1.png)

% Auto generated parameter table will be inserted here

## License & Copyright

Please see the description file distributed with this plugin.

## DREAM3D-NX Help

If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues) GItHub site where the community of DREAM3D-NX users can help answer your questions.
26 changes: 1 addition & 25 deletions src/Plugins/SimplnxCore/docs/RegularGridSampleSurfaceMesh.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,7 @@ This **Filter** "samples" a triangulated surface mesh on a rectilinear grid. The
3. For each bounding box a **Cell** falls in, check against that **Feature's** **Triangle** list to determine if the **Cell** falls within that n-sided polyhedra (*Note:* if the surface mesh is conformal, then each **Cell** will only belong to one **Feature**, but if not, the last **Feature** the **Cell** is found to fall inside of will *own* the **Cell**)
4. Assign the **Feature** number that the **Cell** falls within to the *Feature Ids* array in the new rectilinear grid geometry

## Parameters

| Name | Type | Description |
|------------|------| --------------------------------- |
| Dimensions | uint64 | Number of **Cells** along each axis |
| Resolution | float32 (3x) | The resolution values (dx, dy, dz) |
| Origin | float32 (3x) | The origin of the sampling volume |

## Required Geometry

Triangle

## Required Objects

| Type | Default Name | Type | Comp Dims | Description |
|------|--------------|-----|-----|-----------------------------------|
| Data Array | Face Labels | int32 | (2) | Specifies which **Features** are on either side of each **Face**. |

## Created

| Kind | Default Name | Type | Comp Dims | Description |
|---------------------------|--------------|----------|--------|---------------------------------------------|
| Image Geometry | Image Geometry | N/A | N/A | Created **Image Geometry** name and *DataPath* |
| Attribute Matrix | Cell Data | Cell | N/A | Created **Cell Attribute Matrix** name |
| Data Array | Feature Ids | int32 | (1) | Specifies to which **Feature** each **Cell** belongs |
% Auto generated parameter table will be inserted here

## License & Copyright

Expand Down
10 changes: 5 additions & 5 deletions src/Plugins/SimplnxCore/docs/RemoveFlaggedFeaturesFilter.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ Processing (Cleanup)

## Description

This **Filter** will remove **Features** that have been flagged by another **Filter** from the structure. The **Filter**
requires that the user point to a boolean array at the **Feature** level that tells the **Filter** whether the **Feature**
should remain in the structure. If the boolean array is *false* for a **Feature**, then all **Cells** that belong to that
**Feature** are temporarily *unassigned*. Optionally, after all *undesired* **Features** are removed, the remaining **Features** are
isotropically coarsened to fill in the gaps left by the removed **Features**.
This **Filter** will remove **Features** that have been flagged by another **Filter** from the structure. The **Filter** requires that the user point to a boolean array at the **Feature** level that tells the **Filter** whether the **Feature** should remain in the structure. If the boolean array is *false* for a **Feature**, then all **Cells** that belong to that **Feature** are temporarily *unassigned*. Optionally, after all *undesired* **Features** are removed, the remaining **Features** are isotropically coarsened to fill in the gaps left by the removed **Features**.

## Caveats

This filter will **ONLY** run on an Image Geometry.

% Auto generated parameter table will be inserted here

Expand Down
38 changes: 38 additions & 0 deletions src/Plugins/SimplnxCore/docs/RemoveFlaggedTrianglesFilter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Remove Flagged Triangles

## Group (Subgroup)

Surface Meshing (Misc)

## Description

This **Filter** removes **Triangles** from the supplied **Triangle Geometry** that are flagged by a boolean mask array as **true**. A new reduced **Geometry** is created that contains all the remaining **Triangles**. It is unknown until run time how many **Triangles** will be removed from the **Geometry**. Therefore, this **Filter** requires that a new **TriangleGeom** be created to contain the reduced **Triangle Geometry**. This new **Geometry** will *NOT* contain copies of any **Feature Attribute Matrix** or **Ensemble Attribute Matrix** from the original **Geometry**.

- Additionally, all **Vertex** data will be copied, with tuples *removed* for any **Vertices** removed by the **Filter**. The user must supply a name for the reduced **Geometry**.

The mask is expected to be over the triangles themselves so it should be based on something from the ***Face Data*** **Attribute Matrix**, generally we suggest basing the mask on the created **Region Ids** array from the *Label Triangle Geometry Filter*.

*Note:* Since it cannot be known before run time how many **Vertices** will be removed, the new **Vertex Geometry** and
all associated **Vertex** data to be copied will be initialized to have size 0.

## Example Output

- The next figure shows a triangle geometry that has had a mask generated. Yellow parts are flagged as true.

![Masked triangle geometries for removal.](Images/RemoveFlaggedTriangles_1.png)

- The next figure shows the result of running the filter.

![Resulting triangle geometry](Images/RemoveFlaggedTriangles_2.png)

% Auto generated parameter table will be inserted here

## Example Pipelines

## License & Copyright

Please see the description file distributed with this plugin.

## DREAM3D-NX Help

If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues) GItHub site where the community of DREAM3D-NX users can help answer your questions.
113 changes: 113 additions & 0 deletions src/Plugins/SimplnxCore/pipelines/Remove_Triangles.d3dpipeline
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"isDisabled": false,
"name": "Untitled Pipeline",
"pipeline": [
{
"args": {
"face_attribute_matrix": "Face Data",
"face_normals_data_path": "Face Normals",
"scale_factor": 1.0,
"scale_output": false,
"stl_file_path": "Data/STL_Models/Example_Triangle_Geometry.stl",
"triangle_geometry_name": "TriangleDataContainer",
"vertex_attribute_matrix": "Vertex Data"
},
"comments": "",
"filter": {
"name": "nx::core::ReadStlFileFilter",
"uuid": "2f64bd45-9d28-4254-9e07-6aa7c6d3d015"
},
"isDisabled": false
},
{
"args": {
"created_region_ids_path": "TriangleDataContainer/Face Data/Region Ids",
"num_triangles_name": "NumTriangles",
"triangle_attribute_matrix_name": "CAD Part Data",
"triangle_geom_path": "TriangleDataContainer"
},
"comments": "",
"filter": {
"name": "nx::core::LabelTriangleGeometryFilter",
"uuid": "7a7a2c6f-3b03-444d-8b8c-5976b0e5c82e"
},
"isDisabled": false
},
{
"args": {
"array_thresholds": {
"inverted": false,
"thresholds": [
{
"array_path": "TriangleDataContainer/Face Data/Region Ids",
"comparison": 0,
"inverted": false,
"type": "array",
"union": 0,
"value": 9.0
}
],
"type": "collection",
"union": 0
},
"created_data_path": "Mask",
"created_mask_type": 1,
"custom_false_value": 0.0,
"custom_true_value": 1.0,
"use_custom_false_value": false,
"use_custom_true_value": false
},
"comments": "",
"filter": {
"name": "nx::core::MultiThresholdObjects",
"uuid": "4246245e-1011-4add-8436-0af6bed19228"
},
"isDisabled": false
},
{
"args": {
"array_thresholds": {
"inverted": false,
"thresholds": [
{
"array_path": "TriangleDataContainer/Face Data/Region Ids",
"comparison": 0,
"inverted": false,
"type": "array",
"union": 0,
"value": 9.0
}
],
"type": "collection",
"union": 0
},
"created_data_path": "Mask2",
"created_mask_type": 10,
"custom_false_value": 0.0,
"custom_true_value": 1.0,
"use_custom_false_value": false,
"use_custom_true_value": false
},
"comments": "",
"filter": {
"name": "nx::core::MultiThresholdObjects",
"uuid": "4246245e-1011-4add-8436-0af6bed19228"
},
"isDisabled": false
},
{
"args": {
"input_geometry": "TriangleDataContainer",
"mask_array_path": "TriangleDataContainer/Face Data/Mask2",
"output_geometry": "Part 10"
},
"comments": "",
"filter": {
"name": "nx::core::RemoveFlaggedTrianglesFilter",
"uuid": "38155c61-2709-4731-be95-43745bb3f8d8"
},
"isDisabled": false
}
],
"version": 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include "LabelTriangleGeometry.hpp"

#include "simplnx/DataStructure/DataArray.hpp"
#include "simplnx/DataStructure/DataGroup.hpp"
#include "simplnx/DataStructure/Geometry/TriangleGeom.hpp"

using namespace nx::core;

// -----------------------------------------------------------------------------
LabelTriangleGeometry::LabelTriangleGeometry(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel,
LabelTriangleGeometryInputValues* inputValues)
: m_DataStructure(dataStructure)
, m_InputValues(inputValues)
, m_ShouldCancel(shouldCancel)
, m_MessageHandler(mesgHandler)
{
}

// -----------------------------------------------------------------------------
LabelTriangleGeometry::~LabelTriangleGeometry() noexcept = default;

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

// -----------------------------------------------------------------------------
Result<> LabelTriangleGeometry::operator()()
{
// Scope other values since underlying arrays will be changed by the time they are need again
std::vector<uint32> triangleCounts = {0, 0};
auto& triangle = m_DataStructure.getDataRefAs<TriangleGeom>(m_InputValues->TriangleGeomPath);

{
usize numTris = triangle.getNumberOfFaces();

auto check = triangle.findElementNeighbors(); // use auto since return time is a class declared typename
if(check < 0)
{
return MakeErrorResult(check, fmt::format("Error finding element neighbors for {} geometry", triangle.getName()));
}

const TriangleGeom::ElementDynamicList* triangleNeighborsPtr = triangle.getElementNeighbors();

auto& regionIds = m_DataStructure.getDataRefAs<Int32Array>(m_InputValues->RegionIdsPath);

usize chunkSize = 1000;
std::vector<int32> triList(chunkSize, -1);
// first identify connected triangle sets as features
int32 regionCount = 1;
for(usize i = 0; i < numTris; i++)
{
if(regionIds[i] == 0)
{
regionIds[i] = regionCount;
triangleCounts[regionCount]++;

usize size = 0;
triList[size] = static_cast<int32>(i);
size++;
while(size > 0)
{
TriangleGeom::MeshIndexType tri = triList[size - 1];
size -= 1;
uint16_t tCount = triangleNeighborsPtr->getNumberOfElements(tri);
TriangleGeom::MeshIndexType* dataPtr = triangleNeighborsPtr->getElementListPointer(tri);
for(int j = 0; j < tCount; j++)
{
TriangleGeom::MeshIndexType neighTri = dataPtr[j];
if(regionIds[neighTri] == 0)
{
regionIds[neighTri] = regionCount;
triangleCounts[regionCount]++;
triList[size] = static_cast<int32>(neighTri);
size++;
if(size >= triList.size())
{
size = triList.size();
triList.resize(size + chunkSize);
for(usize k = size; k < triList.size(); ++k)
{
triList[k] = -1;
}
}
}
}
}
regionCount++;
triangleCounts.push_back(0);
}
}

// Resize the Triangle Region AttributeMatrix
m_DataStructure.getDataAs<AttributeMatrix>(m_InputValues->TriangleAMPath)->resizeTuples(std::vector<usize>{triangleCounts.size()});
}

// Clear ElementDynamicLists so write out is possible
triangle.deleteElementNeighbors();
// Remove elements containing vertices, because Element neighbors created it quietly under the covers
triangle.deleteElementsContainingVert();

// copy triangleCounts into the proper DataArray "NumTriangles" in the Feature Attribute Matrix
auto& numTriangles = m_DataStructure.getDataRefAs<UInt64Array>(m_InputValues->NumTrianglesPath);
for(usize index = 0; index < numTriangles.getSize(); index++)
{
numTriangles[index] = static_cast<uint64>(triangleCounts[index]);
}

return {};
}
Loading

0 comments on commit d512fa2

Please sign in to comment.