text: /* ============================================================================
   * Copyright (c) 2009-2016 BlueQuartz Software, LLC
   *
   * 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
   * list of conditions and the following disclaimer.
   *
   * Redistributions in binary form must reproduce the above copyright notice, this
   * 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
   * without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
   * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * The code contained herein was partially funded by the following contracts:
   *    United States Air Force Prime Contract FA8650-07-D-5800
   *    United States Air Force Prime Contract FA8650-10-D-5210
   *    United States Prime Contract Navy N00173-07-C-2068
   *
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  #include "LinkFeatureMapToElementArray.h"
  
  #include <QtCore/QTextStream>
  
  #include "SIMPLib/SIMPLibVersion.h"
  #include "SIMPLib/Common/Constants.h"
  #include "SIMPLib/DataContainers/DataContainer.h"
  #include "SIMPLib/DataContainers/DataContainerArray.h"
  #include "SIMPLib/FilterParameters/AbstractFilterParametersReader.h"
  #include "SIMPLib/FilterParameters/DataArraySelectionFilterParameter.h"
  #include "SIMPLib/FilterParameters/LinkedPathCreationFilterParameter.h"
  #include "SIMPLib/FilterParameters/SeparatorFilterParameter.h"
  #include "SIMPLib/FilterParameters/StringFilterParameter.h"
  
  enum createdPathID : RenameDataPath::DataID_t
  {
    AttributeMatrixID = 1,
    DataArrayID
  };
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  LinkFeatureMapToElementArray::LinkFeatureMapToElementArray() = default;
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  LinkFeatureMapToElementArray::~LinkFeatureMapToElementArray() = default;
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  void LinkFeatureMapToElementArray::setupFilterParameters()
  {
    FilterParameterVectorType parameters;
    parameters.push_back(SeparatorFilterParameter::Create("Element Data", FilterParameter::Category::RequiredArray));
    {
      DataArraySelectionFilterParameter::RequirementType req = DataArraySelectionFilterParameter::CreateCategoryRequirement(SIMPL::TypeNames::Int32, 1, AttributeMatrix::Category::Element);
      parameters.push_back(SIMPL_NEW_DA_SELECTION_FP("Element Attribute Array to Link", SelectedCellArrayPath, FilterParameter::Category::RequiredArray, LinkFeatureMapToElementArray, req));
    }
    parameters.push_back(SeparatorFilterParameter::Create("Feature Data", FilterParameter::Category::CreatedArray));
    parameters.push_back(
        SIMPL_NEW_AM_WITH_LINKED_DC_FP("Feature Attribute Matrix", CellFeatureAttributeMatrixName, SelectedCellArrayPath, FilterParameter::Category::CreatedArray, LinkFeatureMapToElementArray));
    parameters.push_back(
        SIMPL_NEW_DA_WITH_LINKED_AM_FP("Active", ActiveArrayName, SelectedCellArrayPath, CellFeatureAttributeMatrixName, FilterParameter::Category::CreatedArray, LinkFeatureMapToElementArray));
  
    setFilterParameters(parameters);
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  void LinkFeatureMapToElementArray::readFilterParameters(AbstractFilterParametersReader* reader, int index)
  {
    reader->openFilterGroup(this, index);
    setCellFeatureAttributeMatrixName(reader->readString("CellFeatureAttributeMatrixName", getCellFeatureAttributeMatrixName()));
    setActiveArrayName(reader->readString("ActiveArrayName", getActiveArrayName()));
    setSelectedCellArrayPath(reader->readDataArrayPath("SelectedCellArrayPath", getSelectedCellArrayPath()));
    reader->closeFilterGroup();
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  void LinkFeatureMapToElementArray::updateFeatureInstancePointers()
  {
    clearErrorCode();
    clearWarningCode();
  
    if(nullptr != m_ActivePtr.lock())
    {
      m_Active = m_ActivePtr.lock()->getPointer(0);
    } /* Now assign the raw pointer to data from the DataArray<T> object */
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  void LinkFeatureMapToElementArray::initialize()
  {
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  void LinkFeatureMapToElementArray::dataCheck()
  {
    clearErrorCode();
    clearWarningCode();
    DataArrayPath tempPath;
  
    DataContainer::Pointer m = getDataContainerArray()->getPrereqDataContainer(this, getSelectedCellArrayPath().getDataContainerName(), false);
    if(getErrorCode() < 0 || nullptr == m.get())
    {
      return;
    }
  
    std::vector<size_t> tDims(1, 0);
    m->createNonPrereqAttributeMatrix(this, getCellFeatureAttributeMatrixName(), tDims, AttributeMatrix::Type::CellFeature, AttributeMatrixID);
  
    std::vector<size_t> cDims(1, 1);
    m_SelectedCellDataPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int32_t>>(this, getSelectedCellArrayPath(), cDims);
    if(nullptr != m_SelectedCellDataPtr.lock())
    {
      m_SelectedCellData = m_SelectedCellDataPtr.lock()->getPointer(0);
    } /* Now assign the raw pointer to data from the DataArray<T> object */
  
    if(getErrorCode() < 0)
    {
      return;
    }
  
    tempPath.update(getSelectedCellArrayPath().getDataContainerName(), getCellFeatureAttributeMatrixName(), getActiveArrayName());
    m_ActivePtr = getDataContainerArray()->createNonPrereqArrayFromPath<DataArray<bool>>(this, tempPath, false, cDims, "", DataArrayID);
    if(nullptr != m_ActivePtr.lock())
    {
      m_Active = m_ActivePtr.lock()->getPointer(0);
    } /* Now assign the raw pointer to data from the DataArray<T> object */
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  void LinkFeatureMapToElementArray::execute()
  {
    dataCheck();
    if(getErrorCode() < 0)
    {
      return;
    }
  
    DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getSelectedCellArrayPath().getDataContainerName());
    size_t totalPoints = m_SelectedCellDataPtr.lock()->getNumberOfTuples();
  
    int32_t maxIndex = 0;
    std::vector<bool> active;
    for(size_t i = 0; i < totalPoints; i++)
    {
      int32_t index = m_SelectedCellData[i];
      if((index + 1) > maxIndex)
      {
        active.resize(index + 1);
        active[index] = true;
        maxIndex = index + 1;
      }
    }
  
    std::vector<size_t> tDims(1, maxIndex);
    m->getAttributeMatrix(getCellFeatureAttributeMatrixName())->resizeAttributeArrays(tDims);
    updateFeatureInstancePointers();
  
    for(int32_t i = 0; i < maxIndex; i++)
    {
      m_Active[i] = active[i];
    }
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  AbstractFilter::Pointer LinkFeatureMapToElementArray::newFilterInstance(bool copyFilterParameters) const
  {
    LinkFeatureMapToElementArray::Pointer filter = LinkFeatureMapToElementArray::New();
    if(copyFilterParameters)
    {
      copyFilterParameterInstanceVariables(filter.get());
    }
    return filter;
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  QString LinkFeatureMapToElementArray::getCompiledLibraryName() const
  {
    return Core::CoreBaseName;
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  QString LinkFeatureMapToElementArray::getBrandingString() const
  {
    return "SIMPLib Core Filter";
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  QString LinkFeatureMapToElementArray::getFilterVersion() const
  {
    QString version;
    QTextStream vStream(&version);
    vStream << SIMPLib::Version::Major() << "." << SIMPLib::Version::Minor() << "." << SIMPLib::Version::Patch();
    return version;
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  QString LinkFeatureMapToElementArray::getGroupName() const
  {
    return SIMPL::FilterGroups::CoreFilters;
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  QUuid LinkFeatureMapToElementArray::getUuid() const
  {
    return QUuid("{0e1c45f6-ed7a-5279-8a5c-a2d5cc6bfead}");
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  QString LinkFeatureMapToElementArray::getSubGroupName() const
  {
    return SIMPL::FilterSubGroups::MemoryManagementFilters;
  }
  
  // -----------------------------------------------------------------------------
  //
  // -----------------------------------------------------------------------------
  QString LinkFeatureMapToElementArray::getHumanLabel() const
  {
    return "Link Feature Attribute Matrix to Element Attribute Array";
  }
  
  // -----------------------------------------------------------------------------
  LinkFeatureMapToElementArray::Pointer LinkFeatureMapToElementArray::NullPointer()
  {
    return Pointer(static_cast<Self*>(nullptr));
  }
  
  // -----------------------------------------------------------------------------
  std::shared_ptr<LinkFeatureMapToElementArray> LinkFeatureMapToElementArray::New()
  {
    struct make_shared_enabler : public LinkFeatureMapToElementArray
    {
    };
    std::shared_ptr<make_shared_enabler> val = std::make_shared<make_shared_enabler>();
    val->setupFilterParameters();
    return val;
  }
  
  // -----------------------------------------------------------------------------
  QString LinkFeatureMapToElementArray::getNameOfClass() const
  {
    return QString("LinkFeatureMapToElementArray");
  }
  
  // -----------------------------------------------------------------------------
  QString LinkFeatureMapToElementArray::ClassName()
  {
    return QString("LinkFeatureMapToElementArray");
  }
  
  // -----------------------------------------------------------------------------
  void LinkFeatureMapToElementArray::setCellFeatureAttributeMatrixName(const QString& value)
  {
    m_CellFeatureAttributeMatrixName = value;
  }
  
  // -----------------------------------------------------------------------------
  QString LinkFeatureMapToElementArray::getCellFeatureAttributeMatrixName() const
  {
    return m_CellFeatureAttributeMatrixName;
  }
  
  // -----------------------------------------------------------------------------
  void LinkFeatureMapToElementArray::setSelectedCellArrayPath(const DataArrayPath& value)
  {
    m_SelectedCellArrayPath = value;
  }
  
  // -----------------------------------------------------------------------------
  DataArrayPath LinkFeatureMapToElementArray::getSelectedCellArrayPath() const
  {
    return m_SelectedCellArrayPath;
  }
  
  // -----------------------------------------------------------------------------
  void LinkFeatureMapToElementArray::setActiveArrayName(const QString& value)
  {
    m_ActiveArrayName = value;
  }
  
  // -----------------------------------------------------------------------------
  QString LinkFeatureMapToElementArray::getActiveArrayName() const
  {
    return m_ActiveArrayName;
  }
  