diff --git a/Source/Plugins/Reconstruction/ReconstructionFilters/PartitionGeometry.cpp b/Source/Plugins/Reconstruction/ReconstructionFilters/PartitionGeometry.cpp index 9c86da2e6e..dbb8a759d2 100644 --- a/Source/Plugins/Reconstruction/ReconstructionFilters/PartitionGeometry.cpp +++ b/Source/Plugins/Reconstruction/ReconstructionFilters/PartitionGeometry.cpp @@ -37,6 +37,7 @@ #include "SIMPLib/FilterParameters/AttributeMatrixSelectionFilterParameter.h" #include "SIMPLib/FilterParameters/DataArraySelectionFilterParameter.h" #include "SIMPLib/FilterParameters/DataContainerCreationFilterParameter.h" +#include "SIMPLib/FilterParameters/DataContainerSelectionFilterParameter.h" #include "SIMPLib/FilterParameters/IntFilterParameter.h" #include "SIMPLib/FilterParameters/LinkedBooleanFilterParameter.h" #include "SIMPLib/FilterParameters/LinkedChoicesFilterParameter.h" @@ -50,6 +51,7 @@ #include "SIMPLib/Geometry/TetrahedralGeom.h" #include "SIMPLib/Geometry/TriangleGeom.h" #include "SIMPLib/Geometry/VertexGeom.h" +#include "SIMPLib/Utilities/STLUtilities.hpp" #include "Reconstruction/ReconstructionConstants.h" #include "Reconstruction/ReconstructionVersion.h" @@ -58,35 +60,70 @@ namespace Detail { const QString k_RectGridSpaceUnknownStr = "Rectilinear grid geometry space unknown during preflight."; -std::optional InitPartitioningGeometryUsingVertices(ImageGeom& partitionImageGeometry, IntVec3Type& numberOfPartitionsPerAxis, const FloatArrayType& vertices, bool inPreflight, - bool padEdges = false) +struct InitResult +{ + std::optional message; + int errorCode = 0; +}; + +InitResult InitPartitioningGeometryUsingVertices(ImageGeom& partitionImageGeometry, IntVec3Type& numberOfPartitionsPerAxis, const FloatArrayType& vertices, bool inPreflight, bool padEdges = false) { if(inPreflight) { // Do not do this in preflight because the bounding box data is not available - return "Node-based geometry space unknown during preflight."; + return {"Node-based geometry space unknown during preflight."}; } FloatVec3Type ll = {std::numeric_limits::max(), std::numeric_limits::max(), std::numeric_limits::max()}; FloatVec3Type ur = {std::numeric_limits::min(), std::numeric_limits::min(), std::numeric_limits::min()}; // For each tuple, update the current lower-left and upper-right coordinates + std::set setX; + std::set setY; + std::set setZ; for(size_t tuple = 0; tuple < vertices.getNumberOfTuples(); tuple++) { float x = vertices.getComponent(tuple, 0); + setX.insert(x); ll[0] = (x < ll[0]) ? x : ll[0]; ur[0] = (x > ur[0]) ? x : ur[0]; float y = vertices.getComponent(tuple, 1); + setY.insert(y); ll[1] = (y < ll[1]) ? y : ll[1]; ur[1] = (y > ur[1]) ? y : ur[1]; float z = vertices.getComponent(tuple, 2); + setZ.insert(z); ll[2] = (z < ll[2]) ? z : ll[2]; ur[2] = (z > ur[2]) ? z : ur[2]; } - // Pad the points + // YZ Plane + if(setX.size() == 1) + { + return {"Unable to create a partitioning scheme with an X dimension size of 0. Vertices are in a YZ plane. Use the Advanced or Bounding Box partitioning modes to manually create a " + "partitioning scheme.", + -3040}; + } + + // XZ Plane + if(setY.size() == 1) + { + return {"Unable to create a partitioning scheme with a Y dimension size of 0. Vertices are in an XZ plane. Use the Advanced or Bounding Box partitioning modes to manually create a " + "partitioning scheme.", + -3041}; + } + + // XY Plane + if(setZ.size() == 1) + { + return {"Unable to create a partitioning scheme with a Z dimension size of 0. Vertices are in an XY plane. Use the Advanced or Bounding Box partitioning modes to manually create a " + "partitioning scheme.", + -3042}; + } + + // Pad the points (needed to make sure that all points are within the partitioning scheme and not on an edge) if(padEdges) { float padding = 0.000001; @@ -116,9 +153,27 @@ std::optional InitPartitioningGeometryUsingVertices(ImageGeom& partitio return {}; } -std::optional InitPartitioningGeometryUsingBoundingBox(ImageGeom& partitionImageGeometry, IntVec3Type& numberOfPartitionsPerAxis, const FloatVec3Type& lowerLeftCoord, - const FloatVec3Type& upperRightCoord, bool inPreflight) +InitResult InitPartitioningGeometryUsingBoundingBox(ImageGeom& partitionImageGeometry, IntVec3Type& numberOfPartitionsPerAxis, const FloatVec3Type& lowerLeftCoord, + const FloatVec3Type& upperRightCoord, bool inPreflight) { + // YZ Plane + if(lowerLeftCoord.getX() == upperRightCoord.getX()) + { + return {"Unable to create a partitioning scheme with an X dimension size of 0. Bounding box is in a YZ plane.", -3043}; + } + + // XZ Plane + if(lowerLeftCoord.getY() == upperRightCoord.getY()) + { + return {"Unable to create a partitioning scheme with a Y dimension size of 0. Bounding box is in an XZ plane.", -3044}; + } + + // XY Plane + if(lowerLeftCoord.getZ() == upperRightCoord.getZ()) + { + return {"Unable to create a partitioning scheme with a Z dimension size of 0. Bounding box is in an XY plane.", -3045}; + } + FloatArrayType::Pointer vertices = FloatArrayType::CreateArray(2, {3}, "Vertices", true); vertices->setComponent(0, 0, lowerLeftCoord[0]); vertices->setComponent(0, 1, lowerLeftCoord[1]); @@ -130,17 +185,14 @@ std::optional InitPartitioningGeometryUsingBoundingBox(ImageGeom& parti } template -std::optional InitSimplePartitioningGeometry(const T& geometry, ImageGeom& partitionImageGeometry, IntVec3Type& numberOfPartitionsPerAxis, bool inPreflight) +InitResult InitSimplePartitioningGeometry(const T& geometry, ImageGeom& partitionImageGeometry, IntVec3Type& numberOfPartitionsPerAxis, bool inPreflight) { SharedVertexList::Pointer vertexList = geometry.getVertices(); - - // A very small padding around the edges is necessary to avoid assigning the edge indices the wrong partition ID. - // This is only needed in the Simple case, since the partition geometry inputs are more specific in the other cases. - return Detail::InitPartitioningGeometryUsingVertices(partitionImageGeometry, numberOfPartitionsPerAxis, *vertexList, inPreflight, true); + return InitPartitioningGeometryUsingVertices(partitionImageGeometry, numberOfPartitionsPerAxis, *vertexList, inPreflight, true); } template <> -std::optional InitSimplePartitioningGeometry(const ImageGeom& geometry, ImageGeom& partitionImageGeometry, IntVec3Type& numberOfPartitionsPerAxis, bool inPreflight) +InitResult InitSimplePartitioningGeometry(const ImageGeom& geometry, ImageGeom& partitionImageGeometry, IntVec3Type& numberOfPartitionsPerAxis, bool inPreflight) { Q_UNUSED(inPreflight) @@ -157,12 +209,12 @@ std::optional InitSimplePartitioningGeometry(const ImageGeom& geometry, } template <> -std::optional InitSimplePartitioningGeometry(const RectGridGeom& geometry, ImageGeom& partitionImageGeometry, IntVec3Type& numberOfPartitionsPerAxis, bool inPreflight) +InitResult InitSimplePartitioningGeometry(const RectGridGeom& geometry, ImageGeom& partitionImageGeometry, IntVec3Type& numberOfPartitionsPerAxis, bool inPreflight) { // Do not do this in preflight because the bounds data is not available if(inPreflight) { - return Detail::k_RectGridSpaceUnknownStr; + return {Detail::k_RectGridSpaceUnknownStr}; } FloatArrayType::Pointer xBounds = geometry.getXBounds(); @@ -238,7 +290,7 @@ void PartitionGeometry::setupFilterParameters() { LinkedChoicesFilterParameter::Pointer parameter = LinkedChoicesFilterParameter::New(); - parameter->setHumanLabel("Select the partitioning scheme"); + parameter->setHumanLabel("Select the partitioning mode"); parameter->setPropertyName("PartitioningMode"); parameter->setSetterCallback(SIMPL_BIND_SETTER(PartitionGeometry, this, PartitioningMode)); parameter->setGetterCallback(SIMPL_BIND_GETTER(PartitionGeometry, this, PartitioningMode)); @@ -248,31 +300,45 @@ void PartitionGeometry::setupFilterParameters() choices.push_back("Basic"); choices.push_back("Advanced"); choices.push_back("Bounding Box"); + choices.push_back("Existing Partitioning Scheme"); parameter->setChoices(choices); std::vector linkedProps; - linkedProps.push_back("AdvancedOutOfBoundsValue"); - linkedProps.push_back("BoundingBoxOutOfBoundsValue"); + linkedProps.push_back("NumberOfPartitionsPerAxis"); + linkedProps.push_back("OutOfBoundsValue"); linkedProps.push_back("PartitioningSchemeOrigin"); linkedProps.push_back("LengthPerPartition"); // linkedProps.push_back("BoundingBoxPath"); linkedProps.push_back("LowerLeftCoord"); linkedProps.push_back("UpperRightCoord"); + linkedProps.push_back("PartitioningSchemeDataContainerName"); parameter->setLinkedProperties(linkedProps); parameter->setEditable(false); parameter->setCategory(FilterParameter::Category::Parameter); parameters.push_back(parameter); } + int basicMode = SIMPL::to_underlying(PartitioningMode::Basic); + int advancedMode = SIMPL::to_underlying(PartitioningMode::Advanced); + int boundingBoxMode = SIMPL::to_underlying(PartitioningMode::BoundingBox); + int existingPartSchemeMode = SIMPL::to_underlying(PartitioningMode::ExistingPartitioningScheme); + parameters.push_back(SIMPL_NEW_INTEGER_FP("Starting Partition ID", StartingPartitionID, FilterParameter::Category::Parameter, PartitionGeometry)); - parameters.push_back(SIMPL_NEW_INTEGER_FP("Out-Of-Bounds Partition ID", AdvancedOutOfBoundsValue, FilterParameter::Category::Parameter, PartitionGeometry, {1})); - parameters.push_back(SIMPL_NEW_INTEGER_FP("Out-Of-Bounds Partition ID", BoundingBoxOutOfBoundsValue, FilterParameter::Category::Parameter, PartitionGeometry, {2})); + parameters.push_back(SIMPL_NEW_INTEGER_FP("Out-Of-Bounds Value", OutOfBoundsValue, FilterParameter::Category::Parameter, PartitionGeometry, {advancedMode, boundingBoxMode})); parameters.push_back(SeparatorFilterParameter::Create("Partitioning Scheme Details", FilterParameter::Category::Parameter)); - parameters.push_back(SIMPL_NEW_INT_VEC3_FP("Number Of Partitions Per Axis (X, Y, Z)", NumberOfPartitionsPerAxis, FilterParameter::Category::Parameter, PartitionGeometry)); - parameters.push_back(SIMPL_NEW_FLOAT_VEC3_FP("Partitioning Scheme Origin (X, Y, Z)", PartitioningSchemeOrigin, FilterParameter::Category::Parameter, PartitionGeometry, {1})); - parameters.push_back(SIMPL_NEW_FLOAT_VEC3_FP("Length Per Partition (X, Y, Z)", LengthPerPartition, FilterParameter::Category::Parameter, PartitionGeometry, {1})); + parameters.push_back( + SIMPL_NEW_INT_VEC3_FP("Number Of Partitions Per Axis (X, Y, Z)", NumberOfPartitionsPerAxis, FilterParameter::Category::Parameter, PartitionGeometry, {basicMode, advancedMode, boundingBoxMode})); + parameters.push_back(SIMPL_NEW_FLOAT_VEC3_FP("Partitioning Scheme Origin (X, Y, Z)", PartitioningSchemeOrigin, FilterParameter::Category::Parameter, PartitionGeometry, {advancedMode})); + parameters.push_back(SIMPL_NEW_FLOAT_VEC3_FP("Length Per Partition (X, Y, Z)", LengthPerPartition, FilterParameter::Category::Parameter, PartitionGeometry, {advancedMode})); - parameters.push_back(SIMPL_NEW_FLOAT_VEC3_FP("Lower Left Coordinate (X, Y, Z)", LowerLeftCoord, FilterParameter::Category::Parameter, PartitionGeometry, {2})); - parameters.push_back(SIMPL_NEW_FLOAT_VEC3_FP("Upper Right Coordinate (X, Y, Z)", UpperRightCoord, FilterParameter::Category::Parameter, PartitionGeometry, {2})); + parameters.push_back(SIMPL_NEW_FLOAT_VEC3_FP("Lower Left Coordinate (X, Y, Z)", LowerLeftCoord, FilterParameter::Category::Parameter, PartitionGeometry, {boundingBoxMode})); + parameters.push_back(SIMPL_NEW_FLOAT_VEC3_FP("Upper Right Coordinate (X, Y, Z)", UpperRightCoord, FilterParameter::Category::Parameter, PartitionGeometry, {boundingBoxMode})); + + { + DataContainerSelectionFilterParameter::RequirementType req; + req.dcGeometryTypes = IGeometry::Types(1, IGeometry::Type::Image); + parameters.push_back( + SIMPL_NEW_DC_SELECTION_FP("Partitioning Scheme Data Container", PartitioningSchemeDataContainerName, FilterParameter::Category::Parameter, PartitionGeometry, req, {existingPartSchemeMode})); + } PreflightUpdatedValueFilterParameter::Pointer param = SIMPL_NEW_PREFLIGHTUPDATEDVALUE_FP("Partitioning Scheme Information", PartitioningSchemeInformation, FilterParameter::Category::Parameter, PartitionGeometry); @@ -282,8 +348,12 @@ void PartitionGeometry::setupFilterParameters() std::vector linkedProps = {"PSDataContainerPath", "PSAttributeMatrixName"}; parameters.push_back(SIMPL_NEW_LINKED_BOOL_FP("Save Partitioning Scheme As Image Geometry", SavePartitioningScheme, FilterParameter::Category::Parameter, PartitionGeometry, linkedProps)); parameters.push_back(SIMPL_NEW_DC_CREATION_FP("Partitioning Scheme Data Container", PSDataContainerPath, FilterParameter::Category::Parameter, PartitionGeometry)); + parameters.push_back(SIMPL_NEW_AM_WITH_LINKED_DC_FP("Partition Scheme Attribute Matrix", PSAttributeMatrixName, PSDataContainerPath, FilterParameter::Category::Parameter, PartitionGeometry)); + linkedProps = {"VertexMaskPath"}; + parameters.push_back(SIMPL_NEW_LINKED_BOOL_FP("Use Vertex Mask", UseVertexMask, FilterParameter::Category::Parameter, PartitionGeometry, linkedProps)); + { AttributeMatrixSelectionFilterParameter::RequirementType req; req.amTypes = {AttributeMatrix::Type::Cell, AttributeMatrix::Type::Vertex, AttributeMatrix::Type::Face, AttributeMatrix::Type::Edge}; @@ -295,11 +365,21 @@ void PartitionGeometry::setupFilterParameters() param->setReadOnly(true); parameters.push_back(param); + { + DataArraySelectionFilterParameter::RequirementType req; + req.amTypes = {AttributeMatrix::Type::Vertex}; + req.daTypes = {SIMPL::TypeNames::Bool}; + req.componentDimensions = {{1}}; + req.dcGeometryTypes = {IGeometry::Type::Vertex, IGeometry::Type::Edge, IGeometry::Type::Quad, IGeometry::Type::Triangle, IGeometry::Type::Tetrahedral, IGeometry::Type::Hexahedral}; + parameters.push_back(SIMPL_NEW_DA_SELECTION_FP("Vertex Mask", VertexMaskPath, FilterParameter::Category::RequiredArray, PartitionGeometry, req)); + } + // { // DataArraySelectionFilterParameter::RequirementType req = DataArraySelectionFilterParameter::CreateRequirement(SIMPL::TypeNames::Float, 3, AttributeMatrix::Type::Any, IGeometry::Type::Any); // parameters.push_back(SIMPL_NEW_DA_SELECTION_FP("Partitioning Scheme Bounding Box", BoundingBoxPath, FilterParameter::Category::RequiredArray, PartitionGeometry, req, 2)); // } + parameters.push_back(SIMPL_NEW_AM_WITH_LINKED_DC_FP("Feature Attribute Matrix", FeatureAttributeMatrixName, AttributeMatrixPath, FilterParameter::Category::Parameter, PartitionGeometry)); parameters.push_back(SIMPL_NEW_DA_WITH_LINKED_AM_FP("Partition Ids", PartitionIdsArrayName, AttributeMatrixPath, AttributeMatrixPath, FilterParameter::Category::CreatedArray, PartitionGeometry)); setFilterParameters(parameters); @@ -312,77 +392,25 @@ void PartitionGeometry::dataCheck() { clearErrorCode(); clearWarningCode(); + m_PartitionImageGeometryResult = {}; - if(m_NumberOfPartitionsPerAxis.getX() <= 0) - { - QString ss = QObject::tr("Number of Partitions Per Axis: The X dimension must be greater than 0."); - setErrorCondition(-3000, ss); - return; - } - - if(m_NumberOfPartitionsPerAxis.getY() <= 0) + AttributeMatrix::Pointer am = getDataContainerArray()->getPrereqAttributeMatrixFromPath(this, m_AttributeMatrixPath, 1); + if(getErrorCode() != 0) { - QString ss = QObject::tr("Number of Partitions Per Axis: The Y dimension must be greater than 0."); - setErrorCondition(-3001, ss); return; } - if(m_NumberOfPartitionsPerAxis.getZ() <= 0) + if(m_StartingPartitionID < 0) { - QString ss = QObject::tr("Number of Partitions Per Axis: The Z dimension must be greater than 0."); + QString ss = QObject::tr("Starting Partition ID: The value cannot be negative."); setErrorCondition(-3002, ss); return; } - if(static_cast(m_PartitioningMode) == PartitioningMode::Advanced) - { - if(m_LengthPerPartition.getX() < 0) - { - QString ss = QObject::tr("Length Per Partition: The X value cannot be negative."); - setErrorCondition(-3003, ss); - return; - } - if(m_LengthPerPartition.getY() < 0) - { - QString ss = QObject::tr("Length Per Partition: The Y value cannot be negative."); - setErrorCondition(-3004, ss); - return; - } - if(m_LengthPerPartition.getZ() < 0) - { - QString ss = QObject::tr("Length Per Partition: The Z value cannot be negative."); - setErrorCondition(-3005, ss); - return; - } - } - - if(static_cast(m_PartitioningMode) == PartitioningMode::BoundingBox) - { - if(m_LowerLeftCoord.getX() > m_UpperRightCoord.getX()) - { - QString ss = QObject::tr("Lower Left Coordinate: X value is larger than the upper right coordinate X value."); - setErrorCondition(-3006, ss); - return; - } - - if(m_LowerLeftCoord.getY() > m_UpperRightCoord.getY()) - { - QString ss = QObject::tr("Lower Left Coordinate: Y value is larger than the upper right coordinate Y value."); - setErrorCondition(-3007, ss); - return; - } - - if(m_LowerLeftCoord.getZ() > m_UpperRightCoord.getZ()) - { - QString ss = QObject::tr("Lower Left Coordinate: Z value is larger than the upper right coordinate Z value."); - setErrorCondition(-3008, ss); - return; - } - } - - AttributeMatrix::Pointer am = getDataContainerArray()->getPrereqAttributeMatrixFromPath(this, m_AttributeMatrixPath, 1); - if(getErrorCode() < 0) + if(m_FeatureAttributeMatrixName.isEmpty()) { + QString ss = QObject::tr("The output Feature Attribute Matrix must have a name."); + setErrorCondition(-3030, ss); return; } @@ -392,7 +420,7 @@ void PartitionGeometry::dataCheck() { QString ss = QObject::tr("The data container '%1', containing the attribute matrix '%2', must have a geometry.") .arg(m_AttributeMatrixPath.getDataContainerName(), m_AttributeMatrixPath.getAttributeMatrixName()); - setErrorCondition(-3009, ss); + setErrorCondition(-3000, ss); return; } @@ -400,139 +428,78 @@ void PartitionGeometry::dataCheck() { case IGeometry::Type::Image: { - ImageGeom::Pointer geometry = dc->getGeometryAs(); - if(am->getNumberOfTuples() != geometry->getNumberOfElements()) - { - QString ss = QObject::tr("The attribute matrix '%1' does not have the same tuple count (%2) as data container \"%3\"'s cell count (%4).") - .arg(am->getName(), QString::number(am->getNumberOfTuples()), dc->getName(), QString::number(geometry->getNumberOfElements())); - setErrorCondition(-3010, ss); - return; - } - m_PartitionImageGeometryResult = createPartitioningSchemeGeometry(*geometry); + dataCheckPartitioningMode(); + dc->createAndAddAttributeMatrix({0}, m_FeatureAttributeMatrixName, AttributeMatrix::Type::CellFeature); break; } case IGeometry::Type::RectGrid: { - RectGridGeom::Pointer geometry = dc->getGeometryAs(); - if(am->getNumberOfTuples() != geometry->getNumberOfElements()) - { - QString ss = QObject::tr("The attribute matrix '%1' does not have the same tuple count (%2) as data container \"%3\"'s cell count (%4).") - .arg(am->getName(), QString::number(am->getNumberOfTuples()), dc->getName(), QString::number(geometry->getNumberOfElements())); - setErrorCondition(-3011, ss); - return; - } - m_PartitionImageGeometryResult = createPartitioningSchemeGeometry(*geometry); + dataCheckPartitioningMode(); + dc->createAndAddAttributeMatrix({0}, m_FeatureAttributeMatrixName, AttributeMatrix::Type::CellFeature); break; } case IGeometry::Type::Vertex: { - VertexGeom::Pointer geometry = dc->getGeometryAs(); - SharedVertexList::Pointer vertexList = geometry->getVertices(); - if(am->getNumberOfTuples() != vertexList->getNumberOfTuples()) - { - QString ss = QObject::tr("The attribute matrix \"%1\" does not have the same tuple count (%2) as data container \"%3\"'s vertex count (%4).") - .arg(am->getName(), QString::number(am->getNumberOfTuples()), dc->getName(), QString::number(vertexList->getNumberOfTuples())); - setErrorCondition(-3012, ss); - return; - } - m_PartitionImageGeometryResult = createPartitioningSchemeGeometry(*geometry); + dataCheckPartitioningMode(); + dc->createAndAddAttributeMatrix({0}, m_FeatureAttributeMatrixName, AttributeMatrix::Type::VertexFeature); break; } case IGeometry::Type::Edge: { - EdgeGeom::Pointer geometry = dc->getGeometryAs(); - SharedVertexList::Pointer vertexList = geometry->getVertices(); - if(am->getNumberOfTuples() != vertexList->getNumberOfTuples()) - { - QString ss = QObject::tr("The attribute matrix \"%1\" does not have the same tuple count (%2) as data container \"%3\"'s vertex count (%4).") - .arg(am->getName(), QString::number(am->getNumberOfTuples()), dc->getName(), QString::number(vertexList->getNumberOfTuples())); - setErrorCondition(-3013, ss); - return; - } - m_PartitionImageGeometryResult = createPartitioningSchemeGeometry(*geometry); + dataCheckPartitioningMode(); + dc->createAndAddAttributeMatrix({0}, m_FeatureAttributeMatrixName, AttributeMatrix::Type::VertexFeature); break; } case IGeometry::Type::Triangle: { - TriangleGeom::Pointer geometry = dc->getGeometryAs(); - SharedVertexList::Pointer vertexList = geometry->getVertices(); - if(am->getNumberOfTuples() != vertexList->getNumberOfTuples()) - { - QString ss = QObject::tr("The attribute matrix \"%1\" does not have the same tuple count (%2) as data container \"%3\"'s vertex count (%4).") - .arg(am->getName(), QString::number(am->getNumberOfTuples()), dc->getName(), QString::number(vertexList->getNumberOfTuples())); - setErrorCondition(-3014, ss); - return; - } - m_PartitionImageGeometryResult = createPartitioningSchemeGeometry(*geometry); + dataCheckPartitioningMode(); + dc->createAndAddAttributeMatrix({0}, m_FeatureAttributeMatrixName, AttributeMatrix::Type::VertexFeature); break; } case IGeometry::Type::Quad: { - QuadGeom::Pointer geometry = dc->getGeometryAs(); - SharedVertexList::Pointer vertexList = geometry->getVertices(); - if(am->getNumberOfTuples() != vertexList->getNumberOfTuples()) - { - QString ss = QObject::tr("The attribute matrix \"%1\" does not have the same tuple count (%2) as data container \"%3\"'s vertex count (%4).") - .arg(am->getName(), QString::number(am->getNumberOfTuples()), dc->getName(), QString::number(vertexList->getNumberOfTuples())); - setErrorCondition(-3015, ss); - return; - } - m_PartitionImageGeometryResult = createPartitioningSchemeGeometry(*geometry); + dataCheckPartitioningMode(); + dc->createAndAddAttributeMatrix({0}, m_FeatureAttributeMatrixName, AttributeMatrix::Type::VertexFeature); break; } case IGeometry::Type::Tetrahedral: { - TetrahedralGeom::Pointer geometry = dc->getGeometryAs(); - SharedVertexList::Pointer vertexList = geometry->getVertices(); - if(am->getNumberOfTuples() != vertexList->getNumberOfTuples()) - { - QString ss = QObject::tr("The attribute matrix \"%1\" does not have the same tuple count (%2) as data container \"%3\"'s vertex count (%4).") - .arg(am->getName(), QString::number(am->getNumberOfTuples()), dc->getName(), QString::number(vertexList->getNumberOfTuples())); - setErrorCondition(-3016, ss); - return; - } - m_PartitionImageGeometryResult = createPartitioningSchemeGeometry(*geometry); + dataCheckPartitioningMode(); + dc->createAndAddAttributeMatrix({0}, m_FeatureAttributeMatrixName, AttributeMatrix::Type::VertexFeature); break; } case IGeometry::Type::Hexahedral: { - HexahedralGeom::Pointer geometry = dc->getGeometryAs(); - SharedVertexList::Pointer vertexList = geometry->getVertices(); - if(am->getNumberOfTuples() != vertexList->getNumberOfTuples()) - { - QString ss = QObject::tr("The attribute matrix \"%1\" does not have the same tuple count (%2) as data container \"%3\"'s vertex count (%4).") - .arg(am->getName(), QString::number(am->getNumberOfTuples()), dc->getName(), QString::number(vertexList->getNumberOfTuples())); - setErrorCondition(-3017, ss); - return; - } - m_PartitionImageGeometryResult = createPartitioningSchemeGeometry(*geometry); + dataCheckPartitioningMode(); + dc->createAndAddAttributeMatrix({0}, m_FeatureAttributeMatrixName, AttributeMatrix::Type::VertexFeature); break; } default: { QString ss = QObject::tr("Unable to partition geometry - Unknown geometry type detected."); - setErrorCondition(-3018, ss); + setErrorCondition(-3001, ss); return; } } - if(getErrorCode() < 0) + if(getErrorCode() != 0) { return; } - std::vector cDims(1, 1); - DataArrayPath tempPath = DataArrayPath(m_AttributeMatrixPath.getDataContainerName(), m_AttributeMatrixPath.getAttributeMatrixName(), getPartitionIdsArrayName()); - m_PartitionIdsPtr = getDataContainerArray()->createNonPrereqArrayFromPath(this, tempPath, 0, cDims); - if(nullptr != m_PartitionIdsPtr.lock()) + if(m_UseVertexMask) { - m_PartitionIds = m_PartitionIdsPtr.lock()->getPointer(0); - } /* Now assign the raw pointer to data from the DataArray object */ + getDataContainerArray()->getPrereqArrayFromPath(this, m_VertexMaskPath, {1}); + if(getErrorCode() != 0) + { + return; + } + } if(m_SavePartitioningScheme) { DataContainer::Pointer ps_dc = getDataContainerArray()->createNonPrereqDataContainer(this, m_PSDataContainerPath, PartitionSchemeDataContainerID); - if(getErrorCode() < 0) + if(getErrorCode() != 0) { return; } @@ -542,13 +509,13 @@ void PartitionGeometry::dataCheck() DataArrayPath dap = m_PSDataContainerPath; dap.setAttributeMatrixName(m_PSAttributeMatrixName); AttributeMatrix::Pointer ps_am = ps_dc->createNonPrereqAttributeMatrix(this, dap, m_NumberOfPartitionsPerAxis.convertType(), AttributeMatrix::Type::Cell, PartitionSchemeAttributeMatrixID); - if(getErrorCode() < 0) + if(getErrorCode() != 0) { return; } - m_PartitioningSchemeIdsPtr = ps_am->createNonPrereqArray(this, m_PSDataArrayName, 0, cDims, PartitionSchemeDataArrayID); - if(getErrorCode() < 0) + m_PartitioningSchemeIdsPtr = ps_am->createNonPrereqArray(this, m_PSDataArrayName, 0, {1}, PartitionSchemeDataArrayID); + if(getErrorCode() != 0) { return; } @@ -558,28 +525,291 @@ void PartitionGeometry::dataCheck() m_PartitioningSchemeIds = m_PartitioningSchemeIdsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ } + + DataArrayPath tempPath = DataArrayPath(m_AttributeMatrixPath.getDataContainerName(), m_AttributeMatrixPath.getAttributeMatrixName(), getPartitionIdsArrayName()); + m_PartitionIdsPtr = getDataContainerArray()->createNonPrereqArrayFromPath(this, tempPath, 0, {1}); + if(nullptr != m_PartitionIdsPtr.lock()) + { + m_PartitionIds = m_PartitionIdsPtr.lock()->getPointer(0); + } /* Now assign the raw pointer to data from the DataArray object */ } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -void PartitionGeometry::execute() +template +void PartitionGeometry::dataCheckPartitioningMode() { - initialize(); - dataCheck(); - if(getErrorCode() < 0) + switch(static_cast(m_PartitioningMode)) + { + case PartitioningMode::Basic: + dataCheckBasicMode(); + break; + case PartitioningMode::Advanced: + dataCheckAdvancedMode(); + break; + case PartitioningMode::BoundingBox: + dataCheckBoundingBoxMode(); + break; + case PartitioningMode::ExistingPartitioningScheme: + dataCheckExistingGeometryMode(); + break; + } + + if(getErrorCode() != 0) + { + return; + } +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +template +void PartitionGeometry::dataCheckBasicMode() +{ + dataCheckNumberOfPartitions(); + if(getErrorCode() != 0) + { + return; + } + + dataCheckPartitioningScheme(); + if(getErrorCode() != 0) + { + return; + } +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +template +void PartitionGeometry::dataCheckAdvancedMode() +{ + dataCheckNumberOfPartitions(); + if(getErrorCode() != 0) + { + return; + } + + if(m_LengthPerPartition.getX() < 0) + { + QString ss = QObject::tr("Length Per Partition: The X value cannot be negative."); + setErrorCondition(-3003, ss); + return; + } + if(m_LengthPerPartition.getY() < 0) + { + QString ss = QObject::tr("Length Per Partition: The Y value cannot be negative."); + setErrorCondition(-3004, ss); + return; + } + if(m_LengthPerPartition.getZ() < 0) + { + QString ss = QObject::tr("Length Per Partition: The Z value cannot be negative."); + setErrorCondition(-3005, ss); + return; + } + + dataCheckPartitioningScheme(); + if(getErrorCode() != 0) + { + return; + } +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +template +void PartitionGeometry::dataCheckBoundingBoxMode() +{ + dataCheckNumberOfPartitions(); + if(getErrorCode() != 0) + { + return; + } + + if(m_LowerLeftCoord.getX() > m_UpperRightCoord.getX()) + { + QString ss = QObject::tr("Lower Left Coordinate: X value is larger than the upper right coordinate X value."); + setErrorCondition(-3006, ss); + return; + } + + if(m_LowerLeftCoord.getY() > m_UpperRightCoord.getY()) { + QString ss = QObject::tr("Lower Left Coordinate: Y value is larger than the upper right coordinate Y value."); + setErrorCondition(-3007, ss); return; } - std::optional outOfBoundsValue = {}; - if(static_cast(m_PartitioningMode) == PartitioningMode::Advanced) + if(m_LowerLeftCoord.getZ() > m_UpperRightCoord.getZ()) + { + QString ss = QObject::tr("Lower Left Coordinate: Z value is larger than the upper right coordinate Z value."); + setErrorCondition(-3008, ss); + return; + } + + dataCheckPartitioningScheme(); + if(getErrorCode() != 0) + { + return; + } +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void PartitionGeometry::dataCheckExistingGeometryMode() +{ + DataContainer::Pointer existingDC = getDataContainerArray()->getPrereqDataContainer(this, m_PartitioningSchemeDataContainerName.getDataContainerName()); + if(getErrorCode() != 0) { - outOfBoundsValue = m_AdvancedOutOfBoundsValue; + return; } - else if(static_cast(m_PartitioningMode) == PartitioningMode::BoundingBox) + + ImageGeom::Pointer existingGeom = existingDC->getPrereqGeometry(this); + if(getErrorCode() != 0) { - outOfBoundsValue = m_BoundingBoxOutOfBoundsValue; + return; + } + + m_PartitionImageGeometryResult = {existingGeom, {}}; +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +template +void PartitionGeometry::dataCheckPartitioningScheme() +{ + DataContainer::Pointer dc = getDataContainerArray()->getDataContainer(m_AttributeMatrixPath.getDataContainerName()); + AttributeMatrix::Pointer am = dc->getAttributeMatrix(m_AttributeMatrixPath.getAttributeMatrixName()); + + typename GeomType::Pointer geometry = dc->getGeometryAs(); + if constexpr(std::is_same_v || std::is_same_v) + { + if(am->getNumberOfTuples() != geometry->getNumberOfElements()) + { + QString ss = QObject::tr("The attribute matrix '%1' does not have the same tuple count (%2) as data container \"%3\"'s cell count (%4).") + .arg(am->getName(), QString::number(am->getNumberOfTuples()), dc->getName(), QString::number(geometry->getNumberOfElements())); + setErrorCondition(-3009, ss); + return; + } + } + else + { + SharedVertexList::Pointer vertexList = geometry->getVertices(); + if(am->getNumberOfTuples() != vertexList->getNumberOfTuples()) + { + QString ss = QObject::tr("The attribute matrix \"%1\" does not have the same tuple count (%2) as data container \"%3\"'s vertex count (%4).") + .arg(am->getName(), QString::number(am->getNumberOfTuples()), dc->getName(), QString::number(vertexList->getNumberOfTuples())); + setErrorCondition(-3010, ss); + return; + } + } + + createPartitioningSchemeGeometry(*geometry); + if(getErrorCode() != 0) + { + return; + } +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +template +void PartitionGeometry::createPartitioningSchemeGeometry(const GeomType& geometry) +{ + ImageGeom::Pointer partitionImageGeometry = ImageGeom::CreateGeometry(m_PSImageGeomName); + partitionImageGeometry->setDimensions(m_NumberOfPartitionsPerAxis.convertType()); + partitionImageGeometry->setOrigin({0, 0, 0}); + partitionImageGeometry->setSpacing({0, 0, 0}); + + PartitionGeometry::PartitioningMode partitioningMode = static_cast(m_PartitioningMode); + switch(partitioningMode) + { + case PartitionGeometry::PartitioningMode::Basic: + { + Detail::InitResult result = Detail::InitSimplePartitioningGeometry(geometry, *partitionImageGeometry, m_NumberOfPartitionsPerAxis, getInPreflight()); + if(result.errorCode < 0) + { + setErrorCondition(result.errorCode, *result.message); + return; + } + + m_PartitionImageGeometryResult = {partitionImageGeometry, result.message}; + break; + } + case PartitionGeometry::PartitioningMode::Advanced: + { + partitionImageGeometry->setOrigin(m_PartitioningSchemeOrigin); + partitionImageGeometry->setSpacing(m_LengthPerPartition); + m_PartitionImageGeometryResult = {partitionImageGeometry, {}}; + break; + } + case PartitionGeometry::PartitioningMode::BoundingBox: + { + Detail::InitResult result = Detail::InitPartitioningGeometryUsingBoundingBox(*partitionImageGeometry, m_NumberOfPartitionsPerAxis, m_LowerLeftCoord, m_UpperRightCoord, getInPreflight()); + if(result.errorCode < 0) + { + setErrorCondition(result.errorCode, *result.message); + return; + } + + m_PartitionImageGeometryResult = {partitionImageGeometry, result.message}; + break; + } + default: + { + QString ss = QObject::tr("Unable to create partitioning scheme geometry - Unknown partitioning mode."); + setErrorCondition(-3011, ss); + m_PartitionImageGeometryResult = {partitionImageGeometry, ss}; + break; + } + } +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void PartitionGeometry::dataCheckNumberOfPartitions() +{ + if(m_NumberOfPartitionsPerAxis.getX() <= 0) + { + QString ss = QObject::tr("Number of Partitions Per Axis: The X dimension must be greater than 0."); + setErrorCondition(-3012, ss); + return; + } + + if(m_NumberOfPartitionsPerAxis.getY() <= 0) + { + QString ss = QObject::tr("Number of Partitions Per Axis: The Y dimension must be greater than 0."); + setErrorCondition(-3013, ss); + return; + } + + if(m_NumberOfPartitionsPerAxis.getZ() <= 0) + { + QString ss = QObject::tr("Number of Partitions Per Axis: The Z dimension must be greater than 0."); + setErrorCondition(-3014, ss); + return; + } +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void PartitionGeometry::execute() +{ + initialize(); + dataCheck(); + if(getErrorCode() != 0) + { + return; } Int32ArrayType::Pointer partitionIdsPtr = m_PartitionIdsPtr.lock(); @@ -591,61 +821,61 @@ void PartitionGeometry::execute() case IGeometry::Type::Image: { ImageGeom::Pointer geometry = dc->getGeometryAs(); - partitionCellBasedGeometry(*geometry, *partitionIdsPtr, outOfBoundsValue); + partitionCellBasedGeometry(*geometry, *partitionIdsPtr, m_OutOfBoundsValue); break; } case IGeometry::Type::RectGrid: { RectGridGeom::Pointer geometry = dc->getGeometryAs(); - partitionCellBasedGeometry(*geometry, *partitionIdsPtr, outOfBoundsValue); + partitionCellBasedGeometry(*geometry, *partitionIdsPtr, m_OutOfBoundsValue); break; } case IGeometry::Type::Vertex: { VertexGeom::Pointer geometry = dc->getGeometryAs(); SharedVertexList::Pointer vertexList = geometry->getVertices(); - partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, outOfBoundsValue); + partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, m_OutOfBoundsValue); break; } case IGeometry::Type::Edge: { EdgeGeom::Pointer geometry = dc->getGeometryAs(); SharedVertexList::Pointer vertexList = geometry->getVertices(); - partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, outOfBoundsValue); + partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, m_OutOfBoundsValue); break; } case IGeometry::Type::Triangle: { TriangleGeom::Pointer geometry = dc->getGeometryAs(); SharedVertexList::Pointer vertexList = geometry->getVertices(); - partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, outOfBoundsValue); + partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, m_OutOfBoundsValue); break; } case IGeometry::Type::Quad: { QuadGeom::Pointer geometry = dc->getGeometryAs(); SharedVertexList::Pointer vertexList = geometry->getVertices(); - partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, outOfBoundsValue); + partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, m_OutOfBoundsValue); break; } case IGeometry::Type::Tetrahedral: { TetrahedralGeom::Pointer geometry = dc->getGeometryAs(); SharedVertexList::Pointer vertexList = geometry->getVertices(); - partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, outOfBoundsValue); + partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, m_OutOfBoundsValue); break; } case IGeometry::Type::Hexahedral: { HexahedralGeom::Pointer geometry = dc->getGeometryAs(); SharedVertexList::Pointer vertexList = geometry->getVertices(); - partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, outOfBoundsValue); + partitionNodeBasedGeometry(geometry->getName(), *vertexList, *partitionIdsPtr, m_OutOfBoundsValue); break; } default: { QString ss = QObject::tr("Unable to partition geometry - Unknown geometry type detected."); - setErrorCondition(-3012, ss); + setErrorCondition(-3015, ss); return; } } @@ -662,48 +892,11 @@ void PartitionGeometry::execute() // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -template -PartitionGeometry::PartitioningImageGeomResult PartitionGeometry::createPartitioningSchemeGeometry(const T& geometry) -{ - ImageGeom::Pointer partitionImageGeometry = ImageGeom::CreateGeometry(m_PSImageGeomName); - partitionImageGeometry->setDimensions(m_NumberOfPartitionsPerAxis.convertType()); - partitionImageGeometry->setOrigin({0, 0, 0}); - partitionImageGeometry->setSpacing({0, 0, 0}); - - switch(static_cast(m_PartitioningMode)) - { - case PartitioningMode::Basic: - { - std::optional maybeErrMsg = Detail::InitSimplePartitioningGeometry(geometry, *partitionImageGeometry, m_NumberOfPartitionsPerAxis, getInPreflight()); - return {partitionImageGeometry, maybeErrMsg}; - } - case PartitioningMode::Advanced: - { - partitionImageGeometry->setOrigin(m_PartitioningSchemeOrigin); - partitionImageGeometry->setSpacing(m_LengthPerPartition); - return {partitionImageGeometry, {}}; - } - case PartitioningMode::BoundingBox: - { - std::optional maybeErrMsg = Detail::InitPartitioningGeometryUsingBoundingBox(*partitionImageGeometry, m_NumberOfPartitionsPerAxis, m_LowerLeftCoord, m_UpperRightCoord, getInPreflight()); - return {partitionImageGeometry, maybeErrMsg}; - } - default: - { - QString ss = QObject::tr("Unable to create partitioning scheme geometry - Unknown partitioning mode."); - setErrorCondition(-3011, ss); - return {partitionImageGeometry, ss}; - } - } -} - -// ----------------------------------------------------------------------------- -// -// ----------------------------------------------------------------------------- -void PartitionGeometry::partitionCellBasedGeometry(const IGeometryGrid& geometry, Int32ArrayType& partitionIds, const std::optional& outOfBoundsValue) +void PartitionGeometry::partitionCellBasedGeometry(const IGeometryGrid& geometry, Int32ArrayType& partitionIds, int outOfBoundsValue) { SizeVec3Type dims = geometry.getDimensions(); + size_t maxValue = 0; for(size_t z = 0; z < dims[2]; z++) { for(size_t y = 0; y < dims[1]; y++) @@ -717,51 +910,66 @@ void PartitionGeometry::partitionCellBasedGeometry(const IGeometryGrid& geometry auto partitionIndexResult = m_PartitionImageGeometryResult.first->getIndex(coord[0], coord[1], coord[2]); if(partitionIndexResult.has_value()) { - partitionIds.setValue(index, *partitionIndexResult + m_StartingPartitionID); - } - else if(outOfBoundsValue.has_value()) - { - partitionIds.setValue(index, *outOfBoundsValue); + int32_t partitionID = *partitionIndexResult + m_StartingPartitionID; + maxValue = partitionID > maxValue ? partitionID : maxValue; + partitionIds.setValue(index, partitionID); } else { - QString ss = QObject::tr("Coordinate (%1, %2, %3) is out-of-bounds of geometry '%4'.").arg(QString::number(x), QString::number(y), QString::number(z), geometry.getName()); - setErrorCondition(-3020, ss); - return; + partitionIds.setValue(index, outOfBoundsValue); } } } } + + AttributeMatrix::Pointer featureAM = getDataContainerArray()->getAttributeMatrix({m_AttributeMatrixPath.getDataContainerName(), m_FeatureAttributeMatrixName, ""}); + featureAM->setTupleDimensions({maxValue + 1}); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -void PartitionGeometry::partitionNodeBasedGeometry(const QString& geomName, const SharedVertexList& vertexList, Int32ArrayType& partitionIds, const std::optional& outOfBoundsValue) +void PartitionGeometry::partitionNodeBasedGeometry(const QString& geomName, const SharedVertexList& vertexList, Int32ArrayType& partitionIds, int outOfBoundsValue) { + BoolArrayType::Pointer maskPtr = BoolArrayType::NullPointer(); + bool* mask = nullptr; + if(m_UseVertexMask) + { + AttributeMatrix::Pointer am = getDataContainerArray()->getAttributeMatrix(m_VertexMaskPath); + maskPtr = am->getAttributeArrayAs(m_VertexMaskPath.getDataArrayName()); + mask = maskPtr->getPointer(0); + } size_t numOfVertices = vertexList.getNumberOfTuples(); float* vertexArray = vertexList.getPointer(0); + size_t maxValue = 0; for(size_t idx = 0; idx < numOfVertices; idx++) { - float x = vertexArray[idx * 3]; - float y = vertexArray[idx * 3 + 1]; - float z = vertexArray[idx * 3 + 2]; - auto partitionIndexResult = m_PartitionImageGeometryResult.first->getIndex(x, y, z); - if(partitionIndexResult.has_value()) + if(m_UseVertexMask && !mask[idx]) { - partitionIds.setValue(idx, *partitionIndexResult + m_StartingPartitionID); - } - else if(outOfBoundsValue.has_value()) - { - partitionIds.setValue(idx, *outOfBoundsValue); + partitionIds.setValue(idx, outOfBoundsValue); } else { - QString ss = QObject::tr("Coordinate (%1, %2, %3) is out-of-bounds of geometry '%4'.").arg(QString::number(x), QString::number(y), QString::number(z), geomName); - setErrorCondition(-3021, ss); - return; + float x = vertexArray[idx * 3]; + float y = vertexArray[idx * 3 + 1]; + float z = vertexArray[idx * 3 + 2]; + + auto partitionIndexResult = m_PartitionImageGeometryResult.first->getIndex(x, y, z); + if(partitionIndexResult.has_value()) + { + int32_t partitionID = *partitionIndexResult + m_StartingPartitionID; + maxValue = partitionID > maxValue ? partitionID : maxValue; + partitionIds.setValue(idx, partitionID); + } + else + { + partitionIds.setValue(idx, outOfBoundsValue); + } } } + + AttributeMatrix::Pointer featureAM = getDataContainerArray()->getAttributeMatrix({m_AttributeMatrixPath.getDataContainerName(), m_FeatureAttributeMatrixName, ""}); + featureAM->setTupleDimensions({maxValue + 1}); } // ----------------------------------------------------------------------------- @@ -962,27 +1170,27 @@ IntVec3Type PartitionGeometry::getNumberOfPartitionsPerAxis() const } // ----------------------------------------------------------------------------- -void PartitionGeometry::setAdvancedOutOfBoundsValue(const int& value) +void PartitionGeometry::setOutOfBoundsValue(const int& value) { - m_AdvancedOutOfBoundsValue = value; + m_OutOfBoundsValue = value; } // ----------------------------------------------------------------------------- -int PartitionGeometry::getAdvancedOutOfBoundsValue() const +int PartitionGeometry::getOutOfBoundsValue() const { - return m_AdvancedOutOfBoundsValue; + return m_OutOfBoundsValue; } // ----------------------------------------------------------------------------- -void PartitionGeometry::setBoundingBoxOutOfBoundsValue(const int& value) +void PartitionGeometry::setPartitioningSchemeDataContainerName(const DataArrayPath& value) { - m_BoundingBoxOutOfBoundsValue = value; + m_PartitioningSchemeDataContainerName = value; } // ----------------------------------------------------------------------------- -int PartitionGeometry::getBoundingBoxOutOfBoundsValue() const +DataArrayPath PartitionGeometry::getPartitioningSchemeDataContainerName() const { - return m_BoundingBoxOutOfBoundsValue; + return m_PartitioningSchemeDataContainerName; } // ----------------------------------------------------------------------------- @@ -1033,6 +1241,30 @@ QString PartitionGeometry::getPSAttributeMatrixName() const return m_PSAttributeMatrixName; } +// ----------------------------------------------------------------------------- +void PartitionGeometry::setUseVertexMask(const bool& value) +{ + m_UseVertexMask = value; +} + +// ----------------------------------------------------------------------------- +bool PartitionGeometry::getUseVertexMask() const +{ + return m_UseVertexMask; +} + +// ----------------------------------------------------------------------------- +void PartitionGeometry::setVertexMaskPath(const DataArrayPath& value) +{ + m_VertexMaskPath = value; +} + +// ----------------------------------------------------------------------------- +DataArrayPath PartitionGeometry::getVertexMaskPath() const +{ + return m_VertexMaskPath; +} + // ----------------------------------------------------------------------------- QString PartitionGeometry::getInputGeometryInformation() const { @@ -1090,12 +1322,13 @@ QString PartitionGeometry::getPartitioningSchemeInformation() const FloatVec3Type partitioningSchemeOrigin = m_PartitionImageGeometryResult.first->getOrigin(); FloatVec3Type lengthPerPartition = m_PartitionImageGeometryResult.first->getSpacing(); - float xRangeMax = (partitioningSchemeOrigin[0] + (m_NumberOfPartitionsPerAxis[0] * lengthPerPartition[0])); - float xDelta = m_NumberOfPartitionsPerAxis[0] * lengthPerPartition[0]; - float yRangeMax = (partitioningSchemeOrigin[1] + (m_NumberOfPartitionsPerAxis[1] * lengthPerPartition[1])); - float yDelta = m_NumberOfPartitionsPerAxis[1] * lengthPerPartition[1]; - float zRangeMax = (partitioningSchemeOrigin[2] + (m_NumberOfPartitionsPerAxis[2] * lengthPerPartition[2])); - float zDelta = m_NumberOfPartitionsPerAxis[2] * lengthPerPartition[2]; + SizeVec3Type numberOfPartitionsPerAxis = m_PartitionImageGeometryResult.first->getDimensions(); + float xRangeMax = (partitioningSchemeOrigin[0] + (numberOfPartitionsPerAxis[0] * lengthPerPartition[0])); + float xDelta = numberOfPartitionsPerAxis[0] * lengthPerPartition[0]; + float yRangeMax = (partitioningSchemeOrigin[1] + (numberOfPartitionsPerAxis[1] * lengthPerPartition[1])); + float yDelta = numberOfPartitionsPerAxis[1] * lengthPerPartition[1]; + float zRangeMax = (partitioningSchemeOrigin[2] + (numberOfPartitionsPerAxis[2] * lengthPerPartition[2])); + float zDelta = numberOfPartitionsPerAxis[2] * lengthPerPartition[2]; DataContainer::Pointer dc = getDataContainerArray()->getDataContainer(m_AttributeMatrixPath.getDataContainerName()); if(dc == DataContainer::NullPointer()) @@ -1150,6 +1383,18 @@ QString PartitionGeometry::getPartitioningSchemeInformation() const return desc; } +// ----------------------------------------------------------------------------- +void PartitionGeometry::setFeatureAttributeMatrixName(const QString& value) +{ + m_FeatureAttributeMatrixName = value; +} + +// ----------------------------------------------------------------------------- +QString PartitionGeometry::getFeatureAttributeMatrixName() const +{ + return m_FeatureAttributeMatrixName; +} + // ----------------------------------------------------------------------------- void PartitionGeometry::setPartitionIdsArrayName(const QString& value) { diff --git a/Source/Plugins/Reconstruction/ReconstructionFilters/PartitionGeometry.h b/Source/Plugins/Reconstruction/ReconstructionFilters/PartitionGeometry.h index 89d44af692..2e1e082ff5 100644 --- a/Source/Plugins/Reconstruction/ReconstructionFilters/PartitionGeometry.h +++ b/Source/Plugins/Reconstruction/ReconstructionFilters/PartitionGeometry.h @@ -60,11 +60,12 @@ class Reconstruction_EXPORT PartitionGeometry : public AbstractFilter PYB11_PROPERTY(FloatVec3Type PartitioningSchemeOrigin READ getPartitioningSchemeOrigin WRITE setPartitioningSchemeOrigin) PYB11_PROPERTY(FloatVec3Type LengthPerPartition READ getLengthPerPartition WRITE setLengthPerPartition) PYB11_PROPERTY(IntVec3Type NumberOfPartitionsPerAxis READ getNumberOfPartitionsPerAxis WRITE setNumberOfPartitionsPerAxis) - PYB11_PROPERTY(int AdvancedOutOfBoundsValue READ getAdvancedOutOfBoundsValue WRITE setAdvancedOutOfBoundsValue) - PYB11_PROPERTY(int BoundingBoxOutOfBoundsValue READ getBoundingBoxOutOfBoundsValue WRITE setBoundingBoxOutOfBoundsValue) + PYB11_PROPERTY(int OutOfBoundsValue READ getOutOfBoundsValue WRITE setOutOfBoundsValue) PYB11_PROPERTY(int StartingPartitionID READ getStartingPartitionID WRITE setStartingPartitionID) + PYB11_PROPERTY(DataArrayPath PartitioningSchemeDataContainerName READ getPartitioningSchemeDataContainerName WRITE setPartitioningSchemeDataContainerName) PYB11_PROPERTY(QString InputGeometryInformation READ getInputGeometryInformation) PYB11_PROPERTY(QString PartitioningSchemeInformation READ getPartitioningSchemeInformation) + PYB11_PROPERTY(QString FeatureAttributeMatrixName READ getFeatureAttributeMatrixName WRITE setFeatureAttributeMatrixName) PYB11_PROPERTY(QString PartitionIdsArrayName READ getPartitionIdsArrayName WRITE setPartitionIdsArrayName) PYB11_PROPERTY(bool SavePartitioningScheme READ getSavePartitioningScheme WRITE setSavePartitioningScheme) PYB11_PROPERTY(DataArrayPath PSDataContainerPath READ getPSDataContainerPath WRITE setPSDataContainerPath) @@ -77,7 +78,8 @@ class Reconstruction_EXPORT PartitionGeometry : public AbstractFilter { Basic = 0, Advanced = 1, - BoundingBox = 2 + BoundingBox = 2, + ExistingPartitioningScheme = 3 }; using Self = PartitionGeometry; @@ -190,26 +192,26 @@ class Reconstruction_EXPORT PartitionGeometry : public AbstractFilter Q_PROPERTY(IntVec3Type NumberOfPartitionsPerAxis READ getNumberOfPartitionsPerAxis WRITE setNumberOfPartitionsPerAxis) /** - * @brief Setter property for AdvancedOutOfBoundsValue + * @brief Setter property for OutOfBoundsValue */ - void setAdvancedOutOfBoundsValue(const int& value); + void setOutOfBoundsValue(const int& value); /** - * @brief Getter property for AdvancedOutOfBoundsValue - * @return Value of AdvancedOutOfBoundsValue + * @brief Getter property for OutOfBoundsValue + * @return Value of OutOfBoundsValue */ - int getAdvancedOutOfBoundsValue() const; - Q_PROPERTY(int AdvancedOutOfBoundsValue READ getAdvancedOutOfBoundsValue WRITE setAdvancedOutOfBoundsValue) + int getOutOfBoundsValue() const; + Q_PROPERTY(int OutOfBoundsValue READ getOutOfBoundsValue WRITE setOutOfBoundsValue) /** - * @brief Setter property for BoundingBoxOutOfBoundsValue + * @brief Setter property for PartitioningSchemeDataContainerName */ - void setBoundingBoxOutOfBoundsValue(const int& value); + void setPartitioningSchemeDataContainerName(const DataArrayPath& value); /** - * @brief Getter property for BoundingBoxOutOfBoundsValue - * @return Value of BoundingBoxOutOfBoundsValue + * @brief Getter property for PartitioningSchemeDataContainerName + * @return Value of PartitioningSchemeDataContainerName */ - int getBoundingBoxOutOfBoundsValue() const; - Q_PROPERTY(int BoundingBoxOutOfBoundsValue READ getBoundingBoxOutOfBoundsValue WRITE setBoundingBoxOutOfBoundsValue) + DataArrayPath getPartitioningSchemeDataContainerName() const; + Q_PROPERTY(DataArrayPath PartitioningSchemeDataContainerName READ getPartitioningSchemeDataContainerName WRITE setPartitioningSchemeDataContainerName) /** * @brief Setter property for StartingPartitionID @@ -236,6 +238,17 @@ class Reconstruction_EXPORT PartitionGeometry : public AbstractFilter QString getPartitioningSchemeInformation() const; Q_PROPERTY(QString PartitioningSchemeInformation READ getPartitioningSchemeInformation) + /** + * @brief Setter property for FeatureAttributeMatrixName + */ + void setFeatureAttributeMatrixName(const QString& value); + /** + * @brief Getter property for FeatureAttributeMatrixName + * @return Value of FeatureAttributeMatrixName + */ + QString getFeatureAttributeMatrixName() const; + Q_PROPERTY(QString FeatureAttributeMatrixName READ getFeatureAttributeMatrixName WRITE setFeatureAttributeMatrixName) + /** * @brief Setter property for PartitionIdsArrayName */ @@ -281,6 +294,29 @@ class Reconstruction_EXPORT PartitionGeometry : public AbstractFilter QString getPSAttributeMatrixName() const; Q_PROPERTY(QString PSAttributeMatrixName READ getPSAttributeMatrixName WRITE setPSAttributeMatrixName) + /** + * @brief Setter property for UseVertexMask + */ + void setUseVertexMask(const bool& value); + + /** + * @brief Getter property for UseVertexMask + * @return Value of UseVertexMask + */ + bool getUseVertexMask() const; + Q_PROPERTY(bool UseVertexMask READ getUseVertexMask WRITE setUseVertexMask) + + /** + * @brief Setter property for VertexMaskPath + */ + void setVertexMaskPath(const DataArrayPath& value); + /** + * @brief Getter property for VertexMaskPath + * @return Value of VertexMaskPath + */ + DataArrayPath getVertexMaskPath() const; + Q_PROPERTY(DataArrayPath VertexMaskPath READ getVertexMaskPath WRITE setVertexMaskPath) + /** * @brief getCompiledLibraryName Reimplemented from @see AbstractFilter class */ @@ -364,35 +400,138 @@ class Reconstruction_EXPORT PartitionGeometry : public AbstractFilter QString m_PSAttributeMatrixName = {"CellData"}; QString m_PSDataArrayName = m_PartitionIdsArrayName; QString m_PSImageGeomName = {"PartitioningSchemeImageGeom"}; - int m_AdvancedOutOfBoundsValue = 0; - int m_BoundingBoxOutOfBoundsValue = 0; + int m_OutOfBoundsValue = 0; int m_StartingPartitionID = 1; + DataArrayPath m_PartitioningSchemeDataContainerName = {"", "", ""}; DataArrayPath m_AttributeMatrixPath = {"", "", ""}; + QString m_FeatureAttributeMatrixName = {"FeatureData"}; // DataArrayPath m_BoundingBoxPath = {"", "", ""}; + bool m_UseVertexMask = {false}; + DataArrayPath m_VertexMaskPath = {"", "", ""}; - std::weak_ptr m_BoundingBoxPtr; - float* m_BoundingBox = nullptr; std::weak_ptr m_PartitionIdsPtr; int32_t* m_PartitionIds = nullptr; std::weak_ptr m_PartitioningSchemeIdsPtr; int32_t* m_PartitioningSchemeIds = nullptr; PartitioningImageGeomResult m_PartitionImageGeometryResult; + /** + * @brief getInputImageGeometryInformation Helper method that returns displayable image geometry preflight information + */ QString getInputImageGeometryInformation(const ImageGeom& geometry) const; + + /** + * @brief getInputRectGridGeometryInformation Helper method that returns displayable rectilinear grid geometry preflight information + */ QString getInputRectGridGeometryInformation() const; + + /** + * @brief getInputVertexGeometryInformation Helper method that returns displayable vertex geometry preflight information + */ QString getInputVertexGeometryInformation() const; + + /** + * @brief getInputEdgeGeometryInformation Helper method that returns displayable edge geometry preflight information + */ QString getInputEdgeGeometryInformation() const; + + /** + * @brief getInputTriangleGeometryInformation Helper method that returns displayable triangle geometry preflight information + */ QString getInputTriangleGeometryInformation() const; + + /** + * @brief getInputQuadGeometryInformation Helper method that returns displayable quad geometry preflight information + */ QString getInputQuadGeometryInformation() const; + + /** + * @brief getInputTetrahedralGeometryInformation Helper method that returns displayable tetrahedral geometry preflight information + */ QString getInputTetrahedralGeometryInformation() const; + + /** + * @brief getInputHexahedralGeometryInformation Helper method that returns displayable hexahedral geometry preflight information + */ QString getInputHexahedralGeometryInformation() const; + + /** + * @brief getInputUnknownGeometryInformation Helper method that returns displayable unknown geometry preflight information + */ QString getInputUnknownGeometryInformation() const; - template - PartitioningImageGeomResult createPartitioningSchemeGeometry(const T& geometry); + /** + * @brief dataCheckPartitioningMode Helper method that data checks variables depending on the partitioning mode that is selected. + * This method also creates the partitioning scheme geometry if the selected partitioning mode requires one to be created. + */ + template + void dataCheckPartitioningMode(); + + /** + * @brief dataCheckBasicMode Helper method that data checks variables that the Basic partitioning mode depends on. + * This method also creates the partitioning scheme geometry using the Basic partitioning mode inputs. + */ + template + void dataCheckBasicMode(); + + /** + * @brief dataCheckAdvancedMode Helper method that data checks variables that the Advanced partitioning mode depends on. + * This method also creates the partitioning scheme geometry using the Advanced partitioning mode inputs. + */ + template + void dataCheckAdvancedMode(); - void partitionCellBasedGeometry(const IGeometryGrid& geometry, Int32ArrayType& partitionIds, const std::optional &outOfBoundsValue); - void partitionNodeBasedGeometry(const QString &geomName, const SharedVertexList& vertexList, Int32ArrayType& partitionIds, const std::optional &outOfBoundsValue); + /** + * @brief dataCheckBoundingBoxMode Helper method that data checks variables that the Bounding Box partitioning mode depends on. + * This method also creates the partitioning scheme geometry using the Bounding Box partitioning mode inputs. + */ + template + void dataCheckBoundingBoxMode(); + + /** + * @brief dataCheckExistingGeometryMode Helper method that data checks variables that the Existing Geometry partitioning mode depends on. + * The Existing Geometry partitioning mode provides its own partitioning scheme geometry, so this method simply uses this geometry instead + * of creating a new geometry. + */ + void dataCheckExistingGeometryMode(); + + /** + * @brief dataCheckNumberOfPartitions Helper method that data checks the Number Of Partitions Per Axis variable. + */ + void dataCheckNumberOfPartitions(); + + /** + * @brief dataCheckPartitioningScheme Helper method that checks that the number of elements (for cell-based geometries) or number of vertices + * (for node-based geometries) in the input geometry matches the number of tuples in the input attribute matrix. Then it calls + * createPartitioningSchemeGeometry to create the new partitioning scheme. + * @return + */ + template + void dataCheckPartitioningScheme(); + + /** + * @brief createPartitioningSchemeGeometry Creates a partitioning scheme geometry from a given geometry type. + * The way this function creates the partitioning scheme geometry depends on which partitioning mode is selected. + * For the basic mode, it calls the InitSimplePartitioningGeometry helper method to initialize a basic partitioning + * scheme geometry. For the advanced mode, it sets the origin and spacing of the geometry using filter inputs. + * For the bounding box mode, it calls the InitPartitioningGeometryUsingBoundingBox helper method to initialize a + * partitioning scheme geometry using a bounding box. It then sets the PartitionImageGeometryResult class member + * variable with the results. + */ + template + void createPartitioningSchemeGeometry(const GeomType& geometry); + + /** + * @brief partitionCellBasedGeometry Partitions a cell based geometry and sets the results into the partitionIds array. + * If a given cell is located outside the partitioning scheme geometry, that cell will be labeled with the out-of-bounds value. + */ + void partitionCellBasedGeometry(const IGeometryGrid& geometry, Int32ArrayType& partitionIds, int outOfBoundsValue); + + /** + * @brief partitionNodeBasedGeometry Partitions a node based geometry and sets the results into the partitionIds array. + * If a given vertex is located outside the partitioning scheme geometry, that cell will be labeled with the out-of-bounds value. + */ + void partitionNodeBasedGeometry(const QString& geomName, const SharedVertexList& vertexList, Int32ArrayType& partitionIds, int outOfBoundsValue); public: PartitionGeometry(const PartitionGeometry&) = delete; // Copy Constructor Not Implemented diff --git a/Source/Plugins/Reconstruction/Test/PartitionGeometryTest.cpp b/Source/Plugins/Reconstruction/Test/PartitionGeometryTest.cpp index 53f233e2a0..06ef152a1b 100644 --- a/Source/Plugins/Reconstruction/Test/PartitionGeometryTest.cpp +++ b/Source/Plugins/Reconstruction/Test/PartitionGeometryTest.cpp @@ -53,8 +53,6 @@ class PartitionGeometryTest PartitionGeometryTest& operator=(const PartitionGeometryTest&) = delete; // Copy Assignment PartitionGeometryTest& operator=(PartitionGeometryTest&&) = delete; // Move Assignment - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestGeometry(PartitionGeometry::Pointer filter, const QString& inputFile, const DataArrayPath& arrayPath, const QString& exemplaryArrayName) { @@ -97,21 +95,61 @@ class PartitionGeometryTest } // ----------------------------------------------------------------------------- - // + void TestGeometryError(PartitionGeometry::Pointer filter, const QString& inputFile, const DataArrayPath& arrayPath, int expectedErrorCode) + { + DataContainerArray::Pointer dca = DataContainerArray::New(); + { + DataContainerReader::Pointer filter = DataContainerReader::New(); + DataContainerArrayProxy dcaProxy = filter->readDataContainerArrayStructure(inputFile); + filter->setInputFileDataContainerArrayProxy(dcaProxy); + filter->setInputFile(inputFile); + filter->setDataContainerArray(dca); + filter->execute(); + int err = filter->getErrorCode(); + DREAM3D_REQUIRE(err >= 0) + } + + filter->setDataContainerArray(dca); + filter->execute(); + int err = filter->getErrorCode(); + DREAM3D_REQUIRE(err == expectedErrorCode) + } + // ----------------------------------------------------------------------------- - void TestBasicGeometry(const QString& inputFile, const DataArrayPath& arrayPath, const IntVec3Type& numOfPartitionsPerAxis, const QString& exemplaryArrayName) + PartitionGeometry::Pointer CreateBasicPartitionGeometryFilter(const QString& inputFile, const DataArrayPath& arrayPath, const IntVec3Type& numOfPartitionsPerAxis, + PartitionGeometry::PartitioningMode partitioningMode, const std::optional& maskArrayPath) { PartitionGeometry::Pointer filter = PartitionGeometry::New(); - filter->setPartitioningMode(static_cast(PartitionGeometry::PartitioningMode::Basic)); + filter->setPartitioningMode(static_cast(partitioningMode)); filter->setNumberOfPartitionsPerAxis(numOfPartitionsPerAxis); filter->setAttributeMatrixPath(arrayPath); filter->setPartitionIdsArrayName(arrayPath.getDataArrayName()); + if(maskArrayPath.has_value()) + { + filter->setUseVertexMask(true); + filter->setVertexMaskPath(*maskArrayPath); + } + + return filter; + } + + // ----------------------------------------------------------------------------- + void TestBasicGeometry(const QString& inputFile, const DataArrayPath& arrayPath, const IntVec3Type& numOfPartitionsPerAxis, const QString& exemplaryArrayName, + const std::optional& maskArrayPath = {}) + { + PartitionGeometry::Pointer filter = CreateBasicPartitionGeometryFilter(inputFile, arrayPath, numOfPartitionsPerAxis, PartitionGeometry::PartitioningMode::Basic, maskArrayPath); TestGeometry(filter, inputFile, arrayPath, exemplaryArrayName); } // ----------------------------------------------------------------------------- - // + void TestBasicGeometryError(const QString& inputFile, const DataArrayPath& arrayPath, const IntVec3Type& numOfPartitionsPerAxis, int expectedErrorCode, + const std::optional& maskArrayPath = {}) + { + PartitionGeometry::Pointer filter = CreateBasicPartitionGeometryFilter(inputFile, arrayPath, numOfPartitionsPerAxis, PartitionGeometry::PartitioningMode::Basic, maskArrayPath); + TestGeometryError(filter, inputFile, arrayPath, expectedErrorCode); + } + // ----------------------------------------------------------------------------- void TestAdvancedGeometry(const QString& inputFile, const DataArrayPath& arrayPath, const IntVec3Type& numOfPartitionsPerAxis, const FloatVec3Type& partitioningSchemeOrigin, const FloatVec3Type& lengthPerPartition, const QString& exemplaryArrayName) @@ -127,8 +165,6 @@ class PartitionGeometryTest TestGeometry(filter, inputFile, arrayPath, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestBoundingBoxGeometry(const QString& inputFile, const DataArrayPath& arrayPath, const IntVec3Type& numOfPartitionsPerAxis, const FloatVec3Type& lowerLeftCoord, const FloatVec3Type& upperRightCoord, const QString& exemplaryArrayName) @@ -145,20 +181,28 @@ class PartitionGeometryTest } // ----------------------------------------------------------------------------- - // + void TestExistingPartitioningSchemeGeometry(const QString& inputFile, const DataArrayPath& arrayPath, const QString& exemplaryArrayName, const DataArrayPath& partitioningSchemeDCPath) + { + PartitionGeometry::Pointer filter = PartitionGeometry::New(); + filter->setPartitioningMode(static_cast(PartitionGeometry::PartitioningMode::ExistingPartitioningScheme)); + filter->setPartitioningSchemeDataContainerName(partitioningSchemeDCPath); + filter->setAttributeMatrixPath(arrayPath); + filter->setPartitionIdsArrayName(arrayPath.getDataArrayName()); + + TestGeometry(filter, inputFile, arrayPath, exemplaryArrayName); + } + // ----------------------------------------------------------------------------- void TestBasicImageGeometry() { QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryImageGeomIdsPath; IntVec3Type numOfPartitionsPerAxis = {5, 5, 5}; - DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitionIds"}; - QString exemplaryArrayName = "ExemplaryPartitionIds"; + DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitioningSchemeIds"}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestAdvancedImageGeometry() { @@ -166,14 +210,12 @@ class PartitionGeometryTest IntVec3Type numOfPartitionsPerAxis = {5, 5, 5}; FloatVec3Type partitioningSchemeOrigin = {-10, 5, 2}; FloatVec3Type lengthPerPartition = {5, 5, 5}; - DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitionIds"}; - QString exemplaryArrayName = "ExemplaryPartitionIds"; + DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitioningSchemeIds"}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; TestAdvancedGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, partitioningSchemeOrigin, lengthPerPartition, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestBoundingBoxImageGeometry() { @@ -181,27 +223,34 @@ class PartitionGeometryTest IntVec3Type numOfPartitionsPerAxis = {5, 5, 5}; FloatVec3Type lowerLeftCoord = {-10, 5, 2}; FloatVec3Type upperRightCoord = {15, 30, 27}; - DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitionIds"}; - QString exemplaryArrayName = "ExemplaryPartitionIds"; + DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitioningSchemeIds"}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; TestBoundingBoxGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, lowerLeftCoord, upperRightCoord, exemplaryArrayName); } // ----------------------------------------------------------------------------- - // + void TestExistingPartitioningSchemeImageGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryImageGeomIdsPath; + DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitioningSchemeIds"}; + DataArrayPath partitioningSchemeDCPath = {"PartitioningSchemeDataContainer", "", ""}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; + + TestExistingPartitioningSchemeGeometry(inputFile, arrayPath, exemplaryArrayName, partitioningSchemeDCPath); + } + // ----------------------------------------------------------------------------- void TestBasicRectGridGeometry() { QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryRectGridGeomIdsPath; IntVec3Type numOfPartitionsPerAxis = {5, 5, 5}; - DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitionIds"}; - QString exemplaryArrayName = "ExemplaryPartitionIds"; + DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitioningSchemeIds"}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestAdvancedRectGridGeometry() { @@ -209,14 +258,12 @@ class PartitionGeometryTest IntVec3Type numOfPartitionsPerAxis = {5, 5, 5}; FloatVec3Type partitioningSchemeOrigin = {0, 0, 0}; FloatVec3Type lengthPerPartition = {6, 6, 6}; - DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitionIds"}; - QString exemplaryArrayName = "ExemplaryPartitionIds"; + DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitioningSchemeIds"}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; TestAdvancedGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, partitioningSchemeOrigin, lengthPerPartition, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestBoundingBoxRectGridGeometry() { @@ -224,14 +271,23 @@ class PartitionGeometryTest IntVec3Type numOfPartitionsPerAxis = {5, 5, 5}; FloatVec3Type lowerLeftCoord = {0, 0, 0}; FloatVec3Type upperRightCoord = {30, 30, 30}; - DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitionIds"}; - QString exemplaryArrayName = "ExemplaryPartitionIds"; + DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitioningSchemeIds"}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; TestBoundingBoxGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, lowerLeftCoord, upperRightCoord, exemplaryArrayName); } // ----------------------------------------------------------------------------- - // + void TestExistingPartitioningSchemeRectGridGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryRectGridGeomIdsPath; + DataArrayPath arrayPath = {"DataContainer", "CellData", "PartitioningSchemeIds"}; + DataArrayPath partitioningSchemeDCPath = {"PartitioningSchemeDataContainer", "", ""}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; + + TestExistingPartitioningSchemeGeometry(inputFile, arrayPath, exemplaryArrayName, partitioningSchemeDCPath); + } + // ----------------------------------------------------------------------------- void TestBasicTriangleGeometry() { @@ -243,8 +299,6 @@ class PartitionGeometryTest TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestAdvancedTriangleGeometry() { @@ -258,8 +312,6 @@ class PartitionGeometryTest TestAdvancedGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, partitioningSchemeOrigin, lengthPerPartition, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestBoundingBoxTriangleGeometry() { @@ -274,7 +326,28 @@ class PartitionGeometryTest } // ----------------------------------------------------------------------------- - // + void TestExistingPartitioningSchemeTriangleGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryTriangleGeomIdsPath; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath partitioningSchemeDCPath = {"PartitioningSchemeDataContainer", "", ""}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; + + TestExistingPartitioningSchemeGeometry(inputFile, arrayPath, exemplaryArrayName, partitioningSchemeDCPath); + } + + // ----------------------------------------------------------------------------- + void TestMaskedTriangleGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryTriangleGeomIdsPath; + IntVec3Type numOfPartitionsPerAxis = {5, 4, 4}; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath maskPath = {"DataContainer", "VertexData", "Mask"}; + QString exemplaryArrayName = "MaskedExemplaryPartitioningSchemeIds"; + + TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName, maskPath); + } + // ----------------------------------------------------------------------------- void TestBasicEdgeGeometry() { @@ -286,8 +359,6 @@ class PartitionGeometryTest TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestAdvancedEdgeGeometry() { @@ -301,8 +372,6 @@ class PartitionGeometryTest TestAdvancedGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, partitioningSchemeOrigin, lengthPerPartition, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestBoundingBoxEdgeGeometry() { @@ -317,7 +386,28 @@ class PartitionGeometryTest } // ----------------------------------------------------------------------------- - // + void TestExistingPartitioningSchemeEdgeGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryEdgeGeomIdsPath; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath partitioningSchemeDCPath = {"PartitioningSchemeDataContainer", "", ""}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; + + TestExistingPartitioningSchemeGeometry(inputFile, arrayPath, exemplaryArrayName, partitioningSchemeDCPath); + } + + // ----------------------------------------------------------------------------- + void TestMaskedEdgeGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryEdgeGeomIdsPath; + IntVec3Type numOfPartitionsPerAxis = {4, 4, 4}; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath maskPath = {"DataContainer", "VertexData", "Mask"}; + QString exemplaryArrayName = "MaskedExemplaryPartitioningSchemeIds"; + + TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName, maskPath); + } + // ----------------------------------------------------------------------------- void TestBasicVertexGeometry() { @@ -329,8 +419,6 @@ class PartitionGeometryTest TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestAdvancedVertexGeometry() { @@ -344,8 +432,6 @@ class PartitionGeometryTest TestAdvancedGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, partitioningSchemeOrigin, lengthPerPartition, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestBoundingBoxVertexGeometry() { @@ -360,7 +446,28 @@ class PartitionGeometryTest } // ----------------------------------------------------------------------------- - // + void TestExistingPartitioningSchemeVertexGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryVertexGeomIdsPath; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath partitioningSchemeDCPath = {"PartitioningSchemeDataContainer", "", ""}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; + + TestExistingPartitioningSchemeGeometry(inputFile, arrayPath, exemplaryArrayName, partitioningSchemeDCPath); + } + + // ----------------------------------------------------------------------------- + void TestMaskedVertexGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryVertexGeomIdsPath; + IntVec3Type numOfPartitionsPerAxis = {20, 10, 5}; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath maskPath = {"DataContainer", "VertexData", "Mask"}; + QString exemplaryArrayName = "MaskedExemplaryPartitioningSchemeIds"; + + TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName, maskPath); + } + // ----------------------------------------------------------------------------- void TestBasicQuadGeometry() { @@ -372,8 +479,6 @@ class PartitionGeometryTest TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestAdvancedQuadGeometry() { @@ -387,8 +492,6 @@ class PartitionGeometryTest TestAdvancedGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, partitioningSchemeOrigin, lengthPerPartition, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestBoundingBoxQuadGeometry() { @@ -403,7 +506,28 @@ class PartitionGeometryTest } // ----------------------------------------------------------------------------- - // + void TestExistingPartitioningSchemeQuadGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryQuadGeomIdsPath; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath partitioningSchemeDCPath = {"PartitioningSchemeDataContainer", "", ""}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; + + TestExistingPartitioningSchemeGeometry(inputFile, arrayPath, exemplaryArrayName, partitioningSchemeDCPath); + } + + // ----------------------------------------------------------------------------- + void TestMaskedQuadGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryQuadGeomIdsPath; + IntVec3Type numOfPartitionsPerAxis = {10, 5, 3}; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath maskPath = {"DataContainer", "VertexData", "Mask"}; + QString exemplaryArrayName = "MaskedExemplaryPartitioningSchemeIds"; + + TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName, maskPath); + } + // ----------------------------------------------------------------------------- void TestBasicTetrahedralGeometry() { @@ -415,8 +539,6 @@ class PartitionGeometryTest TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestAdvancedTetrahedralGeometry() { @@ -430,8 +552,6 @@ class PartitionGeometryTest TestAdvancedGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, partitioningSchemeOrigin, lengthPerPartition, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestBoundingBoxTetrahedralGeometry() { @@ -446,7 +566,28 @@ class PartitionGeometryTest } // ----------------------------------------------------------------------------- - // + void TestExistingPartitioningSchemeTetrahedralGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryTetrahedralGeomIdsPath; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath partitioningSchemeDCPath = {"PartitioningSchemeDataContainer", "", ""}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; + + TestExistingPartitioningSchemeGeometry(inputFile, arrayPath, exemplaryArrayName, partitioningSchemeDCPath); + } + + // ----------------------------------------------------------------------------- + void TestMaskedTetrahedralGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryTetrahedralGeomIdsPath; + IntVec3Type numOfPartitionsPerAxis = {100, 45, 8}; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath maskPath = {"DataContainer", "VertexData", "Mask"}; + QString exemplaryArrayName = "MaskedExemplaryPartitioningSchemeIds"; + + TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName, maskPath); + } + // ----------------------------------------------------------------------------- void TestBasicHexahedralGeometry() { @@ -458,8 +599,6 @@ class PartitionGeometryTest TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestAdvancedHexahedralGeometry() { @@ -473,8 +612,6 @@ class PartitionGeometryTest TestAdvancedGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, partitioningSchemeOrigin, lengthPerPartition, exemplaryArrayName); } - // ----------------------------------------------------------------------------- - // // ----------------------------------------------------------------------------- void TestBoundingBoxHexahedralGeometry() { @@ -489,7 +626,61 @@ class PartitionGeometryTest } // ----------------------------------------------------------------------------- - // + void TestExistingPartitioningSchemeHexahedralGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryHexahedralGeomIdsPath; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath partitioningSchemeDCPath = {"PartitioningSchemeDataContainer", "", ""}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; + + TestExistingPartitioningSchemeGeometry(inputFile, arrayPath, exemplaryArrayName, partitioningSchemeDCPath); + } + + // ----------------------------------------------------------------------------- + void TestMaskedHexahedralGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryHexahedralGeomIdsPath; + IntVec3Type numOfPartitionsPerAxis = {6, 7, 8}; + DataArrayPath arrayPath = {"DataContainer", "VertexData", "PartitioningSchemeIds"}; + DataArrayPath maskPath = {"DataContainer", "VertexData", "Mask"}; + QString exemplaryArrayName = "MaskedExemplaryPartitioningSchemeIds"; + + TestBasicGeometry(inputFile, arrayPath, numOfPartitionsPerAxis, exemplaryArrayName, maskPath); + } + + // ----------------------------------------------------------------------------- + void TestPlanalXYNodeGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryPlanalXYNodeGeomIdsPath; + IntVec3Type numOfPartitionsPerAxis = {3, 3, 3}; + DataArrayPath arrayPath = {"VertexDataContainer", "AttributeMatrix", "PartitioningSchemeIds"}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; + + TestBasicGeometryError(inputFile, arrayPath, numOfPartitionsPerAxis, -3042); + } + + // ----------------------------------------------------------------------------- + void TestPlanalXZNodeGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryPlanalXZNodeGeomIdsPath; + IntVec3Type numOfPartitionsPerAxis = {3, 3, 3}; + DataArrayPath arrayPath = {"VertexDataContainer", "AttributeMatrix", "PartitioningSchemeIds"}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; + + TestBasicGeometryError(inputFile, arrayPath, numOfPartitionsPerAxis, -3041); + } + + // ----------------------------------------------------------------------------- + void TestPlanalYZNodeGeometry() + { + QString inputFile = UnitTest::PartitionGeometryTest::ExemplaryPlanalYZNodeGeomIdsPath; + IntVec3Type numOfPartitionsPerAxis = {3, 3, 3}; + DataArrayPath arrayPath = {"VertexDataContainer", "AttributeMatrix", "PartitioningSchemeIds"}; + QString exemplaryArrayName = "ExemplaryPartitioningSchemeIds"; + + TestBasicGeometryError(inputFile, arrayPath, numOfPartitionsPerAxis, -3040); + } + // ----------------------------------------------------------------------------- void operator()() { @@ -499,33 +690,51 @@ class PartitionGeometryTest DREAM3D_REGISTER_TEST(TestBasicImageGeometry()) DREAM3D_REGISTER_TEST(TestAdvancedImageGeometry()) DREAM3D_REGISTER_TEST(TestBoundingBoxImageGeometry()) + DREAM3D_REGISTER_TEST(TestExistingPartitioningSchemeImageGeometry()) DREAM3D_REGISTER_TEST(TestBasicRectGridGeometry()) DREAM3D_REGISTER_TEST(TestAdvancedRectGridGeometry()) DREAM3D_REGISTER_TEST(TestBoundingBoxRectGridGeometry()) + DREAM3D_REGISTER_TEST(TestExistingPartitioningSchemeRectGridGeometry()) DREAM3D_REGISTER_TEST(TestBasicTriangleGeometry()) DREAM3D_REGISTER_TEST(TestAdvancedTriangleGeometry()) DREAM3D_REGISTER_TEST(TestBoundingBoxTriangleGeometry()) + DREAM3D_REGISTER_TEST(TestExistingPartitioningSchemeTriangleGeometry()) + DREAM3D_REGISTER_TEST(TestMaskedTriangleGeometry()) DREAM3D_REGISTER_TEST(TestBasicEdgeGeometry()) DREAM3D_REGISTER_TEST(TestAdvancedEdgeGeometry()) DREAM3D_REGISTER_TEST(TestBoundingBoxEdgeGeometry()) + DREAM3D_REGISTER_TEST(TestExistingPartitioningSchemeEdgeGeometry()) + DREAM3D_REGISTER_TEST(TestMaskedEdgeGeometry()) DREAM3D_REGISTER_TEST(TestBasicVertexGeometry()) DREAM3D_REGISTER_TEST(TestAdvancedVertexGeometry()) DREAM3D_REGISTER_TEST(TestBoundingBoxVertexGeometry()) + DREAM3D_REGISTER_TEST(TestExistingPartitioningSchemeVertexGeometry()) + DREAM3D_REGISTER_TEST(TestMaskedVertexGeometry()) DREAM3D_REGISTER_TEST(TestBasicQuadGeometry()) DREAM3D_REGISTER_TEST(TestAdvancedQuadGeometry()) DREAM3D_REGISTER_TEST(TestBoundingBoxQuadGeometry()) + DREAM3D_REGISTER_TEST(TestExistingPartitioningSchemeQuadGeometry()) + DREAM3D_REGISTER_TEST(TestMaskedQuadGeometry()) DREAM3D_REGISTER_TEST(TestBasicTetrahedralGeometry()) DREAM3D_REGISTER_TEST(TestAdvancedTetrahedralGeometry()) DREAM3D_REGISTER_TEST(TestBoundingBoxTetrahedralGeometry()) + DREAM3D_REGISTER_TEST(TestExistingPartitioningSchemeTetrahedralGeometry()) + DREAM3D_REGISTER_TEST(TestMaskedTetrahedralGeometry()) DREAM3D_REGISTER_TEST(TestBasicHexahedralGeometry()) DREAM3D_REGISTER_TEST(TestAdvancedHexahedralGeometry()) DREAM3D_REGISTER_TEST(TestBoundingBoxHexahedralGeometry()) + DREAM3D_REGISTER_TEST(TestExistingPartitioningSchemeHexahedralGeometry()) + DREAM3D_REGISTER_TEST(TestMaskedHexahedralGeometry()) + + DREAM3D_REGISTER_TEST(TestPlanalXYNodeGeometry()) + DREAM3D_REGISTER_TEST(TestPlanalXZNodeGeometry()) + DREAM3D_REGISTER_TEST(TestPlanalYZNodeGeometry()) } }; diff --git a/Source/Plugins/Reconstruction/Test/TestFileLocations.h.in b/Source/Plugins/Reconstruction/Test/TestFileLocations.h.in index b8ab5872f6..2215c20644 100644 --- a/Source/Plugins/Reconstruction/Test/TestFileLocations.h.in +++ b/Source/Plugins/Reconstruction/Test/TestFileLocations.h.in @@ -37,5 +37,8 @@ namespace UnitTest inline const QString ExemplaryQuadGeomIdsPath("@DREAM3DProj_SOURCE_DIR@/Source/Plugins/Reconstruction/Test/TestFiles/quad_geom.dream3d"); inline const QString ExemplaryTetrahedralGeomIdsPath("@DREAM3DProj_SOURCE_DIR@/Source/Plugins/Reconstruction/Test/TestFiles/tetrahedral_geom.dream3d"); inline const QString ExemplaryHexahedralGeomIdsPath("@DREAM3DProj_SOURCE_DIR@/Source/Plugins/Reconstruction/Test/TestFiles/hexahedral_geom.dream3d"); + inline const QString ExemplaryPlanalXYNodeGeomIdsPath("@DREAM3DProj_SOURCE_DIR@/Source/Plugins/Reconstruction/Test/TestFiles/planal_xy_node_geom.dream3d"); + inline const QString ExemplaryPlanalXZNodeGeomIdsPath("@DREAM3DProj_SOURCE_DIR@/Source/Plugins/Reconstruction/Test/TestFiles/planal_xz_node_geom.dream3d"); + inline const QString ExemplaryPlanalYZNodeGeomIdsPath("@DREAM3DProj_SOURCE_DIR@/Source/Plugins/Reconstruction/Test/TestFiles/planal_yz_node_geom.dream3d"); } } diff --git a/Source/Plugins/Reconstruction/Test/TestFiles/edge_geom.dream3d b/Source/Plugins/Reconstruction/Test/TestFiles/edge_geom.dream3d index 4a370af4a9..c69ce67e78 100644 Binary files a/Source/Plugins/Reconstruction/Test/TestFiles/edge_geom.dream3d and b/Source/Plugins/Reconstruction/Test/TestFiles/edge_geom.dream3d differ diff --git a/Source/Plugins/Reconstruction/Test/TestFiles/hexahedral_geom.dream3d b/Source/Plugins/Reconstruction/Test/TestFiles/hexahedral_geom.dream3d index 5e09760fd5..48d01609a4 100644 Binary files a/Source/Plugins/Reconstruction/Test/TestFiles/hexahedral_geom.dream3d and b/Source/Plugins/Reconstruction/Test/TestFiles/hexahedral_geom.dream3d differ diff --git a/Source/Plugins/Reconstruction/Test/TestFiles/image_geom.dream3d b/Source/Plugins/Reconstruction/Test/TestFiles/image_geom.dream3d index 59804c828f..2145ed6570 100644 Binary files a/Source/Plugins/Reconstruction/Test/TestFiles/image_geom.dream3d and b/Source/Plugins/Reconstruction/Test/TestFiles/image_geom.dream3d differ diff --git a/Source/Plugins/Reconstruction/Test/TestFiles/planal_xy_node_geom.dream3d b/Source/Plugins/Reconstruction/Test/TestFiles/planal_xy_node_geom.dream3d new file mode 100644 index 0000000000..2a6f84975d Binary files /dev/null and b/Source/Plugins/Reconstruction/Test/TestFiles/planal_xy_node_geom.dream3d differ diff --git a/Source/Plugins/Reconstruction/Test/TestFiles/planal_xz_node_geom.dream3d b/Source/Plugins/Reconstruction/Test/TestFiles/planal_xz_node_geom.dream3d new file mode 100644 index 0000000000..a24fc6fae6 Binary files /dev/null and b/Source/Plugins/Reconstruction/Test/TestFiles/planal_xz_node_geom.dream3d differ diff --git a/Source/Plugins/Reconstruction/Test/TestFiles/planal_yz_node_geom.dream3d b/Source/Plugins/Reconstruction/Test/TestFiles/planal_yz_node_geom.dream3d new file mode 100644 index 0000000000..18d658ddfb Binary files /dev/null and b/Source/Plugins/Reconstruction/Test/TestFiles/planal_yz_node_geom.dream3d differ diff --git a/Source/Plugins/Reconstruction/Test/TestFiles/quad_geom.dream3d b/Source/Plugins/Reconstruction/Test/TestFiles/quad_geom.dream3d index 9a5108f19e..75dd678fd1 100644 Binary files a/Source/Plugins/Reconstruction/Test/TestFiles/quad_geom.dream3d and b/Source/Plugins/Reconstruction/Test/TestFiles/quad_geom.dream3d differ diff --git a/Source/Plugins/Reconstruction/Test/TestFiles/rectgrid_geom.dream3d b/Source/Plugins/Reconstruction/Test/TestFiles/rectgrid_geom.dream3d index 99644aaad5..65d7f44d30 100644 Binary files a/Source/Plugins/Reconstruction/Test/TestFiles/rectgrid_geom.dream3d and b/Source/Plugins/Reconstruction/Test/TestFiles/rectgrid_geom.dream3d differ diff --git a/Source/Plugins/Reconstruction/Test/TestFiles/tetrahedral_geom.dream3d b/Source/Plugins/Reconstruction/Test/TestFiles/tetrahedral_geom.dream3d index 8b4ad66ab5..30a043c52f 100644 Binary files a/Source/Plugins/Reconstruction/Test/TestFiles/tetrahedral_geom.dream3d and b/Source/Plugins/Reconstruction/Test/TestFiles/tetrahedral_geom.dream3d differ diff --git a/Source/Plugins/Reconstruction/Test/TestFiles/triangle_geom.dream3d b/Source/Plugins/Reconstruction/Test/TestFiles/triangle_geom.dream3d index 4d3c876c0f..c90bb66766 100644 Binary files a/Source/Plugins/Reconstruction/Test/TestFiles/triangle_geom.dream3d and b/Source/Plugins/Reconstruction/Test/TestFiles/triangle_geom.dream3d differ diff --git a/Source/Plugins/Reconstruction/Test/TestFiles/vertex_geom.dream3d b/Source/Plugins/Reconstruction/Test/TestFiles/vertex_geom.dream3d index 4823740e4d..68badef605 100644 Binary files a/Source/Plugins/Reconstruction/Test/TestFiles/vertex_geom.dream3d and b/Source/Plugins/Reconstruction/Test/TestFiles/vertex_geom.dream3d differ