void writePointScalarData(DataContainer::Pointer dc, const QString& vertexAttributeMatrixName, const QString& dataName, const QString& dataType,
                          bool writeBinaryData, FILE* vtkFile, int nT)
{
  IDataArray::Pointer data = dc->getAttributeMatrix(vertexAttributeMatrixName)->getAttributeArray(dataName);
  QString ss;
  if (NULL != data.get())
  {
    T* m = reinterpret_cast<T*>(data->getVoidPointer(0));
    fprintf(vtkFile, "\n");
    fprintf(vtkFile, "SCALARS %s %s\n", dataName.toLatin1().data(), dataType.toLatin1().data());
    fprintf(vtkFile, "LOOKUP_TABLE default\n");
    for(int i = 0; i < nT; ++i)
    {
      T swapped = 0x00;
      if(writeBinaryData == true)
      {
        swapped = static_cast<T>(m[i]);
        SIMPLib::Endian::FromSystemToBig::convert(swapped);
        fwrite(&swapped, sizeof(T), 1, vtkFile);
      }
      else
      {

        ss = QString::number(m[i]) + " ";
        fprintf(vtkFile, "%s ", ss.toLatin1().data());
        //if (i%50 == 0)
        { fprintf(vtkFile, "\n"); }
      }

    }
  }
}
Exemple #2
0
    /**
     * @brief
     * @param parentId
     * @return
     */
    virtual int readH5Data(hid_t parentId)
    {
      int err = 0;

      resize(0);
      IDataArray::Pointer p = H5DataArrayReader::ReadIDataArray(parentId, getName());
      if (p.get() == NULL)
      {
        return -1;
      }
      m_Array = reinterpret_cast<T*>(p->getVoidPointer(0));
      m_Size = p->getSize();
      m_OwnsData = true;
      m_MaxId = (m_Size == 0) ? 0 : m_Size - 1;
      m_IsAllocated = true;
      m_Name = p->getName();
      m_NumTuples = p->getNumberOfTuples();
      m_CompDims = p->getComponentDimensions();
      m_NumComponents = p->getNumberOfComponents();

      // Tell the intermediate DataArray to release ownership of the data as we are going to be responsible
      // for deleting the memory
      p->releaseOwnership();
      return err;
    }
void writeCellScalarData(DataContainer::Pointer dc, const QString& faceAttributeMatrixName, const QString& dataName, const QString& dataType,
                         bool writeBinaryData, FILE* vtkFile, QMap<int32_t, int32_t>& featureIds, int32_t* m_SurfaceMeshFaceLabels)
{
  TriangleGeom::Pointer triangleGeom = dc->getGeometryAs<TriangleGeom>();

  int64_t numTriangles = triangleGeom->getNumberOfTris();
  IDataArray::Pointer data = dc->getAttributeMatrix(faceAttributeMatrixName)->getAttributeArray(dataName);

  QString ss;
  if (NULL != data.get())
  {
    int32_t totalCellsWritten = 0;

    T* m = reinterpret_cast<T*>(data->getVoidPointer(0));
    fprintf(vtkFile, "\n");
    fprintf(vtkFile, "SCALARS %s %s 1\n", dataName.toLatin1().data(), dataType.toLatin1().data());
    fprintf(vtkFile, "LOOKUP_TABLE default\n");
    // Loop over all the features
    for(QMap<int32_t, int32_t>::iterator featureIter = featureIds.begin(); featureIter != featureIds.end(); ++featureIter)
    {
      int32_t gid = featureIter.key(); // The current Feature Id
      size_t size = featureIter.value(); // The number of triangles for this feature id
      std::vector<T> buffer(size, 0);
      totalCellsWritten += size;
      size_t index = 0;

      for (int j = 0; j < numTriangles; j++)
      {
        if (m_SurfaceMeshFaceLabels[j * 2] != gid && m_SurfaceMeshFaceLabels[j * 2 + 1] != gid) { continue; }
        // Get the data
        T s0 = static_cast<T>(m[j]);
        if (m_SurfaceMeshFaceLabels[j * 2 + 1] == gid)
        { s0 = s0 * -1; }


        // Write the values to the buffer after an Endian swap.
        if(writeBinaryData == true)
        {
          SIMPLib::Endian::FromSystemToBig::convert(s0);
          buffer[index] = s0;
          ++index;
        }
        else
        {

          ss = QString::number(s0);
          fprintf(vtkFile, "%s\n", ss.toLatin1().data());
        }
      }

      // Write the Buffer
      if(writeBinaryData == true)
      {
        fwrite(&(buffer.front()), sizeof(T), size, vtkFile);
      }
    }
  }

}
int testCase1_Execute(const QString& name, int scalarType)
{
  int err = 0;
  int dataArraySize = ARRAY_SIZE * N;
  int junkArraySize = 0;
  int skipHeaderBytes = 0;
  qDebug() << "Testing case 1: " << name << " with num comps " << N;


  // Allocate an array, and get the dataArray from that array
  boost::shared_array<T> array(new T[dataArraySize]); // This makes sure our allocated array is deleted when we leave
  T* dataArray = array.get();

  // Write some data into the data array
  for(size_t i = 0; i < dataArraySize; ++i)
  {
    dataArray[i] = static_cast<T>(i);
  }

  // Create junkArray and set it to NULL because there is no junk in this test case
  T* junkArray = NULL;

  // Create the file and write to it.  If any of the information is wrong, the result will be false
  bool result = createAndWriteToFile(dataArray, dataArraySize, junkArray, junkArraySize, Detail::None);

  // Test to make sure that the file was created and written to successfully
  DREAM3D_REQUIRED(result, == , true)

  // Create the data container
  VolumeDataContainer::Pointer m = VolumeDataContainer::New();
  m->setName(DREAM3D::Defaults::DataContainerName);
  DataContainerArray::Pointer dca = DataContainerArray::New();
  dca->pushBack(m);

  // Create the filter, passing in the skipHeaderBytes
  RawBinaryReader::Pointer filt = createRawBinaryReaderFilter(scalarType, N, skipHeaderBytes);
  filt->setDataContainerArray(dca);

  // Preflight, get the error condition, and check that there are no errors
  filt->preflight();
  err = filt->getErrorCondition();
  DREAM3D_REQUIRED(err, >= , 0)

  // Execute the filter, check that there are no errors, and compare the data
  filt->execute();
  DREAM3D_REQUIRED(err, >= , 0)

  IDataArray::Pointer iData = m->getAttributeMatrix(getCellAttributeMatrixName())->getAttributeArray("Test_Array");
  T* data = reinterpret_cast<T*>(iData->getVoidPointer(0));
  T d, p;
  for(size_t i = 0; i < dataArraySize; ++i)
  {
    d = data[i];
    p = dataArray[i];
    DREAM3D_REQUIRE_EQUAL(d, p)
  }
  return err;
}
void writeCellNormalData(DataContainer::Pointer dc, const QString& faceAttributeMatrixName, const QString& dataName, const QString& dataType,
                         bool writeBinaryData, bool writeConformalMesh,
                         FILE* vtkFile, int nT)
{
  IDataArray::Pointer data = dc->getAttributeMatrix(faceAttributeMatrixName)->getAttributeArray(dataName);
  QString buf;
  QTextStream ss(&buf);
  if (NULL != data.get())
  {
    T* m = reinterpret_cast<T*>(data->getVoidPointer(0));
    fprintf(vtkFile, "\n");
    fprintf(vtkFile, "NORMALS %s %s\n", dataName.toLatin1().data(), dataType.toLatin1().data());
    for(int i = 0; i < nT; ++i)
    {
      T s0 = 0x00;
      T s1 = 0x00;
      T s2 = 0x00;
      if(writeBinaryData == true)
      {
        s0 = static_cast<T>(m[i * 3 + 0]);
        s1 = static_cast<T>(m[i * 3 + 1]);
        s2 = static_cast<T>(m[i * 3 + 2]);
        SIMPLib::Endian::FromSystemToBig::convert(s0);
        SIMPLib::Endian::FromSystemToBig::convert(s1);
        SIMPLib::Endian::FromSystemToBig::convert(s2);
        fwrite(&s0, sizeof(T), 1, vtkFile);
        fwrite(&s1, sizeof(T), 1, vtkFile);
        fwrite(&s2, sizeof(T), 1, vtkFile);
        if(false == writeConformalMesh)
        {
          s0 = static_cast<T>(m[i * 3 + 0]) * -1.0;
          s1 = static_cast<T>(m[i * 3 + 1]) * -1.0;
          s2 = static_cast<T>(m[i * 3 + 2]) * -1.0;
          SIMPLib::Endian::FromSystemToBig::convert(s0);
          SIMPLib::Endian::FromSystemToBig::convert(s1);
          SIMPLib::Endian::FromSystemToBig::convert(s2);
          fwrite(&s0, sizeof(T), 1, vtkFile);
          fwrite(&s1, sizeof(T), 1, vtkFile);
          fwrite(&s2, sizeof(T), 1, vtkFile);
        }
      }
      else
      {

        ss << m[i * 3 + 0] << " " << m[i * 3 + 1] << " " << m[i * 3 + 2] << " ";
        if(false == writeConformalMesh)
        {
          ss << -1.0 * m[i * 3 + 0] << " " << -1.0 * m[i * 3 + 1] << " " << -1.0 * m[i * 3 + 2] << " ";
        }
        fprintf(vtkFile, "%s ", buf.toLatin1().data());
        buf.clear();
        if (i % 50 == 0) { fprintf(vtkFile, "\n"); }
      }
    }
  }
}
Exemple #6
0
 /**
  * @brief deepCopy
  * @param forceNoAllocate
  * @return
  */
 virtual IDataArray::Pointer deepCopy(bool forceNoAllocate = false)
 {
   IDataArray::Pointer daCopy = createNewArray(getNumberOfTuples(), getComponentDimensions(), getName(), m_IsAllocated);
   if(m_IsAllocated == true && forceNoAllocate == false)
   {
     T* src = getPointer(0);
     void* dest = daCopy->getVoidPointer(0);
     size_t totalBytes = (getNumberOfTuples() * getNumberOfComponents() * sizeof(T));
     ::memcpy(dest, src, totalBytes);
   }
   return daCopy;
 }
void writeCellVectorData(DataContainer::Pointer dc, const QString& faceAttributeMatrixName, const QString& dataName, const QString& dataType,
                         bool writeBinaryData, const QString& vtkAttributeType,
                         FILE* vtkFile, QMap<int32_t, int32_t>& featureIds)
{
  TriangleGeom::Pointer triangleGeom = dc->getGeometryAs<TriangleGeom>();

  int64_t numTriangles = triangleGeom->getNumberOfTris();

  IDataArray::Pointer data = dc->getAttributeMatrix(faceAttributeMatrixName)->getAttributeArray(dataName);
  QString ss;
  if (NULL != data.get())
  {
    T* m = reinterpret_cast<T*>(data->getVoidPointer(0));
    fprintf(vtkFile, "\n");
    fprintf(vtkFile, "%s %s %s\n", vtkAttributeType.toLatin1().data(), dataName.toLatin1().data(), dataType.toLatin1().data());
    for(int i = 0; i < numTriangles; ++i)
    {
      T s0 = 0x00;
      T s1 = 0x00;
      T s2 = 0x00;
      if(writeBinaryData == true)
      {
        s0 = static_cast<T>(m[i * 3 + 0]);
        s1 = static_cast<T>(m[i * 3 + 1]);
        s2 = static_cast<T>(m[i * 3 + 2]);
        SIMPLib::Endian::FromSystemToBig::convert(s0);
        SIMPLib::Endian::FromSystemToBig::convert(s1);
        SIMPLib::Endian::FromSystemToBig::convert(s2);
        fwrite(&s0, sizeof(T), 1, vtkFile);
        fwrite(&s1, sizeof(T), 1, vtkFile);
        fwrite(&s2, sizeof(T), 1, vtkFile);

      }
      else
      {

        ss << m[i * 3 + 0] << " " << m[i * 3 + 1] << " " << m[i * 3 + 2] << " ";

        fprintf(vtkFile, "%s ", ss.toLatin1().data());
        if (i % 25 == 0) { fprintf(vtkFile, "\n"); }
      }
    }
  }
}
  IDataArray::Pointer readH5Dataset(hid_t locId,
                                    const QString& datasetPath,
                                    const QVector<size_t>& tDims,
                                    const QVector<size_t>& cDims)
  {
    herr_t err = -1;
    IDataArray::Pointer ptr;

    ptr = DataArray<T>::CreateArray(tDims, cDims, datasetPath);

    T* data = (T*)(ptr->getVoidPointer(0));
    err = QH5Lite::readPointerDataset(locId, datasetPath, data);
    if(err < 0)
    {
      qDebug() << "readH5Data read error: " << __FILE__ << "(" << __LINE__ << ")" ;
      ptr = IDataArray::NullPointer();
    }
    return ptr;
  }
Exemple #9
0
 virtual IDataArray::Pointer reorderCopy(QVector<size_t> newOrderMap)
 {
   if(newOrderMap.size() != static_cast<QVector<size_t>::size_type>(getNumberOfTuples()))
   {
     return IDataArray::NullPointer();
   }
   IDataArray::Pointer daCopy = createNewArray(getNumberOfTuples(), getComponentDimensions(), getName(), m_IsAllocated);
   if(m_IsAllocated == true)
   {
     daCopy->initializeWithZeros();
     size_t chunkSize = getNumberOfComponents() * sizeof(T);
     for(size_t i = 0; i < getNumberOfTuples(); i++)
     {
       T* src = getPointer(i * getNumberOfComponents());
       void* dest = daCopy->getVoidPointer(newOrderMap[i] * getNumberOfComponents());
       ::memcpy(dest, src, chunkSize);
     }
   }
   return daCopy;
 }
Exemple #10
0
void writeCellScalarData(DataContainer::Pointer dc, const QString& faceAttributeMatrixName, const QString& dataName, const QString& dataType,
                         bool writeBinaryData, bool writeConformalMesh, FILE* vtkFile, int nT)
{
  // Write the Feature Face ID Data to the file
  IDataArray::Pointer data = dc->getAttributeMatrix(faceAttributeMatrixName)->getAttributeArray(dataName);
  QString buf;
  QTextStream ss(&buf);
  if (NULL != data.get())
  {
    T* m = reinterpret_cast<T*>(data->getVoidPointer(0));
    fprintf(vtkFile, "\n");
    fprintf(vtkFile, "SCALARS %s %s 1\n", dataName.toLatin1().data(), dataType.toLatin1().data());
    fprintf(vtkFile, "LOOKUP_TABLE default\n");
    for(int i = 0; i < nT; ++i)
    {
      T swapped = 0x00;
      if(writeBinaryData == true)
      {
        swapped = static_cast<T>(m[i]);
        SIMPLib::Endian::FromSystemToBig::convert(swapped);
        fwrite(&swapped, sizeof(T), 1, vtkFile);
        if(false == writeConformalMesh)
        {
          fwrite(&swapped, sizeof(T), 1, vtkFile);
        }
      }
      else
      {

        ss << m[i] << " ";
        if(false == writeConformalMesh)
        {
          ss << m[i] << " ";
        }
        fprintf(vtkFile, "%s", buf.toLatin1().data());
        buf.clear();
        if (i % 50 == 0) { fprintf(vtkFile, "\n"); }
      }
    }
  }
}
Exemple #11
0
void writePointVectorData(DataContainer::Pointer dc, const QString& vertexAttributeMatrixName, const QString& dataName, const QString& dataType,
                          bool writeBinaryData, bool writeConformalMesh, const QString& vtkAttributeType,
                          FILE* vtkFile, int nT)
{
  IDataArray::Pointer data = dc->getAttributeMatrix(vertexAttributeMatrixName)->getAttributeArray(dataName);
  QString ss;
  if (NULL != data.get())
  {
    T* m = reinterpret_cast<T*>(data->getVoidPointer(0));
    fprintf(vtkFile, "\n");
    fprintf(vtkFile, "%s %s %s\n", vtkAttributeType.toLatin1().data(), dataName.toLatin1().data(), dataType.toLatin1().data());
    for(int i = 0; i < nT; ++i)
    {
      T s0 = 0x00;
      T s1 = 0x00;
      T s2 = 0x00;
      if(writeBinaryData == true)
      {
        s0 = static_cast<T>(m[i * 3 + 0]);
        s1 = static_cast<T>(m[i * 3 + 1]);
        s2 = static_cast<T>(m[i * 3 + 2]);
        SIMPLib::Endian::FromSystemToBig::convert(s0);
        SIMPLib::Endian::FromSystemToBig::convert(s1);
        SIMPLib::Endian::FromSystemToBig::convert(s2);
        fwrite(&s0, sizeof(T), 1, vtkFile);
        fwrite(&s1, sizeof(T), 1, vtkFile);
        fwrite(&s1, sizeof(T), 1, vtkFile);
      }
      else
      {

        ss = QString::number(m[i * 3 + 0]) + " " + QString::number(m[i * 3 + 1]) + " " + QString::number(m[i * 3 + 2]) + " ";
        fprintf(vtkFile, "%s ", ss.toLatin1().data());
        //if (i%50 == 0)
        { fprintf(vtkFile, "\n"); }
      }

    }
  }
}
void writeCellNormalData(DataContainer::Pointer dc, const QString& faceAttributeMatrixName, const QString& dataName, const QString& dataType,
                         bool writeBinaryData, FILE* vtkFile, QMap<int32_t, int32_t>& featureIds, int32_t* m_SurfaceMeshFaceLabels)
{
  TriangleGeom::Pointer triangleGeom = dc->getGeometryAs<TriangleGeom>();

  int64_t numTriangles = triangleGeom->getNumberOfTris();
  IDataArray::Pointer data = dc->getAttributeMatrix(faceAttributeMatrixName)->getAttributeArray(dataName);
  QString buf;
  QTextStream ss(&buf);
  if (NULL != data.get())
  {
    int32_t totalCellsWritten = 0;

    T* m = reinterpret_cast<T*>(data->getVoidPointer(0));
    fprintf(vtkFile, "\n");
    fprintf(vtkFile, "NORMALS %s %s\n", dataName.toLatin1().data(), dataType.toLatin1().data());
    // Loop over all the features
    for(QMap<int32_t, int32_t>::iterator featureIter = featureIds.begin(); featureIter != featureIds.end(); ++featureIter)
    {
      int32_t gid = featureIter.key(); // The current Feature Id
      size_t size = featureIter.value(); // The number of triangles for this feature id
      std::vector<T> buffer(size * 3, 0);
      totalCellsWritten += size * 3;
      size_t index = 0;

      for (int j = 0; j < numTriangles; j++)
      {
        if (m_SurfaceMeshFaceLabels[j * 2] != gid && m_SurfaceMeshFaceLabels[j * 2 + 1] != gid) { continue; }
        // Get the data
        T s0 = static_cast<T>(m[j * 3 + 0]);
        T s1 = static_cast<T>(m[j * 3 + 1]);
        T s2 = static_cast<T>(m[j * 3 + 2]);
        // Flip the normal if needed because the current feature id is assigned to the triangle.labels[1]
        if (m_SurfaceMeshFaceLabels[j * 2 + 1] == gid )
        {
          s0 *= -1.0;
          s1 *= -1.0;
          s2 *= -1.0;
        }
        // Write the values to the buffer after an Endian swap.
        if(writeBinaryData == true)
        {
          SIMPLib::Endian::FromSystemToBig::convert(s0);
          buffer[index] = s0;
          ++index;

          SIMPLib::Endian::FromSystemToBig::convert(s1);
          buffer[index] = s1;
          ++index;

          SIMPLib::Endian::FromSystemToBig::convert(s2);
          buffer[index] = s2;
          ++index;
        }
        else
        {

          ss << s0 << " " << s1 << " " << s2;
          fprintf(vtkFile, "%s\n", buf.toLatin1().data());
          buf.clear();
        }
      }

      // Write the Buffer
      if(writeBinaryData == true)
      {
        fwrite(&(buffer.front()), sizeof(T), size * 3, vtkFile);
      }
    }
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void WarpRegularGrid::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  DataContainer::Pointer m;
  if (m_SaveAsNewDataContainer == false) { m = getDataContainerArray()->getDataContainer(getCellAttributeMatrixPath().getDataContainerName()); }
  else { m = getDataContainerArray()->getDataContainer(getNewDataContainerName()); }

  AttributeMatrix::Pointer cellAttrMat = m->getAttributeMatrix(getCellAttributeMatrixPath().getAttributeMatrixName());
  AttributeMatrix::Pointer newCellAttrMat = cellAttrMat->deepCopy();

  size_t dims[3] = { 0, 0, 0 };
  m->getGeometryAs<ImageGeom>()->getDimensions(dims);
  float res[3] = { 0.0f, 0.0f, 0.0f };
  m->getGeometryAs<ImageGeom>()->getResolution(res);
  size_t totalPoints = m->getGeometryAs<ImageGeom>()->getNumberOfElements();

  float x = 0.0f, y = 0.0f, z = 0.0f;
  float newX = 0.0f, newY = 0.0f;
  int col = 0.0f, row = 0.0f, plane = 0.0f;
  size_t index;
  size_t index_old;
  std::vector<size_t> newindicies(totalPoints);
  std::vector<bool> goodPoint(totalPoints, true);

  for (size_t i = 0; i < dims[2]; i++)
  {
    QString ss = QObject::tr("Warping Data - %1 Percent Complete").arg(((float)i / dims[2]) * 100);
    notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss);
    for (size_t j = 0; j < dims[1]; j++)
    {
      for (size_t k = 0; k < dims[0]; k++)
      {
        x = static_cast<float>((k * res[0]));
        y = static_cast<float>((j * res[1]));
        z = static_cast<float>((i * res[2]));
        index = (i * dims[0] * dims[1]) + (j * dims[0]) + k;

        determine_warped_coordinates(x, y, newX, newY);
        col = newX / res[0];
        row = newY / res[1];
        plane = i;

        index_old = (plane * dims[0] * dims[1]) + (row * dims[0]) + col;
        newindicies[index] = index_old;
        if (col > 0 && col < dims[0] && row > 0 && row < dims[1]) { goodPoint[index] = true; }
        else { goodPoint[index] = false; }
      }
    }
  }

  QList<QString> voxelArrayNames = cellAttrMat->getAttributeArrayNames();
  for (QList<QString>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter)
  {
    IDataArray::Pointer p = cellAttrMat->getAttributeArray(*iter);
    // Make a copy of the 'p' array that has the same name. When placed into
    // the data container this will over write the current array with
    // the same name. At least in theory
    IDataArray::Pointer data = p->createNewArray(p->getNumberOfTuples(), p->getComponentDimensions(), p->getName());
    data->resize(totalPoints);
    void* source = NULL;
    void* destination = NULL;
    size_t newIndicies_I = 0;
    int nComp = data->getNumberOfComponents();
    for (size_t i = 0; i < static_cast<size_t>(totalPoints); i++)
    {
      newIndicies_I = newindicies[i];

      if(goodPoint[i] == true)
      {
        source = p->getVoidPointer((nComp * newIndicies_I));
        destination = data->getVoidPointer((data->getNumberOfComponents() * i));
        ::memcpy(destination, source, p->getTypeSize() * data->getNumberOfComponents());
      }
      else
      {
        int var = 0;
        data->initializeTuple(i, &var);
      }
    }
    cellAttrMat->removeAttributeArray(*iter);
    newCellAttrMat->addAttributeArray(*iter, data);
  }
  m->removeAttributeMatrix(getCellAttributeMatrixPath().getAttributeMatrixName());
  m->addAttributeMatrix(getCellAttributeMatrixPath().getAttributeMatrixName(), newCellAttrMat);

  notifyStatusMessage(getHumanLabel(), "Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void NearestPointFuseRegularGrids::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  DataContainer::Pointer refDC = getDataContainerArray()->getDataContainer(m_ReferenceCellAttributeMatrixPath.getDataContainerName());
  DataContainer::Pointer sampleDC = getDataContainerArray()->getDataContainer(m_SamplingCellAttributeMatrixPath.getDataContainerName());

  AttributeMatrix::Pointer refAttrMat = refDC->getAttributeMatrix(m_ReferenceCellAttributeMatrixPath.getAttributeMatrixName());
  AttributeMatrix::Pointer sampleAttrMat = sampleDC->getAttributeMatrix(m_SamplingCellAttributeMatrixPath.getAttributeMatrixName());

  // Get dimensions and resolutions of two grids
  size_t _refDims[3] = { 0, 0, 0 };
  size_t _sampleDims[3] = { 0, 0, 0 };
  float refRes[3] = { 0.0f, 0.0f, 0.0f };
  float sampleRes[3] = { 0.0f, 0.0f, 0.0f };
  float refOrigin[3] = { 0.0f, 0.0f, 0.0f };
  float sampleOrigin[3] = { 0.0f, 0.0f, 0.0f };
  refDC->getGeometryAs<ImageGeom>()->getDimensions(_refDims);
  sampleDC->getGeometryAs<ImageGeom>()->getDimensions(_sampleDims);
  refDC->getGeometryAs<ImageGeom>()->getResolution(refRes);
  sampleDC->getGeometryAs<ImageGeom>()->getResolution(sampleRes);
  refDC->getGeometryAs<ImageGeom>()->getOrigin(refOrigin);
  sampleDC->getGeometryAs<ImageGeom>()->getOrigin(sampleOrigin);

  // Further down we divide by sampleRes, so here check to make sure that no components of the resolution are 0
  // This would be incredible unusual behavior if it were to occur, hence why we don't spend the time
  // doing the validation up in the dataCheck
  bool zeroRes = false;
  for (size_t i = 0; i < 3; i++)
  {
    if (sampleRes[i] == 0.0f)
    {
      zeroRes = true;
      break;
    }
  }

  if (zeroRes == true)
  {
    QString ss = QObject::tr("A component of the resolution for the Image Geometry associated with DataContainer '%1' is 0. This would result in a division by 0 operation").arg(m_SamplingCellAttributeMatrixPath.getDataContainerName());
    setErrorCondition(-5555);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }

  int64_t refDims[3] = { 0, 0, 0 };
  int64_t sampleDims[3] = { 0, 0, 0 };
  for (size_t i = 0; i < 3; i++)
  {
    refDims[i] = static_cast<int64_t>(_refDims[i]);
    sampleDims[i] = static_cast<int64_t>(_sampleDims[i]);
  }

  int64_t numRefTuples = refDims[0] * refDims[1] * refDims[2];

  float x = 0.0f, y = 0.0f, z = 0.0f;
  int64_t col = 0, row = 0, plane = 0;
  int64_t refIndex = 0;
  int64_t sampleIndex = 0;
  int64_t planeComp = 0, rowComp = 0;

  // Create arrays on the reference grid to hold data present on the sampling grid
  QList<QString> voxelArrayNames = sampleAttrMat->getAttributeArrayNames();
  for (QList<QString>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter)
  {
    IDataArray::Pointer p = sampleAttrMat->getAttributeArray(*iter);
    // Make a copy of the 'p' array that has the same name. When placed into
    // the data container this will over write the current array with
    // the same name. At least in theory
    IDataArray::Pointer data = p->createNewArray(numRefTuples, p->getComponentDimensions(), p->getName());
    refAttrMat->addAttributeArray(p->getName(), data);
  }

  bool outside  = false;
  for (int64_t i = 0; i < refDims[2]; i++)
  {
    planeComp = i * refDims[0] * refDims[1];
    for (int64_t j = 0; j < refDims[1]; j++)
    {
      rowComp = j * refDims[0];
      for (int64_t k = 0; k < refDims[0]; k++)
      {
        outside = false;
        x = (k * refRes[0] + refOrigin[0]);
        y = (j * refRes[1] + refOrigin[1]);
        z = (i * refRes[2] + refOrigin[2]);
        if ((x - sampleOrigin[0]) < 0) { outside = true; }
        else { col = int64_t((x - sampleOrigin[0]) / sampleRes[0]); }
        if ((y - sampleOrigin[1]) < 0) { outside = true; }
        else { row = int64_t((y - sampleOrigin[1]) / sampleRes[1]); }
        if ((z - sampleOrigin[2]) < 0) { outside = true; }
        else { plane = int64_t((z - sampleOrigin[2]) / sampleRes[2]); }
        if (col > sampleDims[0] ||  row > sampleDims[1] ||  plane > sampleDims[2]) { outside = true; }
        if (outside == false)
        {
          sampleIndex = (plane * sampleDims[0] * sampleDims[1]) + (row * sampleDims[0]) + col;
          refIndex = planeComp + rowComp + k;
          for (QList<QString>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter)
          {
            IDataArray::Pointer p = sampleAttrMat->getAttributeArray(*iter);
            // Make a copy of the 'p' array that has the same name. When placed into
            // the data container this will over write the current array with
            // the same name. At least in theory
            IDataArray::Pointer data = refAttrMat->getAttributeArray(*iter);
            void* source = NULL;
            void* destination = NULL;
            int nComp = data->getNumberOfComponents();

            source = p->getVoidPointer((nComp * sampleIndex));
            destination = data->getVoidPointer((nComp * refIndex));
            ::memcpy(destination, source, p->getTypeSize() * nComp);
          }
        }
      }
    }
  }

  notifyStatusMessage(getHumanLabel(), "Complete");
}
void testCase4_Execute(const QString& name, int scalarType)
{
  int dataArraySize = ARRAY_SIZE * N;
  int junkArraySize = 5;
  int skipHeaderBytes = junkArraySize * sizeof(T);
  int err = 0;
  qDebug() << "Testing case 4: " << name << " with num comps " << N;

  // Allocate an array, and get the dataArray from that array
  boost::shared_array<T> array(new T[dataArraySize]); // This makes sure our allocated array is deleted when we leave
  T* dataArray = array.get();

  // Write some data into the data array
  for(size_t i = 0; i < dataArraySize; ++i)
  {
    dataArray[i] = static_cast<T>(i);
  }

  // Create junkArray
  T* junkArray = new T[junkArraySize];

  // Write a pattern into junkArray
  for(size_t i = 0; i < junkArraySize; ++i)
  {
    junkArray[i] = (unsigned)0xAB;
  }


  // Create the file and write to it.  If any of the information is wrong, the result will be false
  bool result = createAndWriteToFile(dataArray, dataArraySize, junkArray, junkArraySize, Detail::Start);

  // Test to make sure that the file was created and written to successfully
  DREAM3D_REQUIRED(result, == , true)

  // Create the data container
  VolumeDataContainer::Pointer m = VolumeDataContainer::New();
  m->setName(DREAM3D::Defaults::DataContainerName);
  DataContainerArray::Pointer dca = DataContainerArray::New();
  dca->pushBack(m);

  // Create the filter, passing in the skipHeaderBytes
  RawBinaryReader::Pointer filt = createRawBinaryReaderFilter(scalarType, N, skipHeaderBytes);
  filt->setDataContainerArray(dca);

  // Preflight, get error condition, and check that there are no errors
  filt->preflight();
  err = filt->getErrorCondition();
  DREAM3D_REQUIRED(err, >= , 0)

  // Execute, get error condition, check that there are no errors, and compare the data
  filt->execute();
  err = filt->getErrorCondition();
  DREAM3D_REQUIRED(err, >= , 0)

  IDataArray::Pointer iData = m->getAttributeMatrix(getCellAttributeMatrixName())->getAttributeArray("Test_Array");
  T* data = reinterpret_cast<T*>(iData->getVoidPointer(0));
  T d, p;
  for(size_t i = 0; i < dataArraySize; ++i)
  {
    d = data[i];
    p = dataArray[i];
    DREAM3D_REQUIRE_EQUAL(d, p)
  }

  /*
   * SUBTEST: Test when skipHeaderBytes is larger than expected
   */

  // Create another data container
  VolumeDataContainer::Pointer m2 = VolumeDataContainer::New();
  m2->setName(DREAM3D::Defaults::DataContainerName);
  DataContainerArray::Pointer dca2 = DataContainerArray::New();
  dca2->pushBack(m2);

  // Create another filter, passing in the skipHeaderBytes + 1
  RawBinaryReader::Pointer filt2 = createRawBinaryReaderFilter(scalarType, N, skipHeaderBytes + 1);
  filt2->setDataContainerArray(dca2);

  // Preflight, get error condition, and check that there are errors
  filt2->preflight();
  err = filt2->getErrorCondition();
  DREAM3D_REQUIRED(err, < , 0)

  // Execute, get error condition, and check that the "file too small" error occurred
  filt2->execute();
  err = filt2->getErrorCondition();
  DREAM3D_REQUIRED(err, == , RBRT_FILE_TOO_SMALL)
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void RotateSampleRefFrame::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getCellAttributeMatrixPath().getDataContainerName());

  float rotAngle = m_RotationAngle * SIMPLib::Constants::k_Pi / 180.0;

  int64_t xp = 0, yp = 0, zp = 0;
  float xRes = 0.0f, yRes = 0.0f, zRes = 0.0f;
  int64_t xpNew = 0, ypNew = 0, zpNew = 0;
  float xResNew = 0.0f, yResNew = 0.0f, zResNew = 0.0f;
  RotateSampleRefFrameImplArg_t params;

  xp = static_cast<int64_t>(m->getGeometryAs<ImageGeom>()->getXPoints());
  xRes = m->getGeometryAs<ImageGeom>()->getXRes();
  yp = static_cast<int64_t>(m->getGeometryAs<ImageGeom>()->getYPoints());
  yRes = m->getGeometryAs<ImageGeom>()->getYRes();
  zp = static_cast<int64_t>(m->getGeometryAs<ImageGeom>()->getZPoints());
  zRes = m->getGeometryAs<ImageGeom>()->getZRes();

  params.xp = xp;
  params.xRes = xRes;
  params.yp = yp;
  params.yRes = yRes;
  params.zp = zp;
  params.zRes = zRes;

  size_t col = 0, row = 0, plane = 0;
  float rotMat[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float coords[3] = { 0.0f, 0.0f, 0.0f };
  float newcoords[3] = { 0.0f, 0.0f, 0.0f };
  float xMin = std::numeric_limits<float>::max();
  float xMax = std::numeric_limits<float>::min();
  float yMin = std::numeric_limits<float>::max();
  float yMax = std::numeric_limits<float>::min();
  float zMin = std::numeric_limits<float>::max();
  float zMax = std::numeric_limits<float>::min();

  FOrientArrayType om(9);
  FOrientTransformsType::ax2om(FOrientArrayType(m_RotationAxis.x, m_RotationAxis.y, m_RotationAxis.z, rotAngle), om);
  om.toGMatrix(rotMat);
  for (int32_t i = 0; i < 8; i++)
  {
    if (i == 0) { col = 0, row = 0, plane = 0; }
    if (i == 1) { col = xp - 1, row = 0, plane = 0; }
    if (i == 2) { col = 0, row = yp - 1, plane = 0; }
    if (i == 3) { col = xp - 1, row = yp - 1, plane = 0; }
    if (i == 4) { col = 0, row = 0, plane = zp - 1; }
    if (i == 5) { col = xp - 1, row = 0, plane = zp - 1; }
    if (i == 6) { col = 0, row = yp - 1, plane = zp - 1; }
    if (i == 7) { col = xp - 1, row = yp - 1, plane = zp - 1; }
    coords[0] = static_cast<float>(col * xRes);
    coords[1] = static_cast<float>(row * yRes);
    coords[2] = static_cast<float>(plane * zRes);
    MatrixMath::Multiply3x3with3x1(rotMat, coords, newcoords);
    if (newcoords[0] < xMin) { xMin = newcoords[0]; }
    if (newcoords[0] > xMax) { xMax = newcoords[0]; }
    if (newcoords[1] < yMin) { yMin = newcoords[1]; }
    if (newcoords[1] > yMax) { yMax = newcoords[1]; }
    if (newcoords[2] < zMin) { zMin = newcoords[2]; }
    if (newcoords[2] > zMax) { zMax = newcoords[2]; }
  }
  float xAxis[3] = {1, 0, 0};
  float yAxis[3] = {0, 1, 0};
  float zAxis[3] = {0, 0, 1};
  float xAxisNew[3] = { 0.0f, 0.0f, 0.0f };
  float yAxisNew[3] = { 0.0f, 0.0f, 0.0f };
  float zAxisNew[3] = { 0.0f, 0.0f, 0.0f };
  MatrixMath::Multiply3x3with3x1(rotMat, xAxis, xAxisNew);
  MatrixMath::Multiply3x3with3x1(rotMat, yAxis, yAxisNew);
  MatrixMath::Multiply3x3with3x1(rotMat, zAxis, zAxisNew);
  float closestAxis = 0.0f;
  xResNew = xRes;
  closestAxis = fabs(GeometryMath::CosThetaBetweenVectors(xAxis, xAxisNew));
  if (fabs(GeometryMath::CosThetaBetweenVectors(yAxis, xAxisNew)) > closestAxis) { xResNew = yRes, closestAxis = fabs(GeometryMath::CosThetaBetweenVectors(yAxis, xAxisNew)); }
  if (fabs(GeometryMath::CosThetaBetweenVectors(zAxis, xAxisNew)) > closestAxis) { xResNew = zRes, closestAxis = fabs(GeometryMath::CosThetaBetweenVectors(zAxis, xAxisNew)); }
  yResNew = yRes;
  closestAxis = fabs(GeometryMath::CosThetaBetweenVectors(yAxis, yAxisNew));
  if (fabs(GeometryMath::CosThetaBetweenVectors(xAxis, yAxisNew)) > closestAxis) { yResNew = xRes, closestAxis = fabs(GeometryMath::CosThetaBetweenVectors(xAxis, yAxisNew)); }
  if (fabs(GeometryMath::CosThetaBetweenVectors(zAxis, yAxisNew)) > closestAxis) { yResNew = zRes, closestAxis = fabs(GeometryMath::CosThetaBetweenVectors(zAxis, yAxisNew)); }
  zResNew = zRes;
  closestAxis = fabs(GeometryMath::CosThetaBetweenVectors(zAxis, zAxisNew));
  if (fabs(GeometryMath::CosThetaBetweenVectors(xAxis, zAxisNew)) > closestAxis) { zResNew = xRes, closestAxis = fabs(GeometryMath::CosThetaBetweenVectors(xAxis, zAxisNew)); }
  if (fabs(GeometryMath::CosThetaBetweenVectors(yAxis, zAxisNew)) > closestAxis) { zResNew = yRes, closestAxis = fabs(GeometryMath::CosThetaBetweenVectors(yAxis, zAxisNew)); }

  xpNew = static_cast<int64_t>(nearbyint((xMax - xMin) / xResNew) + 1);
  ypNew = static_cast<int64_t>(nearbyint((yMax - yMin) / yResNew) + 1);
  zpNew = static_cast<int64_t>(nearbyint((zMax - zMin) / zResNew) + 1);

  params.xpNew = xpNew;
  params.xResNew = xResNew;
  params.xMinNew = xMin;
  params.ypNew = ypNew;
  params.yResNew = yResNew;
  params.yMinNew = yMin;
  params.zpNew = zpNew;
  params.zResNew = zResNew;
  params.zMinNew = zMin;

  int64_t newNumCellTuples = params.xpNew * params.ypNew * params.zpNew;

  DataArray<int64_t>::Pointer newIndiciesPtr = DataArray<int64_t>::CreateArray(newNumCellTuples, "_INTERNAL_USE_ONLY_RotateSampleRef_NewIndicies");
  newIndiciesPtr->initializeWithValue(-1);
  int64_t* newindicies = newIndiciesPtr->getPointer(0);

#ifdef SIMPLib_USE_PARALLEL_ALGORITHMS
  tbb::task_scheduler_init init;
  bool doParallel = true;
#endif

#ifdef SIMPLib_USE_PARALLEL_ALGORITHMS
  if (doParallel == true)
  {
    tbb::parallel_for(tbb::blocked_range3d<int64_t, int64_t, int64_t>(0, params.zpNew, 0, params.ypNew, 0, params.xpNew),
                      RotateSampleRefFrameImpl(newIndiciesPtr, &params, rotMat, m_SliceBySlice), tbb::auto_partitioner());
  }
  else
#endif
  {
    RotateSampleRefFrameImpl serial(newIndiciesPtr, &params, rotMat, m_SliceBySlice);
    serial.convert(0, params.zpNew, 0, params.ypNew, 0, params.xpNew);
  }

  // This could technically be parallelized also where each thread takes an array to adjust. Except
  // that the DataContainer is NOT thread safe or re-entrant so that would actually be a BAD idea.
  QString attrMatName = getCellAttributeMatrixPath().getAttributeMatrixName();
  QList<QString> voxelArrayNames = m->getAttributeMatrix(attrMatName)->getAttributeArrayNames();

  // resize attribute matrix
  QVector<size_t> tDims(3);
  tDims[0] = params.xpNew;
  tDims[1] = params.ypNew;
  tDims[2] = params.zpNew;
  m->getAttributeMatrix(attrMatName)->resizeAttributeArrays(tDims);

  for (QList<QString>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter)
  {
    IDataArray::Pointer p = m->getAttributeMatrix(attrMatName)->getAttributeArray(*iter);
    // Make a copy of the 'p' array that has the same name. When placed into
    // the data container this will over write the current array with
    // the same name.
    IDataArray::Pointer data = p->createNewArray(newNumCellTuples, p->getComponentDimensions(), p->getName());
    void* source = NULL;
    void* destination = NULL;
    int64_t newIndicies_I = 0;
    int32_t nComp = data->getNumberOfComponents();
    for (size_t i = 0; i < static_cast<size_t>(newNumCellTuples); i++)
    {
      newIndicies_I = newindicies[i];
      if(newIndicies_I >= 0)
      {
        source = p->getVoidPointer((nComp * newIndicies_I));
        if (NULL == source)
        {
          QString ss = QObject::tr("The index is outside the bounds of the source array");
          setErrorCondition(-11004);
          notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
          return;
        }
        destination = data->getVoidPointer((data->getNumberOfComponents() * i));
        ::memcpy(destination, source, p->getTypeSize() * data->getNumberOfComponents());
      }
      else
      {
        data->initializeTuple(i, 0);
      }
    }
    m->getAttributeMatrix(attrMatName)->addAttributeArray(*iter, data);
  }
  m->getGeometryAs<ImageGeom>()->setResolution(params.xResNew, params.yResNew, params.zResNew);
  m->getGeometryAs<ImageGeom>()->setDimensions(params.xpNew, params.ypNew, params.zpNew);
  m->getGeometryAs<ImageGeom>()->setOrigin(xMin, yMin, zMin);

  notifyStatusMessage(getHumanLabel(), "Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void ChangeResolution::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  DataContainer::Pointer m;
  if(m_SaveAsNewDataContainer == false)
  {
    m = getDataContainerArray()->getDataContainer(getCellAttributeMatrixPath().getDataContainerName());
  }
  else
  {
    m = getDataContainerArray()->getDataContainer(getNewDataContainerName());
  }

  if(m->getGeometryAs<ImageGeom>()->getXRes() == m_Resolution.x
      && m->getGeometryAs<ImageGeom>()->getYRes() == m_Resolution.y
      && m->getGeometryAs<ImageGeom>()->getZRes() == m_Resolution.z)
  {
    return;
  }

  AttributeMatrix::Pointer cellAttrMat = m->getAttributeMatrix(getCellAttributeMatrixPath().getAttributeMatrixName());

  size_t dims[3] = { 0, 0, 0 };
  m->getGeometryAs<ImageGeom>()->getDimensions(dims);

  float sizex = (dims[0]) * m->getGeometryAs<ImageGeom>()->getXRes();
  float sizey = (dims[1]) * m->getGeometryAs<ImageGeom>()->getYRes();
  float sizez = (dims[2]) * m->getGeometryAs<ImageGeom>()->getZRes();
  size_t m_XP = size_t(sizex / m_Resolution.x);
  size_t m_YP = size_t(sizey / m_Resolution.y);
  size_t m_ZP = size_t(sizez / m_Resolution.z);
  if (m_XP == 0) { m_XP = 1; }
  if (m_YP == 0) { m_YP = 1; }
  if (m_ZP == 0) { m_ZP = 1; }
  size_t totalPoints = m_XP * m_YP * m_ZP;

  float x = 0.0f, y = 0.0f, z = 0.0f;
  size_t col = 0, row = 0, plane = 0;
  size_t index;
  size_t index_old;
  std::vector<size_t> newindicies(totalPoints);

  for (size_t i = 0; i < m_ZP; i++)
  {
    QString ss = QObject::tr("Changing Resolution - %1 Percent Complete").arg(((float)i / m->getGeometryAs<ImageGeom>()->getZPoints()) * 100);
    notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss);
    for (size_t j = 0; j < m_YP; j++)
    {
      for (size_t k = 0; k < m_XP; k++)
      {
        x = (k * m_Resolution.x);
        y = (j * m_Resolution.y);
        z = (i * m_Resolution.z);
        col = size_t(x / m->getGeometryAs<ImageGeom>()->getXRes());
        row = size_t(y / m->getGeometryAs<ImageGeom>()->getYRes());
        plane = size_t(z / m->getGeometryAs<ImageGeom>()->getZRes());
        index_old = (plane * m->getGeometryAs<ImageGeom>()->getXPoints() * m->getGeometryAs<ImageGeom>()->getYPoints()) + (row * m->getGeometryAs<ImageGeom>()->getXPoints()) + col;
        index = (i * m_XP * m_YP) + (j * m_XP) + k;
        newindicies[index] = index_old;
      }
    }
  }

  QVector<size_t> tDims(3, 0);
  tDims[0] = m_XP;
  tDims[1] = m_YP;
  tDims[2] = m_ZP;
  AttributeMatrix::Pointer newCellAttrMat = AttributeMatrix::New(tDims, cellAttrMat->getName(), cellAttrMat->getType());

  QList<QString> voxelArrayNames = cellAttrMat->getAttributeArrayNames();
  for (QList<QString>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter)
  {
    IDataArray::Pointer p = cellAttrMat->getAttributeArray(*iter);
    // Make a copy of the 'p' array that has the same name. When placed into
    // the data container this will over write the current array with
    // the same name. At least in theory.
    IDataArray::Pointer data = p->createNewArray(p->getNumberOfTuples(), p->getComponentDimensions(), p->getName());
    data->resize(totalPoints);
    void* source = NULL;
    void* destination = NULL;
    size_t newIndicies_I = 0;
    int nComp = data->getNumberOfComponents();
    for (size_t i = 0; i < static_cast<size_t>(totalPoints); i++)
    {
      newIndicies_I = newindicies[i];
      source = p->getVoidPointer((nComp * newIndicies_I));
      destination = data->getVoidPointer((data->getNumberOfComponents() * i));
      ::memcpy(destination, source, p->getTypeSize() * data->getNumberOfComponents());
    }
    cellAttrMat->removeAttributeArray(*iter);
    newCellAttrMat->addAttributeArray(*iter, data);
  }
  m->getGeometryAs<ImageGeom>()->setResolution(m_Resolution.x, m_Resolution.y, m_Resolution.z);
  m->getGeometryAs<ImageGeom>()->setDimensions(m_XP, m_YP, m_ZP);
  m->removeAttributeMatrix(getCellAttributeMatrixPath().getAttributeMatrixName());
  m->addAttributeMatrix(getCellAttributeMatrixPath().getAttributeMatrixName(), newCellAttrMat);

  // Feature Ids MUST already be renumbered.
  if (m_RenumberFeatures == true)
  {
    totalPoints = m->getGeometryAs<ImageGeom>()->getNumberOfElements();
    AttributeMatrix::Pointer cellFeatureAttrMat = m->getAttributeMatrix(getCellFeatureAttributeMatrixPath().getAttributeMatrixName());
    size_t totalFeatures = cellFeatureAttrMat->getNumTuples();
    QVector<bool> activeObjects(totalFeatures, false);
    if (0 == totalFeatures)
    {
      notifyErrorMessage(getHumanLabel(), "The number of Features is 0 and should be greater than 0", -600);
      return;
    }

    updateCellInstancePointers();

    // Find the unique set of feature ids
    for (size_t i = 0; i < totalPoints; ++i)
    {
      activeObjects[m_FeatureIds[i]] = true;
    }
    cellFeatureAttrMat->removeInactiveObjects(activeObjects, m_FeatureIdsPtr.lock());
  }

  notifyStatusMessage(getHumanLabel(), "Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void RegularizeZSpacing::execute()
{
    setErrorCondition(0);
    dataCheck();
    if(getErrorCondition() < 0) {
        return;
    }

    DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getCellAttributeMatrixPath().getDataContainerName());

    size_t dims[3];
    m->getGeometryAs<ImageGeom>()->getDimensions(dims);

    std::ifstream inFile;
    inFile.open(m_InputFile.toLatin1().data());

    float zval = 0.0f;
    std::vector<float> zboundvalues(dims[2] + 1, 0.0);
    for (size_t iter = 0; iter < dims[2] + 1; iter++)
    {
        inFile >> zval;
        zboundvalues[iter] = zval;
    }
    inFile.close();

    float xRes = m->getGeometryAs<ImageGeom>()->getXRes();
    float yRes = m->getGeometryAs<ImageGeom>()->getYRes();

    float sizez = zboundvalues[dims[2]];
    size_t m_XP = dims[0];
    size_t m_YP = dims[1];
    size_t m_ZP = static_cast<size_t>(sizez / m_NewZRes);
    if (m_ZP == 0) {
        m_ZP = 1;
    }
    size_t totalPoints = m_XP * m_YP * m_ZP;

    size_t index = 0, oldindex = 0;
    size_t plane = 0;
    std::vector<size_t> newindicies(totalPoints, 0);
    for (size_t i = 0; i < m_ZP; i++)
    {
        plane = 0;
        for (size_t iter = 1; iter < dims[2]; iter++)
        {
            if ((i * m_NewZRes) > zboundvalues[iter]) {
                plane = iter;
            }
        }
        for (size_t j = 0; j < m_YP; j++)
        {
            for (size_t k = 0; k < m_XP; k++)
            {
                oldindex = (plane * dims[0] * dims[1]) + (j * dims[0]) + k;
                index = (i * dims[0] * dims[1]) + (j * dims[0]) + k;
                newindicies[index] = oldindex;
            }
        }
    }

    AttributeMatrix::Pointer cellAttrMat = m->getAttributeMatrix(getCellAttributeMatrixPath().getAttributeMatrixName());
    QVector<size_t> tDims(3, 0);
    tDims[0] = m_XP;
    tDims[1] = m_YP;
    tDims[2] = m_ZP;
    AttributeMatrix::Pointer newCellAttrMat = AttributeMatrix::New(tDims, cellAttrMat->getName(), cellAttrMat->getType());

    QList<QString> voxelArrayNames = cellAttrMat->getAttributeArrayNames();
    for (QList<QString>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter)
    {
        IDataArray::Pointer p = cellAttrMat->getAttributeArray(*iter);
        // Make a copy of the 'p' array that has the same name. When placed into
        // the data container this will over write the current array with
        // the same name. At least in theory
        IDataArray::Pointer data = p->createNewArray(p->getNumberOfTuples(), p->getComponentDimensions(), p->getName());
        data->resize(totalPoints);
        void* source = NULL;
        void* destination = NULL;
        size_t newIndicies_I = 0;
        int nComp = data->getNumberOfComponents();
        for (size_t i = 0; i < static_cast<size_t>(totalPoints); i++)
        {
            newIndicies_I = newindicies[i];

            source = p->getVoidPointer((nComp * newIndicies_I));
            destination = data->getVoidPointer((data->getNumberOfComponents() * i));
            ::memcpy(destination, source, p->getTypeSize() * data->getNumberOfComponents());
        }
        cellAttrMat->removeAttributeArray(*iter);
        newCellAttrMat->addAttributeArray(*iter, data);
    }
    m->getGeometryAs<ImageGeom>()->setResolution(xRes, yRes, m_NewZRes);
    m->getGeometryAs<ImageGeom>()->setDimensions(m_XP, m_YP, m_ZP);
    m->removeAttributeMatrix(getCellAttributeMatrixPath().getAttributeMatrixName());
    m->addAttributeMatrix(getCellAttributeMatrixPath().getAttributeMatrixName(), newCellAttrMat);

    notifyStatusMessage(getHumanLabel(), "Complete");
}