diff --git a/Source/OrientationLib/Utilities/ModifiedLambertProjectionArray.cpp b/Source/OrientationLib/Utilities/ModifiedLambertProjectionArray.cpp index dcaa5956bc..c18d66a351 100644 --- a/Source/OrientationLib/Utilities/ModifiedLambertProjectionArray.cpp +++ b/Source/OrientationLib/Utilities/ModifiedLambertProjectionArray.cpp @@ -353,7 +353,7 @@ int ModifiedLambertProjectionArray::copyTuple(size_t currentPos, size_t newPos) // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -bool ModifiedLambertProjectionArray::copyData(size_t destTupleOffset, IDataArray::Pointer sourceArray) +bool ModifiedLambertProjectionArray::copyFromArray(size_t destTupleOffset, IDataArray::Pointer sourceArray, size_t srcTupleOffset, size_t totalSrcTuples) { if(!m_IsAllocated) { return false; } if(0 == m_ModifiedLambertProjectionArray.size()) { return false; } @@ -363,11 +363,17 @@ bool ModifiedLambertProjectionArray::copyData(size_t destTupleOffset, IDataArray if(sourceArray->getNumberOfComponents() != getNumberOfComponents()) { return false; } - if( sourceArray->getNumberOfTuples()*sourceArray->getNumberOfComponents() + destTupleOffset*getNumberOfComponents() > m_ModifiedLambertProjectionArray.size() ) { return false; } + if(srcTupleOffset + totalSrcTuples > sourceArray->getNumberOfTuples()) + { + return false; + } - size_t sourceNTuples = source->getNumberOfTuples(); + if(totalSrcTuples * sourceArray->getNumberOfComponents() + destTupleOffset * getNumberOfComponents() > m_ModifiedLambertProjectionArray.size()) + { + return false; + } - for(size_t i = 0; i < sourceNTuples; i++) + for(size_t i = srcTupleOffset; i < srcTupleOffset + totalSrcTuples; i++) { m_ModifiedLambertProjectionArray[destTupleOffset + i] = (*source)[i]; } diff --git a/Source/OrientationLib/Utilities/ModifiedLambertProjectionArray.h b/Source/OrientationLib/Utilities/ModifiedLambertProjectionArray.h index ea0657d97d..c7f38c0658 100644 --- a/Source/OrientationLib/Utilities/ModifiedLambertProjectionArray.h +++ b/Source/OrientationLib/Utilities/ModifiedLambertProjectionArray.h @@ -252,24 +252,30 @@ class OrientationLib_EXPORT ModifiedLambertProjectionArray : public IDataArray */ virtual int copyTuple(size_t currentPos, size_t newPos); + // This line must be here, because we are overloading the copyData pure virtual function in IDataArray. + // This is required so that other classes can call this version of copyData from the subclasses. + using IDataArray::copyFromArray; + /** - * @brief copyData This method copies all data from the sourceArray into - * the current array starting at the target destination tuple offset value. + * @brief copyData This method copies the number of tuples specified by the + * totalSrcTuples value starting from the source tuple offset value in sourceArray + * into the current array starting at the target destination tuple offset value. * - * For example if the DataArray has 10 tuples and the destTupleOffset = 5 then - * then source data will be copied into the destination array starting at - * destination tuple 5. In psuedo code it would be the following: + * For example if the DataArray has 10 tuples, the source DataArray has 10 tuples, + * the destTupleOffset = 5, the srcTupleOffset = 5, and the totalSrcTuples = 3, + * then tuples 5, 6, and 7 will be copied from the source into tuples 5, 6, and 7 + * of the destination array. In psuedo code it would be the following: * @code - * destArray[5] = sourceArray[0]; - * destArray[6] = sourceArray[1]; + * destArray[5] = sourceArray[5]; + * destArray[6] = sourceArray[6]; + * destArray[7] = sourceArray[7]; * ..... * @endcode * @param destTupleOffset * @param sourceArray * @return */ - virtual bool copyData(size_t destTupleOffset, IDataArray::Pointer sourceArray); - + virtual bool copyFromArray(size_t destTupleOffset, IDataArray::Pointer sourceArray, size_t srcTupleOffset, size_t totalSrcTuples); /** * @brief Splats the same value c across all values in the Tuple diff --git a/Source/Plugins/Sampling/SamplingFilters/AppendImageGeometryZSlice.cpp b/Source/Plugins/Sampling/SamplingFilters/AppendImageGeometryZSlice.cpp index 471de06c4e..32b5d12bc4 100644 --- a/Source/Plugins/Sampling/SamplingFilters/AppendImageGeometryZSlice.cpp +++ b/Source/Plugins/Sampling/SamplingFilters/AppendImageGeometryZSlice.cpp @@ -289,7 +289,7 @@ void AppendImageGeometryZSlice::execute() IDataArray::Pointer inputArray = inputCellAttrMat->getAttributeArray(*iter); if(nullptr != inputArray.get()) { - p->copyData(tupleOffset, inputArray); + p->copyFromArray(tupleOffset, inputArray); } else { diff --git a/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/InsertPrecipitatePhases.cpp b/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/InsertPrecipitatePhases.cpp index b1f252c8cc..6dc73abbf4 100644 --- a/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/InsertPrecipitatePhases.cpp +++ b/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/InsertPrecipitatePhases.cpp @@ -1,7 +1,8 @@ /* ============================================================================ * Copyright (c) 2009-2016 BlueQuartz Software, LLC * -* Redistribution and use in source and binary forms, with or without modification, +* Redistribution and use in source and binary forms, with or without +* modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this @@ -11,8 +12,10 @@ * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * -* Neither the name of BlueQuartz Software, the US Air Force, nor the names of its -* contributors may be used to endorse or promote products derived from this software +* Neither the name of BlueQuartz Software, the US Air Force, nor the names of +* its +* contributors may be used to endorse or promote products derived from this +* software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" @@ -41,10 +44,13 @@ #include "SIMPLib/Common/Constants.h" #include "SIMPLib/FilterParameters/AbstractFilterParametersReader.h" +#include "SIMPLib/FilterParameters/AttributeMatrixCreationFilterParameter.h" +#include "SIMPLib/FilterParameters/AttributeMatrixSelectionFilterParameter.h" #include "SIMPLib/FilterParameters/BooleanFilterParameter.h" #include "SIMPLib/FilterParameters/DataArraySelectionFilterParameter.h" #include "SIMPLib/FilterParameters/InputFileFilterParameter.h" #include "SIMPLib/FilterParameters/LinkedBooleanFilterParameter.h" +#include "SIMPLib/FilterParameters/LinkedChoicesFilterParameter.h" #include "SIMPLib/FilterParameters/OutputFileFilterParameter.h" #include "SIMPLib/FilterParameters/SeparatorFilterParameter.h" #include "SIMPLib/Geometry/ImageGeom.h" @@ -59,6 +65,8 @@ // Include the MOC generated file for this class #include "moc_InsertPrecipitatePhases.cpp" +const QString PrecipitateSyntheticShapeParametersName("Synthetic Shape Parameters (Precipitate)"); + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -90,6 +98,7 @@ InsertPrecipitatePhases::InsertPrecipitatePhases() , m_AxisLengthsArrayName(SIMPL::FeatureData::AxisLengths) , m_NumFeaturesArrayPath(SIMPL::Defaults::SyntheticVolumeDataContainerName, SIMPL::Defaults::CellEnsembleAttributeMatrixName, SIMPL::EnsembleData::NumFeatures) , m_SaveGeometricDescriptions(false) +, m_NewAttributeMatrixPath(SIMPL::Defaults::SyntheticVolumeDataContainerName, PrecipitateSyntheticShapeParametersName, "") , m_FeatureIds(nullptr) , m_CellPhases(nullptr) , m_Mask(nullptr) @@ -131,18 +140,15 @@ void InsertPrecipitatePhases::setupFilterParameters() parameters.push_back(SIMPL_NEW_LINKED_BOOL_FP("Use Mask", UseMask, FilterParameter::Parameter, InsertPrecipitatePhases, linkedProps)); parameters.push_back(SeparatorFilterParameter::New("Cell Data", FilterParameter::RequiredArray)); { - DataArraySelectionFilterParameter::RequirementType req = - DataArraySelectionFilterParameter::CreateRequirement(SIMPL::TypeNames::Int32, 1, AttributeMatrix::Type::Cell, IGeometry::Type::Image); + DataArraySelectionFilterParameter::RequirementType req = DataArraySelectionFilterParameter::CreateRequirement(SIMPL::TypeNames::Int32, 1, AttributeMatrix::Type::Cell, IGeometry::Type::Image); parameters.push_back(SIMPL_NEW_DA_SELECTION_FP("Feature Ids", FeatureIdsArrayPath, FilterParameter::RequiredArray, InsertPrecipitatePhases, req)); } { - DataArraySelectionFilterParameter::RequirementType req = - DataArraySelectionFilterParameter::CreateRequirement(SIMPL::TypeNames::Int32, 1, AttributeMatrix::Type::Cell, IGeometry::Type::Image); + DataArraySelectionFilterParameter::RequirementType req = DataArraySelectionFilterParameter::CreateRequirement(SIMPL::TypeNames::Int32, 1, AttributeMatrix::Type::Cell, IGeometry::Type::Image); parameters.push_back(SIMPL_NEW_DA_SELECTION_FP("Phases", CellPhasesArrayPath, FilterParameter::RequiredArray, InsertPrecipitatePhases, req)); } { - DataArraySelectionFilterParameter::RequirementType req = - DataArraySelectionFilterParameter::CreateRequirement(SIMPL::TypeNames::Int8, 1, AttributeMatrix::Type::Cell, IGeometry::Type::Image); + DataArraySelectionFilterParameter::RequirementType req = DataArraySelectionFilterParameter::CreateRequirement(SIMPL::TypeNames::Int8, 1, AttributeMatrix::Type::Cell, IGeometry::Type::Image); parameters.push_back(SIMPL_NEW_DA_SELECTION_FP("Boundary Cells", BoundaryCellsArrayPath, FilterParameter::RequiredArray, InsertPrecipitatePhases, req)); } { @@ -197,8 +203,36 @@ void InsertPrecipitatePhases::setupFilterParameters() parameters.push_back(SIMPL_NEW_LINKED_BOOL_FP("Write Goal Attributes", WriteGoalAttributes, FilterParameter::Parameter, InsertPrecipitatePhases, linkedProps)); parameters.push_back(SIMPL_NEW_OUTPUT_FILE_FP("Goal Attribute CSV File", CsvOutputFile, FilterParameter::Parameter, InsertPrecipitatePhases, "*.csv", "Comma Separated Data")); - parameters.push_back(SIMPL_NEW_BOOL_FP("Save Shape Description Arrays", SaveGeometricDescriptions, FilterParameter::Parameter, InsertPrecipitatePhases)); + { + LinkedChoicesFilterParameter::Pointer parameter = LinkedChoicesFilterParameter::New(); + parameter->setHumanLabel("Save Shape Description Arrays"); + parameter->setPropertyName("SaveGeometricDescriptions"); + parameter->setSetterCallback(SIMPL_BIND_SETTER(InsertPrecipitatePhases, this, SaveGeometricDescriptions)); + parameter->setGetterCallback(SIMPL_BIND_GETTER(InsertPrecipitatePhases, this, SaveGeometricDescriptions)); + + QVector choices; + choices.push_back("Save To New Attribute Matrix"); + choices.push_back("Append To Existing Attribute Matrix"); + choices.push_back("Do Not Save"); + parameter->setChoices(choices); + QStringList linkedProps; + linkedProps << "NewAttributeMatrixPath" + << "SelectedAttributeMatrixPath"; + parameter->setLinkedProperties(linkedProps); + parameter->setEditable(false); + parameter->setCategory(FilterParameter::Parameter); + parameters.push_back(parameter); + } + + { + AttributeMatrixCreationFilterParameter::RequirementType req; + parameters.push_back(SIMPL_NEW_AM_CREATION_FP("New Attribute Matrix", NewAttributeMatrixPath, FilterParameter::Parameter, InsertPrecipitatePhases, req, 0)); + } + { + AttributeMatrixSelectionFilterParameter::RequirementType req = AttributeMatrixSelectionFilterParameter::CreateRequirement(AttributeMatrix::Category::Feature); + parameters.push_back(SIMPL_NEW_AM_SELECTION_FP("Selected Attribute Matrix", SelectedAttributeMatrixPath, FilterParameter::Parameter, InsertPrecipitatePhases, req, 1)); + } setFilterParameters(parameters); } @@ -233,35 +267,51 @@ void InsertPrecipitatePhases::readFilterParameters(AbstractFilterParametersReade void InsertPrecipitatePhases::updateFeatureInstancePointers() { setErrorCondition(0); - if(nullptr != m_FeaturePhasesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + if(nullptr != m_FeaturePhasesPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a DataArray + object */ { m_FeaturePhases = m_FeaturePhasesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ - if(nullptr != m_NumCellsPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + if(nullptr != m_NumCellsPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a DataArray + object */ { m_NumCells = m_NumCellsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ - if(nullptr != m_EquivalentDiametersPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + if(nullptr != m_EquivalentDiametersPtr.lock().get()) /* Validate the Weak + Pointer wraps a + non-nullptr pointer + to a DataArray + object */ { m_EquivalentDiameters = m_EquivalentDiametersPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ - if(nullptr != m_VolumesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + if(nullptr != m_VolumesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a + DataArray object */ { m_Volumes = m_VolumesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ - if(nullptr != m_Omega3sPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + if(nullptr != m_Omega3sPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a + DataArray object */ { m_Omega3s = m_Omega3sPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ - if(nullptr != m_CentroidsPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + if(nullptr != m_CentroidsPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a DataArray + object */ { m_Centroids = m_CentroidsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ - if(nullptr != m_AxisEulerAnglesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + if(nullptr != m_AxisEulerAnglesPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a + DataArray object */ { m_AxisEulerAngles = m_AxisEulerAnglesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ - if(nullptr != m_AxisLengthsPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + if(nullptr != m_AxisLengthsPtr.lock().get()) /* Validate the Weak Pointer + wraps a non-nullptr pointer + to a DataArray object */ { m_AxisLengths = m_AxisLengthsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ @@ -336,7 +386,9 @@ void InsertPrecipitatePhases::dataCheck() QVector cDims(1, 1); m_PhaseTypesPtr = getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getInputPhaseTypesArrayPath(), cDims); - if(nullptr != m_PhaseTypesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + if(nullptr != m_PhaseTypesPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a DataArray + object */ { m_PhaseTypes = m_PhaseTypesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ @@ -346,7 +398,9 @@ void InsertPrecipitatePhases::dataCheck() } m_ShapeTypesPtr = getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getInputShapeTypesArrayPath(), cDims); - if(nullptr != m_ShapeTypesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + if(nullptr != m_ShapeTypesPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a DataArray + object */ { m_ShapeTypes = m_ShapeTypesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ @@ -368,9 +422,11 @@ void InsertPrecipitatePhases::dataCheck() } // Cell Data - m_FeatureIdsPtr = getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getFeatureIdsArrayPath(), - cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_FeatureIdsPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_FeatureIdsPtr = getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getFeatureIdsArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that + is a weak_ptr<> */ + if(nullptr != m_FeatureIdsPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a DataArray + object */ { m_FeatureIds = m_FeatureIdsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ @@ -379,9 +435,11 @@ void InsertPrecipitatePhases::dataCheck() cellDataArrayPaths.push_back(getFeatureIdsArrayPath()); } - m_CellPhasesPtr = getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getCellPhasesArrayPath(), - cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_CellPhasesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_CellPhasesPtr = getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getCellPhasesArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that + is a weak_ptr<> */ + if(nullptr != m_CellPhasesPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a DataArray + object */ { m_CellPhases = m_CellPhasesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ @@ -390,9 +448,12 @@ void InsertPrecipitatePhases::dataCheck() cellDataArrayPaths.push_back(getCellPhasesArrayPath()); } - m_BoundaryCellsPtr = getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getBoundaryCellsArrayPath(), - cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_BoundaryCellsPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_BoundaryCellsPtr = + getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getBoundaryCellsArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that + is a weak_ptr<> */ + if(nullptr != m_BoundaryCellsPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a DataArray + object */ { m_BoundaryCells = m_BoundaryCellsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ @@ -404,7 +465,9 @@ void InsertPrecipitatePhases::dataCheck() if(m_UseMask == true) { m_MaskPtr = getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getMaskArrayPath(), cDims); - if(nullptr != m_MaskPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + if(nullptr != m_MaskPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a + DataArray object */ { m_Mask = m_MaskPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ @@ -414,76 +477,126 @@ void InsertPrecipitatePhases::dataCheck() } } + QVector tDims(1, 0); + DataContainer::Pointer m = getDataContainerArray()->getPrereqDataContainer(this, getFeaturePhasesArrayPath().getDataContainerName()); + if(getErrorCondition() < 0) + { + return; + } + + InsertPrecipitatePhases::SaveMethod saveMethod = static_cast(getSaveGeometricDescriptions()); + if(saveMethod == InsertPrecipitatePhases::SaveMethod::SaveToNew) + { + m->createNonPrereqAttributeMatrix(this, getNewAttributeMatrixPath().getAttributeMatrixName(), tDims, AttributeMatrix::Type::CellFeature); + } + else if(saveMethod == InsertPrecipitatePhases::SaveMethod::AppendToExisting) + { + int err = 0; + m->getPrereqAttributeMatrix(this, getSelectedAttributeMatrixPath().getAttributeMatrixName(), err); + } + // Feature Data - m_FeaturePhasesPtr = getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getFeaturePhasesArrayPath(), - cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_FeaturePhasesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_FeaturePhasesPtr = + getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getFeaturePhasesArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that + is a weak_ptr<> */ + if(nullptr != m_FeaturePhasesPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a DataArray + object */ { m_FeaturePhases = m_FeaturePhasesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ tempPath.update(getFeaturePhasesArrayPath().getDataContainerName(), getFeaturePhasesArrayPath().getAttributeMatrixName(), getNumCellsArrayName()); - m_NumCellsPtr = getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, int32_t>( - this, tempPath, 0, cDims, getNumCellsArrayName()); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_NumCellsPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_NumCellsPtr = getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, int32_t>(this, tempPath, 0, cDims, getNumCellsArrayName()); /* Assigns the shared_ptr<> + to an instance variable + that is a weak_ptr<> */ + if(nullptr != m_NumCellsPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a DataArray + object */ { m_NumCells = m_NumCellsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ tempPath.update(getFeaturePhasesArrayPath().getDataContainerName(), getFeaturePhasesArrayPath().getAttributeMatrixName(), getEquivalentDiametersArrayName()); - m_EquivalentDiametersPtr = getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>( - this, tempPath, 0, cDims, getEquivalentDiametersArrayName()); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_EquivalentDiametersPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_EquivalentDiametersPtr = + getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>(this, tempPath, 0, cDims, getEquivalentDiametersArrayName()); /* Assigns the + shared_ptr<> to + an instance + variable that is + a weak_ptr<> */ + if(nullptr != m_EquivalentDiametersPtr.lock().get()) /* Validate the Weak + Pointer wraps a + non-nullptr pointer + to a DataArray + object */ { m_EquivalentDiameters = m_EquivalentDiametersPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ tempPath.update(getFeaturePhasesArrayPath().getDataContainerName(), getFeaturePhasesArrayPath().getAttributeMatrixName(), getVolumesArrayName()); - m_VolumesPtr = getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>( - this, tempPath, 0, cDims, getVolumesArrayName()); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_VolumesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_VolumesPtr = getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>(this, tempPath, 0, cDims, getVolumesArrayName()); /* Assigns the shared_ptr<> to an + instance variable that is a + weak_ptr<> */ + if(nullptr != m_VolumesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a + DataArray object */ { m_Volumes = m_VolumesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ tempPath.update(getFeaturePhasesArrayPath().getDataContainerName(), getFeaturePhasesArrayPath().getAttributeMatrixName(), getOmega3sArrayName()); - m_Omega3sPtr = getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>( - this, tempPath, 0, cDims, getOmega3sArrayName()); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_Omega3sPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_Omega3sPtr = getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>(this, tempPath, 0, cDims, getOmega3sArrayName()); /* Assigns the shared_ptr<> to an + instance variable that is a + weak_ptr<> */ + if(nullptr != m_Omega3sPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a + DataArray object */ { m_Omega3s = m_Omega3sPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ cDims[0] = 3; tempPath.update(getFeaturePhasesArrayPath().getDataContainerName(), getFeaturePhasesArrayPath().getAttributeMatrixName(), getCentroidsArrayName()); - m_CentroidsPtr = getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>( - this, tempPath, 0, cDims, getCentroidsArrayName()); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_CentroidsPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_CentroidsPtr = getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>(this, tempPath, 0, cDims, getCentroidsArrayName()); /* Assigns the shared_ptr<> to an + instance variable that is a + weak_ptr<> */ + if(nullptr != m_CentroidsPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a DataArray + object */ { m_Centroids = m_CentroidsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ tempPath.update(getFeaturePhasesArrayPath().getDataContainerName(), getFeaturePhasesArrayPath().getAttributeMatrixName(), getAxisEulerAnglesArrayName()); - m_AxisEulerAnglesPtr = getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>( - this, tempPath, 0, cDims, getAxisEulerAnglesArrayName()); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_AxisEulerAnglesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_AxisEulerAnglesPtr = + getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>(this, tempPath, 0, cDims, getAxisEulerAnglesArrayName()); /* Assigns the shared_ptr<> to an + instance variable that is a + weak_ptr<> */ + if(nullptr != m_AxisEulerAnglesPtr.lock().get()) /* Validate the Weak Pointer wraps a + non-nullptr pointer to a + DataArray object */ { m_AxisEulerAngles = m_AxisEulerAnglesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ tempPath.update(getFeaturePhasesArrayPath().getDataContainerName(), getFeaturePhasesArrayPath().getAttributeMatrixName(), getAxisLengthsArrayName()); - m_AxisLengthsPtr = getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>( - this, tempPath, 0, cDims, getAxisLengthsArrayName()); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_AxisLengthsPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_AxisLengthsPtr = + getDataContainerArray()->createNonPrereqArrayFromPath, AbstractFilter, float>(this, tempPath, 0, cDims, getAxisLengthsArrayName()); /* Assigns the shared_ptr<> to an + instance variable that is a + weak_ptr<> */ + if(nullptr != m_AxisLengthsPtr.lock().get()) /* Validate the Weak Pointer + wraps a non-nullptr pointer + to a DataArray object */ { m_AxisLengths = m_AxisLengthsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ // Ensemble Data cDims[0] = 1; - m_NumFeaturesPtr = getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getNumFeaturesArrayPath(), - cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ - if(nullptr != m_NumFeaturesPtr.lock().get()) /* Validate the Weak Pointer wraps a non-nullptr pointer to a DataArray object */ + m_NumFeaturesPtr = + getDataContainerArray()->getPrereqArrayFromPath, AbstractFilter>(this, getNumFeaturesArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that + is a weak_ptr<> */ + if(nullptr != m_NumFeaturesPtr.lock().get()) /* Validate the Weak Pointer + wraps a non-nullptr pointer + to a DataArray object */ { m_NumFeatures = m_NumFeaturesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray object */ @@ -557,7 +670,8 @@ void InsertPrecipitatePhases::execute() if(m_HavePrecips == false) { notifyStatusMessage(getMessagePrefix(), getHumanLabel(), "Packing Precipitates || Generating and Placing Precipitates"); - // this initializes the arrays to hold the details of the locations of all of the features during packing + // this initializes the arrays to hold the details of the locations of all + // of the features during packing Int32ArrayType::Pointer exclusionZonesPtr = Int32ArrayType::CreateArray(m_TotalPoints, "_INTERNAL_USE_ONLY_PackPrimaryFeatures::exclusion_zones"); exclusionZonesPtr->initializeWithZeros(); place_precipitates(exclusionZonesPtr); @@ -594,9 +708,12 @@ void InsertPrecipitatePhases::execute() return; } - // At this point we are done reassigning values to all arrays, so we are safe to copy - // down the Feature phases to the cells ; the Feature phases are correct from the - // generate_precipitate() function, but the cell phases are best done after all + // At this point we are done reassigning values to all arrays, so we are safe + // to copy + // down the Feature phases to the cells ; the Feature phases are correct from + // the + // generate_precipitate() function, but the cell phases are best done after + // all // assignment since cell values may be cleaned up after Feature generation size_t numTuples = m_FeatureIdsPtr.lock()->getNumberOfTuples(); for(size_t i = 0; i < numTuples; i++) @@ -731,7 +848,8 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi } } - // figure out how many grains we already have so we can start the counter at +1 this + // figure out how many grains we already have so we can start the counter at + // +1 this int32_t currentnumfeatures = static_cast(m_FeaturePhasesPtr.lock()->getNumberOfTuples()); size_t numensembles = m_PhaseTypesPtr.lock()->getNumberOfTuples(); @@ -759,9 +877,12 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi PrecipitateStatsData* pp = PrecipitateStatsData::SafePointerDownCast(statsDataArray[i].get()); if(nullptr == pp) { - QString ss = QObject::tr("Tried to cast a statsDataArray[%1].get() to a PrecipitateStatsData* " - "pointer but this resulted in a nullptr pointer. The value at m_PhaseTypes[%2] = %3 does not match up " - "with the type of pointer stored in the StatsDataArray (PrecipitateStatsData)\n") + QString ss = QObject::tr("Tried to cast a statsDataArray[%1].get() to a " + "PrecipitateStatsData* " + "pointer but this resulted in a nullptr pointer. The " + "value at m_PhaseTypes[%2] = %3 does not match up " + "with the type of pointer stored in the StatsDataArray " + "(PrecipitateStatsData)\n") .arg(i) .arg(i) .arg(m_PhaseTypes[i]); @@ -786,11 +907,13 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi return; } - // This is the set that we are going to keep updated with the points that are not in an exclusion zone + // This is the set that we are going to keep updated with the points that are + // not in an exclusion zone std::map availablePoints; std::map availablePointsInv; - // Get a pointer to the Feature Owners that was just initialized in the initialize_packinggrid() method + // Get a pointer to the Feature Owners that was just initialized in the + // initialize_packinggrid() method int32_t* exclusionZones = exclusionZonesPtr->getPointer(0); size_t featureOwnersIdx = 0; @@ -810,7 +933,9 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi VectorOfFloatArray GSdist = pp->getFeatureSizeDistribution(); float avg = GSdist[0]->getValue(0); float stdev = GSdist[1]->getValue(0); - float denominatorConst = sqrtf(2.0f * stdev * stdev); // Calculate it here rather than calculating the same thing multiple times below + float denominatorConst = sqrtf(2.0f * stdev * stdev); // Calculate it here rather than + // calculating the same thing multiple + // times below for(size_t j = 0; j < m_FeatureSizeDist[i].size(); j++) { input = (float(j + 1) * m_FeatureSizeDistStep[i]) + (pp->getMinFeatureDiameter() / 2.0f); @@ -832,7 +957,9 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi return; } - // adding precipitates until the volume fraction of precipitates matches the target (while making sure to keep the size distribution error within tolerance) + // adding precipitates until the volume fraction of precipitates matches the + // target (while making sure to keep the size distribution error within + // tolerance) Precip_t precip; std::vector curphasevol; curphasevol.resize(m_PrecipitatePhases.size()); @@ -876,7 +1003,8 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi QString ss = QObject::tr("Packing Precipitates || Starting Feature Placement..."); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); - // initializing the target RDF vector - this is the radial distribution function we are trying to match to + // initializing the target RDF vector - this is the radial distribution + // function we are trying to match to if(m_MatchRDF == true) { for(size_t i = 1; i < numensembles; ++i) @@ -923,7 +1051,8 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi m_AvailablePointsCount++; } } - // and clear the pointsToRemove and pointsToAdd vectors from the initial packing + // and clear the pointsToRemove and pointsToAdd vectors from the initial + // packing m_PointsToRemove.clear(); m_PointsToAdd.clear(); @@ -949,7 +1078,8 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi float boundaryFraction = (float)boundaryVoxels / (float)m_TotalPoints; - // boolean used to determine if current placement is acceptable if the precipitates are being treated as "hard" + // boolean used to determine if current placement is acceptable if the + // precipitates are being treated as "hard" // bool good = false; // int32_t progFeature = 0; @@ -958,7 +1088,8 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi // { // if (int32_t(i) > progFeature + progPrecipInc) // { - // QString ss = QObject::tr("Packing Precipitates || Placing Precipitate #%1").arg(i); + // QString ss = QObject::tr("Packing Precipitates || Placing Precipitate + // #%1").arg(i); // notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); // progFeature = i; // } @@ -972,7 +1103,8 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi // int32_t iterCount = 0; // while (good == false && iterCount < 100000 ) // { - // PrecipitateStatsData* pp = PrecipitateStatsData::SafePointerDownCast(statsDataArray[m_FeaturePhases[i]].get()); + // PrecipitateStatsData* pp = + // PrecipitateStatsData::SafePointerDownCast(statsDataArray[m_FeaturePhases[i]].get()); // precipboundaryfraction = pp->getPrecipBoundaryFraction(); // random = static_cast(rg.genrand_res53()); @@ -980,23 +1112,28 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi // { // if (random <= precipboundaryfraction) // { - // // figure out if we want this to be a boundary centroid voxel or not for the proposed precipitate + // // figure out if we want this to be a boundary centroid voxel or + // not for the proposed precipitate // if (availablePointsCount > 0) // { - // key = static_cast(rg.genrand_res53() * (availablePointsCount - 1)); + // key = static_cast(rg.genrand_res53() * + // (availablePointsCount - 1)); // featureOwnersIdx = availablePointsInv[key]; // while (m_BoundaryCells[featureOwnersIdx] == 0) // { - // key = static_cast(rg.genrand_res53() * (availablePointsCount - 1)); + // key = static_cast(rg.genrand_res53() * + // (availablePointsCount - 1)); // featureOwnersIdx = availablePointsInv[key]; // } // } // else // { - // featureOwnersIdx = static_cast(rg.genrand_res53() * m_TotalPoints); + // featureOwnersIdx = static_cast(rg.genrand_res53() * + // m_TotalPoints); // while (m_BoundaryCells[featureOwnersIdx] == 0) // { - // featureOwnersIdx = static_cast(rg.genrand_res53() * m_TotalPoints); + // featureOwnersIdx = static_cast(rg.genrand_res53() * + // m_TotalPoints); // } // } @@ -1005,20 +1142,24 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi // { // if (availablePointsCount > 0) // { - // key = static_cast(rg.genrand_res53() * (availablePointsCount - 1)); + // key = static_cast(rg.genrand_res53() * + // (availablePointsCount - 1)); // featureOwnersIdx = availablePointsInv[key]; // while (m_BoundaryCells[featureOwnersIdx] != 0) // { - // key = static_cast(rg.genrand_res53() * (availablePointsCount - 1)); + // key = static_cast(rg.genrand_res53() * + // (availablePointsCount - 1)); // featureOwnersIdx = availablePointsInv[key]; // } // } // else // { - // featureOwnersIdx = static_cast(rg.genrand_res53() * m_TotalPoints); + // featureOwnersIdx = static_cast(rg.genrand_res53() * + // m_TotalPoints); // while (m_BoundaryCells[featureOwnersIdx] != 0) // { - // featureOwnersIdx = static_cast(rg.genrand_res53() * m_TotalPoints); + // featureOwnersIdx = static_cast(rg.genrand_res53() * + // m_TotalPoints); // } // } // } @@ -1027,25 +1168,30 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi // { // if (precipboundaryfraction > 0) // { - // QString msg("There are no Feature boundaries on which to place precipitates and the target statistics precipitate fraction is greater than 0. This Filter will run without trying to match + // QString msg("There are no Feature boundaries on which to place + // precipitates and the target statistics precipitate fraction is + // greater than 0. This Filter will run without trying to match // the precipitate fraction"); // notifyWarningMessage(getHumanLabel(), msg, -5010); // } // if (availablePointsCount > 0) // { - // key = static_cast(rg.genrand_res53() * (availablePointsCount - 1)); + // key = static_cast(rg.genrand_res53() * + // (availablePointsCount - 1)); // featureOwnersIdx = availablePointsInv[key]; // } // else // { - // featureOwnersIdx = static_cast(rg.genrand_res53() * m_TotalPoints); + // featureOwnersIdx = static_cast(rg.genrand_res53() * + // m_TotalPoints); // } // } // column = static_cast(featureOwnersIdx % m_XPoints); // row = static_cast(featureOwnersIdx / m_XPoints) % m_YPoints; - // plane = static_cast(featureOwnersIdx / (m_XPoints * m_YPoints)); + // plane = static_cast(featureOwnersIdx / (m_XPoints * + // m_YPoints)); // xc = static_cast((column * m_XRes) + (m_XRes * 0.5)); // yc = static_cast((row * m_YRes) + (m_YRes * 0.5)); // zc = static_cast((plane * m_ZRes) + (m_ZRes * 0.5)); @@ -1066,7 +1212,8 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi // tDims[0] = i + 1; // m->getAttributeMatrix(getFeaturePhasesArrayPath().getAttributeMatrixName())->resizeAttributeArrays(tDims); // updateFeatureInstancePointers(); - // numfeatures = m->getAttributeMatrix(getFeaturePhasesArrayPath().getAttributeMatrixName())->getNumberOfTuples(); + // numfeatures = + // m->getAttributeMatrix(getFeaturePhasesArrayPath().getAttributeMatrixName())->getNumberOfTuples(); // } // } @@ -1087,7 +1234,8 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi { if(random <= precipboundaryfraction) { - // figure out if we want this to be a boundary centroid voxel or not for the proposed precipitate + // figure out if we want this to be a boundary centroid voxel or not for + // the proposed precipitate if(m_AvailablePointsCount > 0) { key = static_cast(rg.genrand_res53() * (m_AvailablePointsCount - 1)); @@ -1134,7 +1282,10 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi if(precipboundaryfraction > 0) { - QString msg("There are no Feature boundaries on which to place precipitates and the target statistics precipitate fraction is greater than 0. This Filter will run without trying to match the " + QString msg("There are no Feature boundaries on which to place " + "precipitates and the target statistics precipitate " + "fraction is greater than 0. This Filter will run without " + "trying to match the " "precipitate fraction"); notifyWarningMessage(getHumanLabel(), msg, -5010); } @@ -1170,9 +1321,12 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi { /*RANDOM: Figure out the RDF for randomly distributed particles. We always keep the same stepsize as the target RDF, - but change (increase if the current box is bigger than what the target dist was built on and vice versa) - the number of bins to account for smaller and larger (up to the max distance i.e. the box diagonal) - distances that can occur when particles are just randomly placed in a box. This is true for both m_rdfRandom and m_rdfCurrentDist.*/ + but change (increase if the current box is bigger than what the target dist + was built on and vice versa) + the number of bins to account for smaller and larger (up to the max distance + i.e. the box diagonal) + distances that can occur when particles are just randomly placed in a box. + This is true for both m_rdfRandom and m_rdfCurrentDist.*/ // initialize boxdims and boxres vectors std::vector boxdims(3); @@ -1189,15 +1343,19 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi int32_t current_num_bins = static_cast(ceil((max_box_distance - m_rdfMin) / (m_StepSize))); - // resize box to include all the possible distances but using the same stepsize as the target RDF. The zero bin includes all distances smaller than the smallest from the targetRDF + // resize box to include all the possible distances but using the same + // stepsize as the target RDF. The zero bin includes all distances smaller + // than the smallest from the targetRDF m_RdfRandom.resize(current_num_bins + 1); - // Call this function to generate the random distribution, which is normalized by the total number of distances + // Call this function to generate the random distribution, which is + // normalized by the total number of distances m_RdfRandom = RadialDistributionFunction::GenerateRandomDistribution(m_rdfMin, m_rdfMax, m_numRDFbins, boxdims, boxres); size_t numPPTfeatures = static_cast(numfeatures - m_FirstPrecipitateFeature); - // Scale the randomRDF to have the same number of particles (and therfore distances) as the current distribution. + // Scale the randomRDF to have the same number of particles (and therfore + // distances) as the current distribution. for(size_t i = 0; i < m_RdfRandom.size(); i++) { m_RdfRandom[i] = m_RdfRandom[i] * numPPTfeatures * (numPPTfeatures - 1); @@ -1218,7 +1376,8 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi if(m_MatchRDF == true) { - // calculate the initial current RDF - this will change as we move particles around + // calculate the initial current RDF - this will change as we move particles + // around for(size_t i = size_t(m_FirstPrecipitateFeature); i < numfeatures; i++) { m_oldRDFerror = check_RDFerror(int32_t(i), -1000, false); @@ -1233,13 +1392,18 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi } // begin swaping/moving/adding/removing features to try to improve packing - // The totalAdjustments are roughly equal to the prefactor (1000, right now) times the number of precipitates. - // This is not based on convergence or any physics - it's just a factor and there's probably room for improvement here + // The totalAdjustments are roughly equal to the prefactor (1000, right + // now) times the number of precipitates. + // This is not based on convergence or any physics - it's just a factor + // and there's probably room for improvement here int32_t totalAdjustments = static_cast(1000 * ((numfeatures - m_FirstPrecipitateFeature) - 1)); for(int32_t iteration = 0; iteration < totalAdjustments; ++iteration) { QString ss; - ss = QObject::tr("Packing Features - Swapping/Moving/Adding/Removing Features Iteration %1/%2").arg(iteration).arg(totalAdjustments); + ss = QObject::tr("Packing Features - Swapping/Moving/Adding/Removing " + "Features Iteration %1/%2") + .arg(iteration) + .arg(totalAdjustments); if(iteration % 100 == 0) { notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); @@ -1274,7 +1438,8 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi { if(random <= precipboundaryfraction) { - // figure out if we want this to be a boundary centroid voxel or not for the proposed precipitate + // figure out if we want this to be a boundary centroid voxel or not + // for the proposed precipitate if(m_AvailablePointsCount > 0) { key = static_cast(rg.genrand_res53() * (m_AvailablePointsCount - 1)); @@ -1321,7 +1486,10 @@ void InsertPrecipitatePhases::place_precipitates(Int32ArrayType::Pointer exclusi if(precipboundaryfraction > 0) { - QString msg("There are no Feature boundaries to place precipitates on and the target statistics precipitate fraction is greater than 0. This Filter will run without trying to match the " + QString msg("There are no Feature boundaries to place precipitates " + "on and the target statistics precipitate fraction is " + "greater than 0. This Filter will run without trying " + "to match the " "precipitate fraction"); notifyWarningMessage(getHumanLabel(), msg, -5010); } @@ -1499,7 +1667,7 @@ void InsertPrecipitatePhases::generate_precipitate(int32_t phase, Precip_t* prec float mf = omega3[0]->getValue(diameter); float s = omega3[1]->getValue(diameter); float omega3f = static_cast(rg.genrand_beta(mf, s)); - if (shapeclass == ShapeType::Type::Ellipsoid) + if(shapeclass == ShapeType::Type::Ellipsoid) { omega3f = 1; } @@ -1708,10 +1876,13 @@ void InsertPrecipitatePhases::update_exclusionZones(int32_t gadd, int32_t gremov } } -//// ----------------------------------------------------------------------------- //// -//// ----------------------------------------------------------------------------- -// bool InsertPrecipitatePhases::check_for_overlap(size_t gNum, Int32ArrayType::Pointer exclusionZonesPtr) +///----------------------------------------------------------------------------- +//// +//// +///----------------------------------------------------------------------------- +// bool InsertPrecipitatePhases::check_for_overlap(size_t gNum, +// Int32ArrayType::Pointer exclusionZonesPtr) //{ // size_t featureOwnersIdx = 0; // int32_t* exclusionZones = exclusionZonesPtr->getPointer(0); @@ -1735,19 +1906,23 @@ void InsertPrecipitatePhases::update_exclusionZones(int32_t gadd, int32_t gremov // if (row > m_YPoints - 1) { row = row - m_YPoints; } // if (plane < 0) { plane = plane + m_ZPoints; } // if (plane > m_ZPoints - 1) { plane = plane - m_ZPoints; } -// featureOwnersIdx = (m_XPoints * m_YPoints * plane) + (m_XPoints * row) + col; +// featureOwnersIdx = (m_XPoints * m_YPoints * plane) + (m_XPoints * row) + +// col; // if (exclusionZones[featureOwnersIdx] > 0) { overlapCount++; } // } // else // { -// if (col >= 0 && col < m_XPoints && row >= 0 && row < m_YPoints && plane >= 0 && plane < m_ZPoints) +// if (col >= 0 && col < m_XPoints && row >= 0 && row < m_YPoints && plane +// >= 0 && plane < m_ZPoints) // { -// featureOwnersIdx = (m_XPoints * m_YPoints * plane) + (m_XPoints * row) + col; +// featureOwnersIdx = (m_XPoints * m_YPoints * plane) + (m_XPoints * row) +// + col; // if (exclusionZones[featureOwnersIdx] > 0) { overlapCount++; } // } // } // } -// if ((static_cast(overlapCount) / static_cast(size)) > 0.1) { return false; } +// if ((static_cast(overlapCount) / static_cast(size)) > 0.1) { +// return false; } // return true; //} @@ -1895,7 +2070,8 @@ void InsertPrecipitatePhases::determine_randomRDF(size_t gnum, int32_t add, bool // ----------------------------------------------------------------------------- std::vector InsertPrecipitatePhases::normalizeRDF(std::vector rdf, int32_t num_bins, float m_StepSize, float rdfmin, int32_t numPPTfeatures) { - // //Normalizing the RDF by number density of particles (4/3*pi*(r2^3-r1^3)*numPPTfeatures/volume) + // //Normalizing the RDF by number density of particles + // (4/3*pi*(r2^3-r1^3)*numPPTfeatures/volume) // float normfactor; // float r1; // float r2; @@ -1904,7 +2080,8 @@ std::vector InsertPrecipitatePhases::normalizeRDF(std::vector rdf, // r1 = 0*finiteAdjFactor; // r2 = rdfmin*finiteAdjFactor; - // normfactor = 4.0f/3.0f*SIMPLib::Constants::k_Pi*((r2*r2*r2) - (r1*r1*r1))*numPPTfeatures*oneovervolume; + // normfactor = 4.0f/3.0f*SIMPLib::Constants::k_Pi*((r2*r2*r2) - + // (r1*r1*r1))*numPPTfeatures*oneovervolume; // rdf[0] = rdf[0]; // for (size_t i = 1; i < num_bins+2; i++) @@ -1913,7 +2090,8 @@ std::vector InsertPrecipitatePhases::normalizeRDF(std::vector rdf, // r2 = (r1 + m_StepSize); // r1 = r1*finiteAdjFactor; // r2 = r2*finiteAdjFactor; - // normfactor = 4.0f/3.0f*SIMPLib::Constants::k_Pi*((r2*r2*r2) - (r1*r1*r1))*numPPTfeatures*oneovervolume; + // normfactor = 4.0f/3.0f*SIMPLib::Constants::k_Pi*((r2*r2*r2) - + // (r1*r1*r1))*numPPTfeatures*oneovervolume; // rdf[i] = rdf[i]/normfactor; // } @@ -2044,7 +2222,8 @@ void InsertPrecipitatePhases::compare_3Ddistributions(std::vectorgetDataContainer(m_FeatureIdsArrayPath.getDataContainerName()); + // DataContainer::Pointer m = + // getDataContainerArray()->getDataContainer(m_FeatureIdsArrayPath.getDataContainerName()); StatsDataArray& statsDataArray = *(m_StatsDataArray.lock()); @@ -2151,7 +2330,7 @@ void InsertPrecipitatePhases::insert_precipitate(size_t gnum) ShapeType::Type shapeclass = static_cast(m_ShapeTypes[m_FeaturePhases[gnum]]); // Bail if the shapeclass is not one of our enumerated types - if (shapeclass >= ShapeType::Type::ShapeTypeEnd) + if(shapeclass >= ShapeType::Type::ShapeTypeEnd) { QString ss = QObject::tr("Undefined shape class in shape types array with path %1").arg(m_InputShapeTypesArrayPath.serialize()); setErrorCondition(-667); @@ -2296,7 +2475,8 @@ void InsertPrecipitatePhases::assign_voxels() yc = m_Centroids[3 * i + 1]; zc = m_Centroids[3 * i + 2]; float radcur1 = 0.0f; - // Unbounded Check for the size of shapeTypes. We assume a 1:1 with phase ; this has been checked in insert_precipitate + // Unbounded Check for the size of shapeTypes. We assume a 1:1 with phase ; + // this has been checked in insert_precipitate ShapeType::Type shapeclass = static_cast(m_ShapeTypes[m_FeaturePhases[i]]); // init any values for each of the Shape Ops @@ -2488,7 +2668,8 @@ void InsertPrecipitatePhases::assign_voxels() AttributeMatrix::Pointer cellFeatureAttrMat = m->getAttributeMatrix(getFeaturePhasesArrayPath().getAttributeMatrixName()); cellFeatureAttrMat->removeInactiveObjects(activeObjects, m_FeatureIdsPtr.lock()); - // need to update pointers after resize, but do not need to run full data check because pointers are still valid + // need to update pointers after resize, but do not need to run full data + // check because pointers are still valid updateFeatureInstancePointers(); } @@ -2643,7 +2824,10 @@ void InsertPrecipitatePhases::assign_gaps() } if(iterationCounter >= 1) { - QString ss = QObject::tr("Assign Gaps || Cycle#: %1 || Remaining Unassigned Voxel Count: %2").arg(iterationCounter).arg(gapVoxelCount); + QString ss = QObject::tr("Assign Gaps || Cycle#: %1 || Remaining " + "Unassigned Voxel Count: %2") + .arg(iterationCounter) + .arg(gapVoxelCount); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); } if(getCancel() == true) @@ -2695,7 +2879,8 @@ void InsertPrecipitatePhases::write_goal_attributes() setErrorCondition(err); DataContainer::Pointer m = getDataContainerArray()->getDataContainer(m_FeatureIdsArrayPath.getDataContainerName()); - // Make sure any directory path is also available as the user may have just typed + // Make sure any directory path is also available as the user may have just + // typed // in a path without actually creating the full path QFileInfo fi(m_CsvOutputFile); @@ -2735,7 +2920,8 @@ void InsertPrecipitatePhases::write_goal_attributes() // Print the FeatureIds Header before the rest of the headers dStream << SIMPL::FeatureData::FeatureID; - // Loop throught the list and print the rest of the headers, ignoring those we don't want + // Loop throught the list and print the rest of the headers, ignoring those we + // don't want for(QList::iterator iter = headers.begin(); iter != headers.end(); ++iter) { // Only get the array if the name does NOT match those listed @@ -2746,7 +2932,8 @@ void InsertPrecipitatePhases::write_goal_attributes() { dStream << space << (*iter); } - else // There are more than a single component so we need to add multiple header values + else // There are more than a single component so we need to add + // multiple header values { for(int k = 0; k < p->getNumberOfComponents(); ++k) { @@ -2799,20 +2986,82 @@ void InsertPrecipitatePhases::moveShapeDescriptions() names << m_EquivalentDiametersArrayName << m_Omega3sArrayName << m_AxisEulerAnglesArrayName << m_AxisLengthsArrayName << m_VolumesArrayName << m_CentroidsArrayName; AttributeMatrix::Pointer cellFeatureAttrMat = getDataContainerArray()->getAttributeMatrix(getFeaturePhasesArrayPath()); - QVector tDims(1, 0); - AttributeMatrix::Pointer shapeDescriptions = AttributeMatrix::New(tDims, "Synthetic Shape Parameters (Precipitate)", AttributeMatrix::Type::Generic); + + QList attrArrays; foreach(const QString name, names) { - IDataArray::Pointer p = cellFeatureAttrMat->removeAttributeArray(name); - size_t numTuples = p->getNumberOfTuples(); - tDims[0] = numTuples; - shapeDescriptions->resizeAttributeArrays(tDims); - shapeDescriptions->addAttributeArray(p->getName(), p); + IDataArray::Pointer arrayPtr = cellFeatureAttrMat->removeAttributeArray(name); + if(arrayPtr != IDataArray::NullPointer()) + { + attrArrays.push_back(arrayPtr); + } + } + + InsertPrecipitatePhases::SaveMethod saveMethod = static_cast(getSaveGeometricDescriptions()); + if(saveMethod == InsertPrecipitatePhases::SaveMethod::SaveToNew) + { + saveToNewAttributeMatrix(attrArrays); } - if(getSaveGeometricDescriptions()) + else if(saveMethod == InsertPrecipitatePhases::SaveMethod::AppendToExisting) { - DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getFeaturePhasesArrayPath()); - m->addAttributeMatrix(shapeDescriptions->getName(), shapeDescriptions); + appendToExistingAttributeMatrix(attrArrays); + } +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void InsertPrecipitatePhases::saveToNewAttributeMatrix(QList incomingArrays) +{ + QVector tDims(1, 0); + + AttributeMatrix::Pointer newAM = getDataContainerArray()->getAttributeMatrix(getNewAttributeMatrixPath()); + if(newAM != AttributeMatrix::NullPointer()) + { + if(incomingArrays.size() > 0) + { + size_t incomingArrayTupleCount = incomingArrays[0]->getNumberOfTuples(); + size_t newAMTupleCount = newAM->getTupleDimensions()[0]; + tDims[0] = incomingArrayTupleCount + newAMTupleCount; + newAM->resizeAttributeArrays(tDims); + } + + foreach(IDataArray::Pointer incomingArray, incomingArrays) + { + newAM->addAttributeArray(incomingArray->getName(), incomingArray); + } + } +} + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +void InsertPrecipitatePhases::appendToExistingAttributeMatrix(QList incomingArrays) +{ + QVector tDims(1, 0); + + AttributeMatrix::Pointer existingAM = getDataContainerArray()->getAttributeMatrix(getSelectedAttributeMatrixPath()); + if(existingAM != AttributeMatrix::NullPointer()) + { + size_t existingAMTupleCount = existingAM->getTupleDimensions()[0]; + if(incomingArrays.size() > 0) + { + size_t incomingArrayTupleCount = incomingArrays[0]->getNumberOfTuples(); + tDims[0] = incomingArrayTupleCount; + existingAM->resizeAttributeArrays(tDims); + } + + foreach(IDataArray::Pointer incomingArray, incomingArrays) + { + int err = 0; + IDataArray::Pointer existingArray = existingAM->getPrereqIDataArray(this, incomingArray->getName(), err); + if(existingArray != IDataArray::NullPointer()) + { + // ATTENTION: This "append" code is making the assumption that there will be 0's preceding the precipitate phase data. The number of preceding + // 0's is equal to the number of elements in the existing array that will be appended to. If this changes, then this "append" code needs to be updated! + existingArray->copyFromArray(existingAMTupleCount, incomingArray, existingAMTupleCount, existingArray->getNumberOfTuples() - existingAMTupleCount); + } + } } } diff --git a/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/InsertPrecipitatePhases.h b/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/InsertPrecipitatePhases.h index 991aab855c..88c9458c95 100644 --- a/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/InsertPrecipitatePhases.h +++ b/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/InsertPrecipitatePhases.h @@ -73,6 +73,15 @@ class InsertPrecipitatePhases : public AbstractFilter virtual ~InsertPrecipitatePhases(); + using EnumType = unsigned int; + + enum class SaveMethod : EnumType + { + SaveToNew = 0, + AppendToExisting = 1, + DoNotSave = 2 + }; + SIMPL_INSTANCE_STRING_PROPERTY(ClusteringListArrayName) SIMPL_INSTANCE_STRING_PROPERTY(ErrorOutputFile) @@ -146,8 +155,14 @@ class InsertPrecipitatePhases : public AbstractFilter SIMPL_FILTER_PARAMETER(DataArrayPath, NumFeaturesArrayPath) Q_PROPERTY(DataArrayPath NumFeaturesArrayPath READ getNumFeaturesArrayPath WRITE setNumFeaturesArrayPath) - SIMPL_FILTER_PARAMETER(bool, SaveGeometricDescriptions) - Q_PROPERTY(bool SaveGeometricDescriptions READ getSaveGeometricDescriptions WRITE setSaveGeometricDescriptions) + SIMPL_FILTER_PARAMETER(int, SaveGeometricDescriptions) + Q_PROPERTY(int SaveGeometricDescriptions READ getSaveGeometricDescriptions WRITE setSaveGeometricDescriptions) + + SIMPL_FILTER_PARAMETER(DataArrayPath, NewAttributeMatrixPath) + Q_PROPERTY(DataArrayPath NewAttributeMatrixPath READ getNewAttributeMatrixPath WRITE setNewAttributeMatrixPath) + + SIMPL_FILTER_PARAMETER(DataArrayPath, SelectedAttributeMatrixPath) + Q_PROPERTY(DataArrayPath SelectedAttributeMatrixPath READ getSelectedAttributeMatrixPath WRITE setSelectedAttributeMatrixPath) /** * @brief getCompiledLibraryName Reimplemented from @see AbstractFilter class @@ -505,6 +520,16 @@ class InsertPrecipitatePhases : public AbstractFilter */ void updateFeatureInstancePointers(); + /** + * @brief saveToNewAttributeMatrix + */ + void saveToNewAttributeMatrix(QList incomingArrays); + + /** + * @brief appendToExistingAttributeMatrix + */ + void appendToExistingAttributeMatrix(QList incomingArrays); + InsertPrecipitatePhases(const InsertPrecipitatePhases&); // Copy Constructor Not Implemented void operator=(const InsertPrecipitatePhases&); // Operator '=' Not Implemented }; diff --git a/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/PackPrimaryPhases.cpp b/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/PackPrimaryPhases.cpp index 934aa3062f..e0c9edfc40 100644 --- a/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/PackPrimaryPhases.cpp +++ b/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/PackPrimaryPhases.cpp @@ -52,11 +52,13 @@ #include "SIMPLib/Common/ShapeType.h" #include "SIMPLib/DataArrays/NeighborList.hpp" #include "SIMPLib/FilterParameters/AbstractFilterParametersReader.h" +#include "SIMPLib/FilterParameters/AttributeMatrixCreationFilterParameter.h" #include "SIMPLib/FilterParameters/AttributeMatrixSelectionFilterParameter.h" #include "SIMPLib/FilterParameters/BooleanFilterParameter.h" #include "SIMPLib/FilterParameters/DataArraySelectionFilterParameter.h" #include "SIMPLib/FilterParameters/InputFileFilterParameter.h" #include "SIMPLib/FilterParameters/LinkedBooleanFilterParameter.h" +#include "SIMPLib/FilterParameters/LinkedChoicesFilterParameter.h" #include "SIMPLib/FilterParameters/OutputFileFilterParameter.h" #include "SIMPLib/FilterParameters/SeparatorFilterParameter.h" #include "SIMPLib/FilterParameters/StringFilterParameter.h" @@ -93,8 +95,7 @@ class AssignVoxelsGapsImpl FloatArrayType::Pointer ellipfuncsPtr; public: - AssignVoxelsGapsImpl(int64_t* dimensions, float* resolution, int32_t* featureIds, float* radCur, - float* xx, ShapeOps* shapeOps, float gA[3][3], float* size, int32_t cur_feature, + AssignVoxelsGapsImpl(int64_t* dimensions, float* resolution, int32_t* featureIds, float* radCur, float* xx, ShapeOps* shapeOps, float gA[3][3], float* size, int32_t cur_feature, Int32ArrayType::Pointer newowners, FloatArrayType::Pointer ellipfuncs) : m_FeatureIds(featureIds) , m_ShapeOps(shapeOps) @@ -233,6 +234,8 @@ class AssignVoxelsGapsImpl // Include the MOC generated file for this class #include "moc_PackPrimaryPhases.cpp" +const QString PrimaryPhaseSyntheticShapeParametersName("Synthetic Shape Parameters (Primary Phase)"); + // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- @@ -257,6 +260,7 @@ PackPrimaryPhases::PackPrimaryPhases() , m_PeriodicBoundaries(false) , m_WriteGoalAttributes(false) , m_SaveGeometricDescriptions(false) +, m_NewAttributeMatrixPath(SIMPL::Defaults::SyntheticVolumeDataContainerName, PrimaryPhaseSyntheticShapeParametersName, "") , m_NeighborhoodsArrayName(SIMPL::FeatureData::Neighborhoods) , m_CentroidsArrayName(SIMPL::FeatureData::Centroids) , m_VolumesArrayName(SIMPL::FeatureData::Volumes) @@ -367,8 +371,7 @@ void PackPrimaryPhases::setupFilterParameters() parameters.push_back(SIMPL_NEW_AM_SELECTION_FP("Cell Attribute Matrix", OutputCellAttributeMatrixPath, FilterParameter::RequiredArray, PackPrimaryPhases, req)); } { - DataArraySelectionFilterParameter::RequirementType req = - DataArraySelectionFilterParameter::CreateRequirement(SIMPL::TypeNames::Bool, 1, AttributeMatrix::Type::Cell, IGeometry::Type::Image); + DataArraySelectionFilterParameter::RequirementType req = DataArraySelectionFilterParameter::CreateRequirement(SIMPL::TypeNames::Bool, 1, AttributeMatrix::Type::Cell, IGeometry::Type::Image); parameters.push_back(SIMPL_NEW_DA_SELECTION_FP("Mask", MaskArrayPath, FilterParameter::RequiredArray, PackPrimaryPhases, req)); } parameters.push_back(SeparatorFilterParameter::New("Cell Ensemble Data", FilterParameter::RequiredArray)); @@ -430,7 +433,36 @@ void PackPrimaryPhases::setupFilterParameters() parameters.push_back(SIMPL_NEW_LINKED_BOOL_FP("Write Goal Attributes", WriteGoalAttributes, FilterParameter::Parameter, PackPrimaryPhases, linkedProps)); parameters.push_back(SIMPL_NEW_OUTPUT_FILE_FP("Goal Attribute CSV File", CsvOutputFile, FilterParameter::Parameter, PackPrimaryPhases, "*.csv", "Comma Separated Data")); - parameters.push_back(SIMPL_NEW_BOOL_FP("Save Shape Description Arrays", SaveGeometricDescriptions, FilterParameter::Parameter, PackPrimaryPhases)); + { + LinkedChoicesFilterParameter::Pointer parameter = LinkedChoicesFilterParameter::New(); + parameter->setHumanLabel("Save Shape Description Arrays"); + parameter->setPropertyName("SaveGeometricDescriptions"); + parameter->setSetterCallback(SIMPL_BIND_SETTER(PackPrimaryPhases, this, SaveGeometricDescriptions)); + parameter->setGetterCallback(SIMPL_BIND_GETTER(PackPrimaryPhases, this, SaveGeometricDescriptions)); + + QVector choices; + choices.push_back("Save To New Attribute Matrix"); + choices.push_back("Append To Existing Attribute Matrix"); + choices.push_back("Do Not Save"); + parameter->setChoices(choices); + QStringList linkedProps; + linkedProps << "NewAttributeMatrixPath" + << "SelectedAttributeMatrixPath"; + parameter->setLinkedProperties(linkedProps); + parameter->setEditable(false); + parameter->setCategory(FilterParameter::Parameter); + parameters.push_back(parameter); + } + + { + AttributeMatrixCreationFilterParameter::RequirementType req; + parameters.push_back(SIMPL_NEW_AM_CREATION_FP("New Attribute Matrix", NewAttributeMatrixPath, FilterParameter::Parameter, PackPrimaryPhases, req, 0)); + } + + { + AttributeMatrixSelectionFilterParameter::RequirementType req = AttributeMatrixSelectionFilterParameter::CreateRequirement(AttributeMatrix::Category::Feature); + parameters.push_back(SIMPL_NEW_AM_SELECTION_FP("Selected Attribute Matrix", SelectedAttributeMatrixPath, FilterParameter::Parameter, PackPrimaryPhases, req, 1)); + } #if PPP_SHOW_DEBUG_OUTPUTS parameters.push_back(InputFileFilterParameter::New("Debug VTK File", "VtkOutputFile", getVtkOutputFile(), FilterParameter::Parameter, "*.vtk", "VTK File")); @@ -625,6 +657,17 @@ void PackPrimaryPhases::dataCheck() QVector tDims(1, 0); m->createNonPrereqAttributeMatrix(this, getOutputCellFeatureAttributeMatrixName(), tDims, AttributeMatrix::Type::CellFeature); + PackPrimaryPhases::SaveMethod saveMethod = static_cast(getSaveGeometricDescriptions()); + if(saveMethod == PackPrimaryPhases::SaveMethod::SaveToNew) + { + m->createNonPrereqAttributeMatrix(this, getNewAttributeMatrixPath().getAttributeMatrixName(), tDims, AttributeMatrix::Type::CellFeature); + } + else if(saveMethod == PackPrimaryPhases::SaveMethod::AppendToExisting) + { + int err = 0; + m->getPrereqAttributeMatrix(this, getSelectedAttributeMatrixPath().getAttributeMatrixName(), err); + } + AttributeMatrix::Pointer outEnsembleAttrMat = AttributeMatrix::NullPointer(); if(m->doesAttributeMatrixExist(getOutputCellEnsembleAttributeMatrixName())) { @@ -860,7 +903,6 @@ void PackPrimaryPhases::execute() return; } - moveShapeDescriptions(); DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getOutputCellAttributeMatrixPath().getDataContainerName()); @@ -1810,7 +1852,7 @@ void PackPrimaryPhases::generateFeature(int32_t phase, Feature_t* feature, uint3 float mf = omega3[0]->getValue(diameter); float s = omega3[1]->getValue(diameter); float omega3f = static_cast(rg.genrand_beta(mf, s)); - if (shapeclass == static_cast(ShapeType::Type::Ellipsoid)) + if(shapeclass == static_cast(ShapeType::Type::Ellipsoid)) { omega3f = 1; } @@ -2450,7 +2492,7 @@ void PackPrimaryPhases::insertFeature(size_t gnum) uint32_t shapeclass = m_ShapeTypes[m_FeaturePhases[gnum]]; // Bail if the shapeclass is not one of our enumerated types - if (shapeclass >= static_cast(ShapeType::Type::ShapeTypeEnd)) + if(shapeclass >= static_cast(ShapeType::Type::ShapeTypeEnd)) { QString ss = QObject::tr("Undefined shape class in shape types array with path %1").arg(m_InputShapeTypesArrayPath.serialize()); setErrorCondition(-78009); @@ -3405,25 +3447,64 @@ void PackPrimaryPhases::moveShapeDescriptions() DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getOutputCellAttributeMatrixPath().getDataContainerName()); QStringList names; - names << m_EquivalentDiametersArrayName << m_Omega3sArrayName << m_AxisEulerAnglesArrayName - << m_AxisLengthsArrayName << m_VolumesArrayName - << m_CentroidsArrayName << m_NeighborhoodsArrayName; - + names << m_EquivalentDiametersArrayName << m_Omega3sArrayName << m_AxisEulerAnglesArrayName << m_AxisLengthsArrayName << m_VolumesArrayName << m_CentroidsArrayName << m_NeighborhoodsArrayName; AttributeMatrix::Pointer cellFeatureAttrMat = m->getAttributeMatrix(m_OutputCellFeatureAttributeMatrixName); QVector tDims(1, 0); - AttributeMatrix::Pointer shapeDescriptions = AttributeMatrix::New(tDims, "Synthetic Shape Parameters (Primary Phase)", AttributeMatrix::Type::Generic); + + QList attrArrays; foreach(const QString name, names) { - IDataArray::Pointer p = cellFeatureAttrMat->removeAttributeArray(name); - size_t numTuples = p->getNumberOfTuples(); - tDims[0] = numTuples; - shapeDescriptions->resizeAttributeArrays(tDims); - shapeDescriptions->addAttributeArray(p->getName(), p); + IDataArray::Pointer arrayPtr = cellFeatureAttrMat->removeAttributeArray(name); + if(arrayPtr != IDataArray::NullPointer()) + { + attrArrays.push_back(arrayPtr); + } + } + + PackPrimaryPhases::SaveMethod saveMethod = static_cast(getSaveGeometricDescriptions()); + if(saveMethod == PackPrimaryPhases::SaveMethod::SaveToNew) + { + AttributeMatrix::Pointer newAM = getDataContainerArray()->getAttributeMatrix(getNewAttributeMatrixPath()); + if(newAM != AttributeMatrix::NullPointer()) + { + if(attrArrays.size() > 0) + { + size_t incomingArrayTupleCount = attrArrays[0]->getNumberOfTuples(); + size_t newAMTupleCount = newAM->getTupleDimensions()[0]; + tDims[0] = incomingArrayTupleCount + newAMTupleCount; + newAM->resizeAttributeArrays(tDims); + } + + foreach(IDataArray::Pointer incomingArray, attrArrays) + { + newAM->addAttributeArray(incomingArray->getName(), incomingArray); + } + } } - if(getSaveGeometricDescriptions()) + else if(saveMethod == PackPrimaryPhases::SaveMethod::AppendToExisting) { - m->addAttributeMatrix(shapeDescriptions->getName(), shapeDescriptions); + AttributeMatrix::Pointer existingAM = getDataContainerArray()->getAttributeMatrix(getSelectedAttributeMatrixPath()); + if(existingAM != AttributeMatrix::NullPointer()) + { + if(attrArrays.size() > 0) + { + size_t incomingArrayTupleCount = attrArrays[0]->getNumberOfTuples(); + size_t existingAMTupleCount = existingAM->getTupleDimensions()[0]; + tDims[0] = incomingArrayTupleCount + existingAMTupleCount; + existingAM->resizeAttributeArrays(tDims); + } + + foreach(IDataArray::Pointer incomingArray, attrArrays) + { + int err = 0; + IDataArray::Pointer existingArray = existingAM->getPrereqIDataArray(this, incomingArray->getName(), err); + if(existingArray != IDataArray::NullPointer()) + { + existingArray->copyFromArray(tDims[0], incomingArray); + } + } + } } } diff --git a/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/PackPrimaryPhases.h b/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/PackPrimaryPhases.h index 9883b750e1..80a8e1d411 100644 --- a/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/PackPrimaryPhases.h +++ b/Source/Plugins/SyntheticBuilding/SyntheticBuildingFilters/PackPrimaryPhases.h @@ -68,6 +68,15 @@ class PackPrimaryPhases : public AbstractFilter virtual ~PackPrimaryPhases(); + using EnumType = unsigned int; + + enum class SaveMethod : EnumType + { + SaveToNew = 0, + AppendToExisting = 1, + DoNotSave = 2 + }; + SIMPL_FILTER_PARAMETER(DataArrayPath, OutputCellAttributeMatrixPath) Q_PROPERTY(DataArrayPath OutputCellAttributeMatrixPath READ getOutputCellAttributeMatrixPath WRITE setOutputCellAttributeMatrixPath) @@ -122,8 +131,14 @@ class PackPrimaryPhases : public AbstractFilter SIMPL_FILTER_PARAMETER(bool, WriteGoalAttributes) Q_PROPERTY(bool WriteGoalAttributes READ getWriteGoalAttributes WRITE setWriteGoalAttributes) - SIMPL_FILTER_PARAMETER(bool, SaveGeometricDescriptions) - Q_PROPERTY(bool SaveGeometricDescriptions READ getSaveGeometricDescriptions WRITE setSaveGeometricDescriptions) + SIMPL_FILTER_PARAMETER(int, SaveGeometricDescriptions) + Q_PROPERTY(int SaveGeometricDescriptions READ getSaveGeometricDescriptions WRITE setSaveGeometricDescriptions) + + SIMPL_FILTER_PARAMETER(DataArrayPath, NewAttributeMatrixPath) + Q_PROPERTY(DataArrayPath NewAttributeMatrixPath READ getNewAttributeMatrixPath WRITE setNewAttributeMatrixPath) + + SIMPL_FILTER_PARAMETER(DataArrayPath, SelectedAttributeMatrixPath) + Q_PROPERTY(DataArrayPath SelectedAttributeMatrixPath READ getSelectedAttributeMatrixPath WRITE setSelectedAttributeMatrixPath) /** * @brief getCompiledLibraryName Reimplemented from @see AbstractFilter class