// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void AdjustVolumeOrigin::updateSurfaceMesh()
{
  int err = 0;
  std::stringstream ss;
  setErrorCondition(err);
  SurfaceMeshDataContainer* m = getSurfaceMeshDataContainer();
  if(NULL == m)
  {
    setErrorCondition(-999);
    notifyErrorMessage("The SurfaceMeshing DataContainer Object was NULL", -999);
    return;
  }
  setErrorCondition(0);
  notifyStatusMessage("Starting");

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

  DREAM3D::SurfaceMesh::VertListPointer_t nodesPtr = getSurfaceMeshDataContainer()->getVertices();
  DREAM3D::SurfaceMesh::Vert_t* nodes = nodesPtr->GetPointer(0);

  // First get the min/max coords.

  float min[3] = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
//  float max[3] = { std::numeric_limits<float>::min(), std::numeric_limits<float>::min(), std::numeric_limits<float>::min() };

  size_t count = nodesPtr->GetNumberOfTuples();
  for (size_t i = 0; i < count; i++)
  {
//    if (nodes[i].pos[0] > max[0]) { max[0] = nodes[i].pos[0]; }
//    if (nodes[i].pos[1] > max[1]) { max[1] = nodes[i].pos[1]; }
//    if (nodes[i].pos[2] > max[2]) { max[2] = nodes[i].pos[2]; }

    if (nodes[i].pos[0] < min[0]) { min[0] = nodes[i].pos[0]; }
    if (nodes[i].pos[1] < min[1]) { min[1] = nodes[i].pos[1]; }
    if (nodes[i].pos[2] < min[2]) { min[2] = nodes[i].pos[2]; }
  }

  float delta[3] = {min[0] - m_Origin.x, min[1] - m_Origin.y, min[2] - m_Origin.z };
#ifdef DREAM3D_USE_PARALLEL_ALGORITHMS
  if (doParallel == true)
  {
    tbb::parallel_for(tbb::blocked_range<size_t>(0, count),
                      Detail::UpdateVerticesImpl(nodesPtr, delta), tbb::auto_partitioner());

  }
  else
#endif
  {
    Detail::UpdateVerticesImpl serial(nodesPtr, delta);
    serial.generate(0, count);
  }

}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void GenerateSurfaceMeshConnectivity::execute()
{
  int err = 0;
  std::stringstream ss;
  setErrorCondition(err);
  VoxelDataContainer* m = getVoxelDataContainer();
  if(NULL == m)
  {
    setErrorCondition(-999);
    notifyErrorMessage("The Voxel DataContainer Object was NULL", -999);
    return;
  }
  setErrorCondition(0);
  dataCheck(false, 1, 1, 1);
  if (getErrorCondition() < 0)
  {
    return;
  }
  // We need the vertex->Triangle Lists to build the Triangle Neighbor lists so if either
  // of those are true then build the vertex->triangle lists
  if (m_GenerateVertexTriangleLists == true || m_GenerateTriangleNeighbors == true)
  {
    notifyStatusMessage("Generating Vertex Triangle List");
    getSurfaceMeshDataContainer()->buildMeshVertLinks();
  }
  if (m_GenerateTriangleNeighbors == true)
  {
    notifyStatusMessage("Generating Face Neighbors List");
    getSurfaceMeshDataContainer()->buildMeshFaceNeighborLists();
  }

  if (m_GenerateEdgeIdList == true)
  {
    // There was no Edge connectivity before this filter so delete it when we are done with it
    GenerateUniqueEdges::Pointer conn = GenerateUniqueEdges::New();
    ss.str("");
    ss << getMessagePrefix() << " |->Generating Unique Edge Ids |->";
    conn->setMessagePrefix(ss.str());
    conn->setObservers(getObservers());
    conn->setVoxelDataContainer(getVoxelDataContainer());
    conn->setSurfaceMeshDataContainer(getSurfaceMeshDataContainer());
    conn->setSolidMeshDataContainer(getSolidMeshDataContainer());
    conn->execute();
    if(conn->getErrorCondition() < 0)
    {
      setErrorCondition(conn->getErrorCondition());
      return;
    }
  }

  /* Let the GUI know we are done with this filter */
  notifyStatusMessage("Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void BinaryNodesTrianglesReader::dataCheck(bool preflight, size_t voxels, size_t fields, size_t ensembles)
{
    setErrorCondition(0);
    std::stringstream ss;

    SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
    if(NULL == sm)
    {
        setErrorCondition(-384);
        addErrorMessage(getHumanLabel(), "SurfaceMeshDataContainer is missing", getErrorCondition());
    }

    if (getBinaryNodesFile().empty() == true)
    {
        std::stringstream ss;
        ss << ClassName() << " needs the Binary Nodes File path set and it was not.";
        setErrorCondition(-387);
        addErrorMessage(getHumanLabel(), ss.str(), getErrorCondition());
    }

    if (getBinaryNodesFile().empty() == true)
    {
        std::stringstream ss;
        ss << ClassName() << " needs the Binary Nodes File path set and it was not.";
        setErrorCondition(-387);
        addErrorMessage(getHumanLabel(), ss.str(), getErrorCondition());
    }

}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void AbaqusSurfaceMeshWriter::dataCheck(bool preflight, size_t voxels, size_t fields, size_t ensembles)
{
  setErrorCondition(0);
  if (m_OutputFile.empty() == true)
  {
    setErrorCondition(-1003);
    addErrorMessage(getHumanLabel(), "Abaqus Output file is not set.", getErrorCondition());
  }

  SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
  if (NULL == sm)
  {
    setErrorCondition(-384);
    addErrorMessage(getHumanLabel(), "SurfaceMeshDataContainer is missing", getErrorCondition());
  }
  else
  {
    if (sm->getFaces().get() == NULL)
    {
      setErrorCondition(-385);
      addErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Triangles",getErrorCondition());
    }
    if (sm->getVertices().get() == NULL)
    {
      setErrorCondition(-386);
      addErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Nodes",getErrorCondition());
    }
    std::stringstream ss;
    GET_PREREQ_DATA(sm, DREAM3D, FaceData, SurfaceMeshFaceLabels, ss, -30, int32_t, Int32ArrayType, sm->getNumFaceTuples(), 2)
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void AdjustVolumeOrigin::dataCheck(bool preflight, size_t voxels, size_t fields, size_t ensembles)
{
  setErrorCondition(0);
  std::stringstream ss;
  if (m_ApplyToVoxelVolume == true)
  {
    VoxelDataContainer* m = getVoxelDataContainer();
    if(NULL == m)
    {
      setErrorCondition(-383);
      addErrorMessage(getHumanLabel(), "VoxelDataContainer is missing", getErrorCondition());
    }
  }


  if (m_ApplyToSurfaceMesh == true)
  {
    SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
    if(NULL == sm)
    {
      setErrorCondition(-383);
      addErrorMessage(getHumanLabel(), "SurfaceMeshDataContainer is missing", getErrorCondition());
    }
    else
    {
      // We MUST have Nodes
      if(sm->getVertices().get() == NULL)
      {
        setErrorCondition(-384);
        addErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Nodes", getErrorCondition());
      }
    }
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void GenerateSurfaceMeshConnectivity::dataCheck(bool preflight, size_t voxels, size_t fields, size_t ensembles)
{
  setErrorCondition(0);
  std::stringstream ss;
  SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
  if(NULL == sm)
  {
    setErrorCondition(-383);
    addErrorMessage(getHumanLabel(), "SurfaceMeshDataContainer is missing", getErrorCondition());
  }
  else
  {
    // We MUST have Nodes
    if(sm->getVertices().get() == NULL)
    {
      setErrorCondition(-384);
      addErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Nodes", getErrorCondition());
    }

    // We MUST have Triangles defined also.
    if(sm->getFaces().get() == NULL)
    {
      setErrorCondition(-385);
      addErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Triangles", getErrorCondition());
    }
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void GenerateNodeTriangleConnectivity::execute()
{
  int err = 0;
  std::stringstream ss;
  setErrorCondition(err);
  SurfaceMeshDataContainer* m = getSurfaceMeshDataContainer();
  if(NULL == m)
  {
    setErrorCondition(-999);
    notifyErrorMessage("The SurfaceMesh DataContainer Object was NULL", -999);
    return;
  }
  setErrorCondition(0);

  // Just to double check we have everything.
  dataCheck(false, 0,0,0);
  if (getErrorCondition() < 0)
  {
    return;
  }

  notifyStatusMessage("Starting");

  // Generate the connectivity data
  generateConnectivity();

  /* Let the GUI know we are done with this filter */
  notifyStatusMessage("Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void TriangleNormalFilter::dataCheck(bool preflight, size_t voxels, size_t fields, size_t ensembles)
{
  setErrorCondition(0);
  std::stringstream ss;
  SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
  if(NULL == sm)
  {
    setErrorCondition(-383);
    addErrorMessage(getHumanLabel(), "SurfaceMeshDataContainer is missing", getErrorCondition());
  }
  else
  {
    // We MUST have Nodes
    if(sm->getVertices().get() == NULL)
    {
      setErrorCondition(-384);
      addErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Nodes", getErrorCondition());
    }

    // We MUST have Triangles defined also.
    if(sm->getFaces().get() == NULL)
    {
      setErrorCondition(-385);
      addErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Triangles", getErrorCondition());
    }
    else
    {
      CREATE_NON_PREREQ_DATA(sm, DREAM3D, FaceData, SurfaceMeshTriangleNormals, ss, double, DoubleArrayType, 0, voxels, 3)
    }
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void TriangleNormalFilter::execute()
{
  int err = 0;
  std::stringstream ss;
  setErrorCondition(err);
  SurfaceMeshDataContainer* m = getSurfaceMeshDataContainer();
  if(NULL == m)
  {
    setErrorCondition(-999);
    notifyErrorMessage("The SurfaceMesh DataContainer Object was NULL", -999);
    return;
  }
  setErrorCondition(0);
  notifyStatusMessage("Starting");

#ifdef DREAM3D_USE_PARALLEL_ALGORITHMS
  bool doParallel = true;
#endif

  DREAM3D::SurfaceMesh::VertListPointer_t nodesPtr = getSurfaceMeshDataContainer()->getVertices();

  DREAM3D::SurfaceMesh::FaceListPointer_t trianglesPtr = getSurfaceMeshDataContainer()->getFaces();
  size_t totalPoints = trianglesPtr->GetNumberOfTuples();

  // Run the data check to allocate the memory for the centroid array
  dataCheck(false, trianglesPtr->GetNumberOfTuples(), 0, 0);

#ifdef DREAM3D_USE_PARALLEL_ALGORITHMS
  if (doParallel == true)
  {
    tbb::parallel_for(tbb::blocked_range<size_t>(0, totalPoints),
                      CalculateNormalsImpl(nodesPtr, trianglesPtr, m_SurfaceMeshTriangleNormals), tbb::auto_partitioner());

  }
  else
#endif
  {
    CalculateNormalsImpl serial(nodesPtr, trianglesPtr, m_SurfaceMeshTriangleNormals);
    serial.generate(0, totalPoints);
  }


  /* Let the GUI know we are done with this filter */
  notifyStatusMessage("Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void GoldfeatherReader::dataCheck(bool preflight, size_t voxels, size_t fields, size_t ensembles)
{
  setErrorCondition(0);
  std::stringstream ss;
  SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();

  if (getInputFile().empty() == true)
  {
    ss << ClassName() << " needs the Input File Set and it was not.";
    setErrorCondition(-387);
    addErrorMessage(getHumanLabel(), ss.str(), getErrorCondition());
  }
  else if (MXAFileInfo::exists(getInputFile()) == false)
  {
    ss << "The input file does not exist.";
    setErrorCondition(-388);
    addErrorMessage(getHumanLabel(), ss.str(), getErrorCondition());
  }


  DREAM3D::SurfaceMesh::VertListPointer_t vertices = DREAM3D::SurfaceMesh::VertList_t::CreateArray(1, DREAM3D::VertexData::SurfaceMeshNodes);
  DREAM3D::SurfaceMesh::FaceListPointer_t triangles = DREAM3D::SurfaceMesh::FaceList_t::CreateArray(1, DREAM3D::FaceData::SurfaceMeshFaces);

  sm->setVertices(vertices);
  sm->setFaces(triangles);

  DoubleArrayType::Pointer normalsPtr = DoubleArrayType::CreateArray(1, 3, DREAM3D::VertexData::SurfaceMeshNodeNormals);
  //addCreatedCellData( normalsPtr->GetName());
  sm->addVertexData(normalsPtr->GetName(), normalsPtr);

  DoubleArrayType::Pointer pcurv1Ptr = DoubleArrayType::CreateArray(1, 1, "Principal_Curvature_1");
  //addCreatedCellData( pcurv1Ptr->GetName());
  sm->addVertexData(pcurv1Ptr->GetName(), pcurv1Ptr);

  DoubleArrayType::Pointer pcurv2Ptr = DoubleArrayType::CreateArray(1, 1, "Principal_Curvature_2");
 // addCreatedCellData( pcurv2Ptr->GetName());
  sm->addVertexData(pcurv2Ptr->GetName(), pcurv2Ptr);

  DoubleArrayType::Pointer pDirection1Ptr = DoubleArrayType::CreateArray(1, 3, "Principal_Direction_1");
 // addCreatedCellData( pDirection1Ptr->GetName());
  sm->addVertexData(pDirection1Ptr->GetName(), pDirection1Ptr);

  DoubleArrayType::Pointer pDirection2Ptr = DoubleArrayType::CreateArray(1, 3, "Principal_Direction_2");
//  addCreatedCellData( pDirection2Ptr->GetName());
  sm->addVertexData(pDirection2Ptr->GetName(), pDirection2Ptr);


  DataArray<int32_t>::Pointer faceLabelPtr = DataArray<int32_t>::CreateArray(1, 2, DREAM3D::FaceData::SurfaceMeshFaceLabels);
//  addCreatedFieldData( faceLabelPtr->GetName());
  sm->addFaceData(faceLabelPtr->GetName(), faceLabelPtr);

  DoubleArrayType::Pointer triNormalsPtr = DoubleArrayType::CreateArray(1, 3, DREAM3D::FaceData::SurfaceMeshFaceNormals);
//  addCreatedFieldData( triNormalsPtr->GetName());
  sm->addFaceData(triNormalsPtr->GetName(), triNormalsPtr);

}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void AbaqusSurfaceMeshWriter::execute()
{
  int err = 0;
  std::stringstream ss;

  SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
  dataCheck(false, 1, 1, 1);
  if(getErrorCondition() < 0)
  {
    return;
  }

  // Make sure any directory path is also available as the user may have just typed
  // in a path without actually creating the full path
  std::string parentPath = MXAFileInfo::parentPath(getOutputFile());
  if(!MXADir::mkdir(parentPath, true))
  {
    std::stringstream ss;
    ss << "Error creating parent path '" << parentPath << "'";
    notifyErrorMessage(ss.str(), -1);
    setErrorCondition(-1);
    return;
  }

  DREAM3D::SurfaceMesh::VertListPointer_t nodesPtr = sm->getVertices();
  DREAM3D::SurfaceMesh::FaceListPointer_t trianglePtr = sm->getFaces();

  // Get the Labels(GrainIds or Region Ids) for the triangles
  Int32ArrayType::Pointer faceLabelsPtr = boost::dynamic_pointer_cast<Int32ArrayType>(sm->getFaceData(DREAM3D::FaceData::SurfaceMeshFaceLabels));
  int32_t* faceLabels = faceLabelsPtr->GetPointer(0);

  // Store all the unique Spins
  std::set<int> uniqueSpins;
  for (int i = 0; i < trianglePtr->GetNumberOfTuples(); i++)
  {
    uniqueSpins.insert(faceLabels[i*2]);
    uniqueSpins.insert(faceLabels[i*2+1]);
  }

  FILE* f = fopen(m_OutputFile.c_str(), "wb");
  ScopedFileMonitor fileMonitor(f);

  err = writeHeader(f, nodesPtr->GetNumberOfTuples(), trianglePtr->GetNumberOfTuples(), uniqueSpins.size()-1);
  err = writeNodes(f);
  err = writeTriangles(f);
  err = writeGrains(f);

  setErrorCondition(0);
  notifyStatusMessage("Complete");

  return;
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void SurfaceMeshDataContainerWriter::writeXdmfGridHeader()
{
  if (m_WriteXdmfFile == false || m_XdmfPtr == NULL)
  {
    return;
  }
  DREAM3D::SurfaceMesh::FaceListPointer_t faces = getSurfaceMeshDataContainer()->getFaces();
  if (NULL == faces.get())
  {
    return;
  }
  DREAM3D::SurfaceMesh::VertListPointer_t verts = getSurfaceMeshDataContainer()->getVertices();
  if(NULL == verts.get())
  {
    return;
  }

  std::ostream& out = *m_XdmfPtr;
  out << "  <Grid Name=\"SurfaceMesh DataContainer\">" << std::endl;

  out << "    <Topology TopologyType=\"Triangle\" NumberOfElements=\"" << faces->GetNumberOfTuples() << "\">" << std::endl;
  out << "      <DataItem Format=\"HDF\" NumberType=\"Int\" Dimensions=\"" << faces->GetNumberOfTuples() << " 3\">" << std::endl;
  ssize_t nameSize = H5Fget_name(m_HdfFileId, NULL, 0) + 1;
  std::vector<char> nameBuffer(nameSize, 0);
  nameSize = H5Fget_name(m_HdfFileId, &(nameBuffer.front()), nameSize);
  std::string hdfFileName(&(nameBuffer.front()), nameSize);
  hdfFileName = MXAFileInfo::filename(hdfFileName);
  out << "        " << hdfFileName << ":/SurfaceMeshDataContainer/Faces" << std::endl;
  out << "      </DataItem>" << std::endl;
  out << "    </Topology>" << std::endl;

  out << "    <Geometry Type=\"XYZ\">" << std::endl;
  out << "      <DataItem Format=\"HDF\"  Dimensions=\"" << verts->GetNumberOfTuples() << " 3\" NumberType=\"Float\" Precision=\"4\">" << std::endl;
  out << "        " << hdfFileName << ":/SurfaceMeshDataContainer/Vertices" << std::endl;
  out << "      </DataItem>" << std::endl;
  out << "    </Geometry>" << std::endl;
  out << "" << std::endl;
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void SurfaceMeshDataContainerWriter::writeXdmfGridFooter()
{
  if (m_WriteXdmfFile == false || m_XdmfPtr == NULL)
  {
    return;
  }
  DREAM3D::SurfaceMesh::FaceListPointer_t faces = getSurfaceMeshDataContainer()->getFaces();
  if (NULL == faces.get())
  {
    return;
  }
  std::ostream& out = *m_XdmfPtr;
  out << "  </Grid>" << std::endl;
  out << "    <!-- *************** END OF SurfaceMesh DataContainer *************** -->" << std::endl;
  out << std::endl;
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void SurfaceMeshDataContainerWriter::dataCheck(bool preflight, size_t voxels, size_t fields, size_t ensembles)
{
  setErrorCondition(0);
  std::stringstream ss;
  SurfaceMeshDataContainer* m = getSurfaceMeshDataContainer();

  if(NULL == m)
  {
    setErrorCondition(-383);
    addErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer is missing", getErrorCondition());
  }
  if(m_HdfFileId < 0)
  {
    setErrorCondition(-150);
    addErrorMessage(getHumanLabel(), "The HDF5 file id was < 0. This means this value was not set correctly from the calling object.", getErrorCondition());
  }

}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
int AbaqusSurfaceMeshWriter::writeNodes(FILE* f)
{
  DREAM3D::SurfaceMesh::VertListPointer_t nodesPtr = getSurfaceMeshDataContainer()->getVertices();
  DREAM3D::SurfaceMesh::Vert_t* nodes = nodesPtr->GetPointer(0);
  size_t numNodes = nodesPtr->GetNumberOfTuples();
  int err = 0;
  fprintf(f, "*Node,NSET=NALL\n");
  //1, 72.520433763730, 70.306420652241, 100.000000000000


  for(size_t i = 1; i <= numNodes; ++i)
  {
    DREAM3D::SurfaceMesh::Vert_t& n = nodes[i-1];
    fprintf(f, "%lu, %0.6f, %0.6f, %0.6f\n", i, n.pos[0], n.pos[1], n.pos[2]);
  }

  return err;
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void GenerateNodeTriangleConnectivity::dataCheck()
{
  setErrorCondition(0);

  SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
  if(NULL == sm)
  {
    setErrorCondition(-384);
    notifyErrorMessage(getHumanLabel(), "SurfaceMeshDataContainer is missing", getErrorCondition());
  }
  else
  {
    // We MUST have Nodes
    if(sm->getVertices().get() == NULL)
    {
      setErrorCondition(-384);
      notifyErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Nodes", getErrorCondition());
    }

    // We MUST have Triangles defined also.
    if(sm->getFaces().get() == NULL)
    {
      setErrorCondition(-384);
      notifyErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Triangles", getErrorCondition());
    }
    else
    {
      // This depends on the triangles array already being created
      int size = sm->getFaces()->GetNumberOfTuples();
      m_SurfaceMeshTriangleEdgesPtr = sattrMat->createNonPrereqArray<DataArray<int32_t>, AbstractFilter, int32_t>(this, m_CellAttributeMatrixName,  m_SurfaceMeshTriangleEdgesArrayName, 0, size, 3); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
      if( NULL != m_SurfaceMeshTriangleEdgesPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
      { m_SurfaceMeshTriangleEdges = m_SurfaceMeshTriangleEdgesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
    }

    // We do not know the size of the array so we can not use the macro so we just manually call
    // the needed methods that will propagate these array additions to the pipeline
    DataArray<int>::Pointer uniqueEdgesArray = DataArray<int>::CreateArray(1, 2, SIMPL::CellData::SurfaceMeshUniqueEdges);
    sm->getAttributeMatrix(getCellAttributeMatrixName())->addAttributeArray(SIMPL::CellData::SurfaceMeshUniqueEdges, uniqueEdgesArray);

    // This is just for tracking what Arrays are being created by this filter. Normally the macro
    // would do this for us.
    addCreatedCellData(SIMPL::CellData::SurfaceMeshUniqueEdges);
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
int AbaqusSurfaceMeshWriter::writeTriangles(FILE* f)
{
  int err = 0;
  DREAM3D::SurfaceMesh::FaceListPointer_t trianglePtr = getSurfaceMeshDataContainer()->getFaces();
  DREAM3D::SurfaceMesh::Face_t* triangles = trianglePtr->GetPointer(0);
  size_t numTri = trianglePtr->GetNumberOfTuples();

  fprintf(f, "*ELEMENT, TYPE=%s\n", TRI_ELEMENT_TYPE);
  for(size_t i = 1; i <= numTri; ++i)
  {

    // When we get the node index, add 1 to it because Abaqus number is 1 based.
    int nId0 = triangles[i-1].verts[0] + 1;
    int nId1 = triangles[i-1].verts[1] + 1;
    int nId2 = triangles[i-1].verts[2] + 1;
    fprintf(f, "%lu, %d, %d, %d\n", i, nId0, nId1, nId2);
  }
  return err;
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void GenerateNodeTriangleConnectivity::dataCheck(bool preflight, size_t voxels, size_t fields, size_t ensembles)
{
  setErrorCondition(0);
  std::stringstream ss;
  SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
  if(NULL == sm)
  {
    addErrorMessage(getHumanLabel(), "SurfaceMeshDataContainer is missing", -383);
    setErrorCondition(-384);
  }
  else
  {
    // We MUST have Nodes
    if(sm->getVertices().get() == NULL)
    {
      addErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Nodes", -384);
      setErrorCondition(-384);
    }

    // We MUST have Triangles defined also.
    if(sm->getFaces().get() == NULL)
    {
      addErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Triangles", -383);
      setErrorCondition(-384);
    }
    else
    {
      // This depends on the triangles array already being created
      int size = sm->getFaces()->GetNumberOfTuples();
      CREATE_NON_PREREQ_DATA(sm, DREAM3D, CellData, SurfaceMeshTriangleEdges, ss, int32_t, Int32ArrayType, 0, size, 3)
    }

    // We do not know the size of the array so we can not use the macro so we just manually call
    // the needed methods that will propagate these array additions to the pipeline
    DataArray<int>::Pointer uniqueEdgesArray = DataArray<int>::CreateArray(1, 2, DREAM3D::CellData::SurfaceMeshUniqueEdges);
    sm->addCellData(DREAM3D::CellData::SurfaceMeshUniqueEdges, uniqueEdgesArray);

    // This is just for tracking what Arrays are being created by this filter. Normally the macro
    // would do this for us.
    addCreatedCellData(DREAM3D::CellData::SurfaceMeshUniqueEdges);
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void GenerateNodeTriangleConnectivity::generateConnectivity()
{

  // Get our Reference counted Array of Triangle Structures
  StructArray<SurfaceMesh::DataStructures::Face_t>::Pointer trianglesPtr = getSurfaceMeshDataContainer()->getTriangles();
  if(NULL == trianglesPtr.get())
  {
    setErrorCondition(-556);
    notifyErrorMessage("The SurfaceMesh DataContainer Does NOT contain Triangles", -556);
    return;
  }
  int ntri = trianglesPtr->GetNumberOfTuples();
  NodeTrianglesMap_t m_Node2Triangle;
  notifyStatusMessage("Creating the Mapping of Triangles to Node");
  // get the triangle definitions - use the pointer to the start of the Struct Array
  Triangle* triangles = trianglesPtr->GetPointer(0);
  // Generate the map of node_id -> Triangles that include that node_id value
  for(int i = 0; i < ntri; ++i)
  {
    Triangle& tri = triangles[i];
    m_Node2Triangle[tri.node_id[0]].insert(i);
    m_Node2Triangle[tri.node_id[1]].insert(i);
    m_Node2Triangle[tri.node_id[2]].insert(i);
  }
  if (getCancel() == true) { return; }

  ManagedPointerArray<int>::Pointer nodeTriangleArray = ManagedPointerArray<int>::CreateArray(m_Node2Triangle.size(), DREAM3D::CellData::SurfaceMeshNodeTriangles);

  float progIndex = 0.0;
  float curPercent = 0.0;
  float total = static_cast<float>(m_Node2Triangle.size());
  std::stringstream ss;

  // Loop over each entry in the map
  for(NodeTrianglesMap_t::iterator iter = m_Node2Triangle.begin(); iter != m_Node2Triangle.end(); ++iter)
  {
    if ( progIndex/total * 100.0f > (curPercent) )
    {
      ss.str("");
      ss << (progIndex/total * 100.0f) << "% Complete";
      notifyStatusMessage(ss.str());
      curPercent += 5.0f;
    }
    progIndex++;
    if (getCancel() == true) { return; }

    int nodeId = (*iter).first;
    ManagedPointerArray<int>::Data_t& entry = *(nodeTriangleArray->GetPointer(nodeId));
    UniqueTriangleIds_t& triangles = (*iter).second;
    // Allocate enough memory to hold the list of triangles
    entry.count = triangles.size();
    if (entry.count > 0)
    {
      entry.data = (int*)(malloc(sizeof(int) * entry.count));
      int index = 0;
      for(UniqueTriangleIds_t::iterator tIter = triangles.begin(); tIter != triangles.end(); ++tIter)
      {
        entry.data[index++] = *tIter; // Copy the value from the triangle Ids set into the ManagedPointer
      }
    }
  }

  getSurfaceMeshDataContainer()->addCellData(nodeTriangleArray->GetName(), nodeTriangleArray);
  return;
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
int AbaqusSurfaceMeshWriter::writeGrains(FILE* f)
{

  //*Elset, elset=Grain1
  //1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16

  int err = 0;

  std::stringstream ss;
  SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
  DREAM3D::SurfaceMesh::VertListPointer_t nodesPtr = sm->getVertices();
  DREAM3D::SurfaceMesh::FaceListPointer_t trianglePtr = sm->getFaces();

  // Get the Labels(GrainIds or Region Ids) for the triangles
  Int32ArrayType::Pointer faceLabelsPtr = boost::dynamic_pointer_cast<Int32ArrayType>(sm->getFaceData(DREAM3D::FaceData::SurfaceMeshFaceLabels));
  int32_t* faceLabels = faceLabelsPtr->GetPointer(0);

  int nTriangles = trianglePtr->GetNumberOfTuples();

  // Store all the unique Spins
  std::set<int> uniqueSpins;
  for (int i = 0; i < nTriangles; i++)
  {
    uniqueSpins.insert(faceLabels[i*2]);
    uniqueSpins.insert(faceLabels[i*2+1]);
  }

  int spin = 0;

  //Loop over the unique Spins
  for (std::set<int>::iterator spinIter = uniqueSpins.begin(); spinIter != uniqueSpins.end(); ++spinIter )
  {
    spin = *spinIter;
    if(spin < 0) { continue; }

    fprintf(f, "*ELSET, ELSET=Grain%d\n", spin);

    ss.str("");
    ss << "Writing ELSET for Grain Id " << spin;
    notifyStatusMessage(ss.str());


    // Loop over all the triangles for this spin
    int lineCount = 0;
    for(int t = 0; t < nTriangles; ++t)
    {
      if (faceLabels[t*2] != spin && faceLabels[t*2+1] != spin)
      {
        continue; // We do not match either spin so move to the next triangle
      }

      // Only print 15 Triangles per line
      if (lineCount == 15)
      {
        fprintf(f, ", %d\n", t);
        lineCount = 0;
      }
      else if(lineCount == 0) // First value on the line
      {
        fprintf(f,"%d", t);
        lineCount++;
      }
      else
      {
        fprintf(f,", %d", t);
        lineCount++;
      }

    }
    // Make sure we have a new line at the end of the section
    if (lineCount != 0)
    {
      fprintf(f, "\n");
    }
  }
  return err;
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void SurfaceMeshDataContainerWriter::execute()
{
  int err = 0;
  std::stringstream ss;
  setErrorCondition(err);
  SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
  if(NULL == sm)
  {
    setErrorCondition(-999);
    notifyErrorMessage("The Surfacemesh DataContainer Object was NULL", -999);
    return;
  }
  setErrorCondition(0);

  // Create the HDF5 Group for the Data Container
  err = H5Utilities::createGroupsFromPath(DREAM3D::HDF5::SurfaceMeshDataContainerName.c_str(), m_HdfFileId);
  if (err < 0)
  {
    ss.str("");
    ss << "Error creating HDF Group " << DREAM3D::HDF5::SurfaceMeshDataContainerName << std::endl;
    setErrorCondition(-60);
    addErrorMessage(getHumanLabel(), ss.str(), err);
    return;
  }
  hid_t dcGid = H5Gopen(m_HdfFileId, DREAM3D::HDF5::SurfaceMeshDataContainerName.c_str(), H5P_DEFAULT );
  if (dcGid < 0)
  {
    ss.str("");
    ss << "Error opening Group " << DREAM3D::HDF5::SurfaceMeshDataContainerName << std::endl;
    setErrorCondition(-61);
    addErrorMessage(getHumanLabel(), ss.str(), err);
    return;
  }

  // Add some VTK hints into the group
  err = createVtkObjectGroup(DREAM3D::HDF5::SurfaceMeshDataContainerName, H5_VTK_POLYDATA);
  if (err < 0)  {
    return;
  }

  writeXdmfGridHeader();


  H5GroupAutoCloser dcGidAutoCloser(&dcGid);

  err = writeVertices(dcGid);
  if (err < 0)
  {
    return;
  }

  err = writeMeshVertLinks(dcGid);
  if (err < 0)
  {
    return;
  }

  err = writeVertexAttributeData(dcGid);
  if (err < 0)
  {
    return;
  }


  err = writeFaces(dcGid);
  if (err < 0)
  {
    return;
  }

  err = writeMeshFaceNeighborLists(dcGid);
  if (err < 0)
  {
    return;
  }

  err = writeFaceAttributeData(dcGid);
  if (err < 0)
  {
    return;
  }

  err = writeEdges(dcGid);
  if (err < 0)
  {
    return;
  }

  err = writeEdgeAttributeData(dcGid);
  if (err < 0)
  {
    return;
  }


  err = writeFieldData(dcGid);
  if (err < 0)
  {
    H5Gclose(dcGid); // Close the Data Container Group
    return;
  }

  err = writeEnsembleData(dcGid);
  if (err < 0)
  {
    H5Gclose(dcGid); // Close the Data Container Group
    return;
  }


  // Now finally close the group and the HDf5 File
  H5Gclose(dcGid); // Close the Data Container Group
  dcGid = -1;

  writeXdmfGridFooter();


  notifyStatusMessage("Complete");
}
Example #22
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void RemoveArrays::dataCheck(bool preflight, size_t voxels, size_t fields, size_t ensembles)
{
  setErrorCondition(0);
  typedef std::set<std::string> NameList_t;

  VoxelDataContainer* m = getVoxelDataContainer();
  if (NULL != m)
  {
    for(NameList_t::iterator iter = m_SelectedVoxelCellArrays.begin(); iter != m_SelectedVoxelCellArrays.end(); ++iter)
    {
      m->removeCellData(*iter);
    }
    for(NameList_t::iterator iter = m_SelectedVoxelFieldArrays.begin(); iter != m_SelectedVoxelFieldArrays.end(); ++iter)
    {
      m->removeFieldData(*iter);
    }
    for(NameList_t::iterator iter = m_SelectedVoxelEnsembleArrays.begin(); iter != m_SelectedVoxelEnsembleArrays.end(); ++iter)
    {
      m->removeEnsembleData(*iter);
    }
  }



  SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
  if (NULL != sm)
  {
    for(NameList_t::iterator iter = m_SelectedSurfaceVertexArrays.begin(); iter != m_SelectedSurfaceVertexArrays.end(); ++iter)
    {
      sm->removeVertexData(*iter);
    }
    for(NameList_t::iterator iter = m_SelectedSurfaceFaceArrays.begin(); iter != m_SelectedSurfaceFaceArrays.end(); ++iter)
    {
      sm->removeFaceData(*iter);
    }
    for(NameList_t::iterator iter = m_SelectedSurfaceEdgeArrays.begin(); iter != m_SelectedSurfaceEdgeArrays.end(); ++iter)
    {
      sm->removeEdgeData(*iter);
    }
    for(NameList_t::iterator iter = m_SelectedSurfaceFieldArrays.begin(); iter != m_SelectedSurfaceFieldArrays.end(); ++iter)
    {
      sm->removeFieldData(*iter);
    }
    for(NameList_t::iterator iter = m_SelectedSurfaceEnsembleArrays.begin(); iter != m_SelectedSurfaceEnsembleArrays.end(); ++iter)
    {
      sm->removeEnsembleData(*iter);
    }
  }

  SolidMeshDataContainer* sol = getSolidMeshDataContainer();
  if (NULL != sol)
  {
    for(NameList_t::iterator iter = m_SelectedSolidMeshVertexArrays.begin(); iter != m_SelectedSolidMeshVertexArrays.end(); ++iter)
    {
      sol->removeVertexData(*iter);
    }
    for(NameList_t::iterator iter = m_SelectedSolidMeshFaceArrays.begin(); iter != m_SelectedSolidMeshFaceArrays.end(); ++iter)
    {
      sol->removeFaceData(*iter);
    }
    for(NameList_t::iterator iter = m_SelectedSolidMeshEdgeArrays.begin(); iter != m_SelectedSolidMeshEdgeArrays.end(); ++iter)
    {
      sol->removeEdgeData(*iter);
    }
  }

}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
int BinaryNodesTrianglesReader::read()
{

    SurfaceMeshDataContainer *sm = getSurfaceMeshDataContainer();
    int err = 0;
    setErrorCondition(err);

    std::stringstream s;
    // Open the Nodes file for reading
    FILE* nodesFile = fopen(m_BinaryNodesFile.c_str(), "rb+");
    if(nodesFile == NULL)
    {
        s.str("");
        s << "Error opening nodes file '" << m_BinaryNodesFile << "'";
        setErrorCondition(786);
        //    PipelineMessage em (getHumanLabel(), s.str(), -1);
        //    addErrorMessage(em);
        //    notifyMessage(em);
        return getErrorCondition();
    }
    ScopedFileMonitor nodesMonitor(nodesFile);

    // Calculate how many nodes are in the file based on the file size
    fseek(nodesFile, 0, SEEK_END);
    size_t fLength = ftell(nodesFile);
    size_t nNodes = fLength / SurfaceMesh::NodesFile::ByteCount;
    fseek(nodesFile, 0, SEEK_SET);
    fLength = ftell(nodesFile);
    if(0 != fLength)
    {
        s.str("");
        s << getNameOfClass() << ": Error Could not rewind to beginning of file after nodes count.'" << m_BinaryNodesFile << "'";
        setErrorCondition(787);
        //    PipelineMessage em (getHumanLabel(), s.str(), -1);
        //    addErrorMessage(em);
        //    notifyMessage(em);
        return getErrorCondition();
    }
    s.str("");
    s << "Calc Node Count from Nodes.bin File: " << nNodes;
    notifyStatusMessage(s.str());

    // Open the triangles file for reading
    FILE* triFile = fopen(m_BinaryTrianglesFile.c_str(), "rb+");
    if(triFile == NULL)
    {
        s.str("");
        s << getNameOfClass() << ": Error opening Triangles file '" << m_BinaryTrianglesFile << "'";
        setErrorCondition(788);
        //    PipelineMessage em (getHumanLabel(), s.str(), -1);
        //    addErrorMessage(em);
        //    notifyMessage(em);
        return getErrorCondition();
    }

    ScopedFileMonitor trianglesMonitor(triFile);
    // Calculate how many Triangles are in the file based in the file size
    fseek(triFile, 0, SEEK_END);
    fLength = ftell(triFile);
    size_t nTriangles = fLength / SurfaceMesh::TrianglesFile::ByteCount;
    fseek(triFile, 0, SEEK_SET);
    fLength = ftell(triFile);
    if(0 != fLength)
    {
        s.str("");
        s << getNameOfClass() << ": Error Could not rewind to beginning of file after triangles count.'" << m_BinaryTrianglesFile << "'";
        setErrorCondition(789);
        //    PipelineMessage em (getHumanLabel(), s.str(), -1);
        //    addErrorMessage(em);
        //    notifyMessage(em);
        return getErrorCondition();
    }
    s.str("");
    s << "Calc Triangle Count from Triangles.bin File: " << nTriangles;
    notifyStatusMessage(s.str());

    // Allocate all the nodes
    typedef DREAM3D::SurfaceMesh::Vert_t Vert_t;
    StructArray<Vert_t>::Pointer m_NodeListPtr = StructArray<Vert_t>::CreateArray(nNodes, DREAM3D::VertexData::SurfaceMeshNodes);
    Vert_t* m_NodeList = m_NodeListPtr->GetPointer(0);

    Int8ArrayType::Pointer nodeTypePtr = Int8ArrayType::CreateArray(nNodes, 1, DREAM3D::VertexData::SurfaceMeshNodeType);
    nodeTypePtr->initializeWithZeros();
    int8_t* nodeType = nodeTypePtr->GetPointer(0);

    s.str("");
    s << "Reading Nodes file into Memory";
    notifyStatusMessage(s.str());
    size_t nread = 0;
    SurfaceMesh::NodesFile::NodesFileRecord_t nRecord;

    for (size_t i = 0; i < nNodes; i++)
    {

        nread = fread(&nRecord, SurfaceMesh::NodesFile::ByteCount, 1, nodesFile); // Read one set of positions from the nodes file
        if(nread != 1)
        {
            break;
        }
        DREAM3D::SurfaceMesh::Vert_t& node = m_NodeList[nRecord.nodeId];
        node.pos[0] = nRecord.x;
        node.pos[1] = nRecord.y;
        node.pos[2] = nRecord.z;
        nodeType[nRecord.nodeId] = nRecord.nodeKind;
    }

    s.str("");
    s << "Reading Triangles file into Memory";
    notifyStatusMessage(s.str());

    // Allocate all the Triangle Objects
    typedef DREAM3D::SurfaceMesh::Face_t Face_t;
    StructArray<Face_t>::Pointer m_TriangleListPtr = StructArray<Face_t>::CreateArray(nTriangles, DREAM3D::FaceData::SurfaceMeshFaces);
    Face_t* m_TriangleList = m_TriangleListPtr->GetPointer(0);
    ::memset(m_TriangleList, 0xAB, sizeof(Face_t) * nTriangles);

    DataArray<int32_t>::Pointer faceLabelPtr = DataArray<int32_t>::CreateArray(nTriangles, 2, DREAM3D::FaceData::SurfaceMeshFaceLabels);
    int32_t* faceLabels = faceLabelPtr->GetPointer(0);
    faceLabelPtr->initializeWithZeros();


    SurfaceMesh::TrianglesFile::TrianglesFileRecord_t tRecord;
    for (size_t i = 0; i < nTriangles; i++)
    {
        // Read from the Input Triangles Temp File
        nread = fread(&tRecord, SurfaceMesh::TrianglesFile::ByteCount, 1, triFile);
        if(nread != 1)
        {
            break;
        }

        DREAM3D::SurfaceMesh::Face_t& triangle = m_TriangleList[tRecord.triId];

        triangle.verts[0] = tRecord.nodeId_0;
        triangle.verts[1] = tRecord.nodeId_1;
        triangle.verts[2] = tRecord.nodeId_2;
        faceLabels[tRecord.triId * 2] = tRecord.label_0;
        faceLabels[tRecord.triId * 2 + 1] = tRecord.label_1;
    }

    sm->setVertices(m_NodeListPtr);
    sm->setFaces(m_TriangleListPtr);
    sm->addFaceData(faceLabelPtr->GetName(), faceLabelPtr);
    sm->addVertexData(nodeTypePtr->GetName(), nodeTypePtr);





    // The ScopedFileMonitor classes will take care of closing the files

    return getErrorCondition();
}
Example #24
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void FindFaceAverage::dataCheckSurfaceMesh(bool preflight, size_t voxels, size_t fields, size_t ensembles)
{
  setErrorCondition(0);
  std::stringstream ss;
  SurfaceMeshDataContainer* sm = getSurfaceMeshDataContainer();
  if(NULL == sm)
  {
    addErrorMessage(getHumanLabel(), "SurfaceMeshDataContainer is missing", -383);
    setErrorCondition(-383);
  }
  else
  {
    // We MUST have Triangles defined.
    if(sm->getFaces().get() == NULL)
    {
      addErrorMessage(getHumanLabel(), "SurfaceMesh DataContainer missing Triangles", -385);
      setErrorCondition(-385);
    }
    else
    {
      GET_PREREQ_DATA(sm, DREAM3D, FaceData, SurfaceMeshGrainFaceId, ss, -387, int32_t, Int32ArrayType, fields, 1)
      if(1==m_AverageMethod)
      {
        GET_PREREQ_DATA(sm, DREAM3D, FaceData, SurfaceMeshTriangleAreas, ss, -387, double, DoubleArrayType, fields, 1)
      }

      if(m_SelectedFaceArrayName.empty() == true)
      {
        setErrorCondition(-11000);
        addErrorMessage(getHumanLabel(), "An array from the Face Data Container must be selected.", getErrorCondition());
      }
      else if(preflight)
      {
        IDataArray::Pointer inputData = sm->getFaceData(m_SelectedFaceArrayName);
        if (NULL == inputData.get())
        {
          ss.str("");
          ss << "Selected array '" << m_SelectedFaceArrayName << "' does not exist in the Surface Mesh Data Container. Was it spelled correctly?";
          setErrorCondition(-11001);
          notifyErrorMessage(ss.str(), getErrorCondition());
          return;
        }

        int numberOfComponents = inputData->GetNumberOfComponents();
        std::string dType = inputData->getTypeAsString();
        IDataArray::Pointer p = IDataArray::NullPointer();
        if (dType.compare("int8_t") == 0)
        {
          p = Int8ArrayType::CreateArray(1, numberOfComponents, m_SelectedFaceArrayName);
        }
        else if (dType.compare("uint8_t") == 0)
        {
          p = UInt8ArrayType::CreateArray(1, numberOfComponents, m_SelectedFaceArrayName);
        }
        else if (dType.compare("int16_t") == 0)
        {
          p = Int16ArrayType::CreateArray(1, numberOfComponents, m_SelectedFaceArrayName);
        }
        else if (dType.compare("uint16_t") == 0)
        {
          p = UInt16ArrayType::CreateArray(1, numberOfComponents, m_SelectedFaceArrayName);
        }
        else if (dType.compare("int32_t") == 0)
        {
          p = Int32ArrayType::CreateArray(1, numberOfComponents, m_SelectedFaceArrayName);
        }
        else if (dType.compare("uint32_t") == 0)
        {
          p = UInt32ArrayType::CreateArray(1, numberOfComponents, m_SelectedFaceArrayName);
        }
        else if (dType.compare("int64_t") == 0)
        {
          p = Int64ArrayType::CreateArray(1, numberOfComponents, m_SelectedFaceArrayName);
        }
        else if (dType.compare("uint64_t") == 0)
        {
          p = UInt64ArrayType::CreateArray(1, numberOfComponents, m_SelectedFaceArrayName);
        }
        else if (dType.compare("float") == 0)
        {
          p = FloatArrayType::CreateArray(1, numberOfComponents, m_SelectedFaceArrayName);
        }
        else if (dType.compare("double") == 0)
        {
          p = DoubleArrayType::CreateArray(1, numberOfComponents, m_SelectedFaceArrayName);
        }
        else if (dType.compare("bool") == 0)
        {
          p = BoolArrayType::CreateArray(1, numberOfComponents, m_SelectedFaceArrayName);
        }
        sm->addFieldData(p->GetName(), p);
      }
    }
  }
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void GoldfeatherReader::execute()
{
  int err = 0;
  std::stringstream ss;
  setErrorCondition(err);
  SurfaceMeshDataContainer* m = getSurfaceMeshDataContainer();
  if(NULL == m)
  {
    setErrorCondition(-999);
    notifyErrorMessage("The Voxel DataContainer Object was NULL", -999);
    return;
  }
  setErrorCondition(0);



  FILE* f = fopen(m_InputFile.c_str(), "r");
  if (NULL == f)
  {
    setErrorCondition(-999);
    notifyErrorMessage("Error opening Input file", getErrorCondition());
    return;
  }
  ScopedFileMonitor fileMonitor(f);

  int nNodes = 0;
  fscanf(f, "%d\n", &nNodes);

  dataCheck(false, nNodes, 1, 1);

  // Allocate the Nodes, Normals, curvatures and principal direction vectors
  DREAM3D::SurfaceMesh::VertListPointer_t nodesPtr = DREAM3D::SurfaceMesh::VertList_t::CreateArray(nNodes, DREAM3D::VertexData::SurfaceMeshNodes);
  nodesPtr->initializeWithZeros();
  DREAM3D::SurfaceMesh::Vert_t* nodes = nodesPtr->GetPointer(0);


  DoubleArrayType::Pointer normalsPtr = DoubleArrayType::CreateArray(nNodes, 3, DREAM3D::VertexData::SurfaceMeshNodeNormals);
  double* normals = normalsPtr->GetPointer(0);

  DoubleArrayType::Pointer pcurv1Ptr = DoubleArrayType::CreateArray(nNodes, 1, "Principal_Curvature_1");
  double* pcurv1 = pcurv1Ptr->GetPointer(0);

  DoubleArrayType::Pointer pcurv2Ptr = DoubleArrayType::CreateArray(nNodes, 1, "Principal_Curvature_2");
  double* pcurv2 = pcurv2Ptr->GetPointer(0);

  DoubleArrayType::Pointer pDirection1Ptr = DoubleArrayType::CreateArray(nNodes, 3, "Principal_Direction_1");
  double* pDirection1 = pDirection1Ptr->GetPointer(0);

  DoubleArrayType::Pointer pDirection2Ptr = DoubleArrayType::CreateArray(nNodes, 3, "Principal_Direction_2");
  double* pDirection2 = pDirection2Ptr->GetPointer(0);

  float x, y, z, n0, n1, n2, p1, p2;
  for(int n = 0; n < nNodes; ++n)
  {
    fscanf(f, "%f %f %f %f %f %f %f %f\n", &x, &y, &z, &n0, &n1, &n2, &p1, &p2);
    nodes[n].pos[0] = x;
    nodes[n].pos[1] = y;
    nodes[n].pos[2] = z;
    normals[n*3+0] = n0;
    normals[n*3+1] = n1;
    normals[n*3+2] = n2;
    pcurv1[n] = p1;
    pcurv2[n] = p2;

    // Read the next line of the data which is the principal direction vectors
    fscanf(f, "%f %f %f %f %f %f\n", &x, &y, &z, &n0, &n1, &n2);
    pDirection1[n*3+0] = x;
    pDirection1[n*3+1] = y;
    pDirection1[n*3+2] = z;

    pDirection2[n*3+0] = n0;
    pDirection2[n*3+1] = n1;
    pDirection2[n*3+2] = n2;

  }

  m->setVertices(nodesPtr);
  m->addVertexData(normalsPtr->GetName(), normalsPtr);
  m->addVertexData(pcurv1Ptr->GetName(), pcurv1Ptr);
  m->addVertexData(pcurv2Ptr->GetName(), pcurv2Ptr);
  m->addVertexData(pDirection1Ptr->GetName(), pDirection1Ptr);
  m->addVertexData(pDirection2Ptr->GetName(), pDirection2Ptr);

  int nTriangles = 0;
  err = fscanf(f, "%d\n", &nTriangles);
  if (err < 0)
  {
    off_t fpos;
    fpos = ftell(f);
    setErrorCondition(-876);
    notifyErrorMessage("Error Reading the number of Triangles from the file", getErrorCondition());
    return;
  }

  DREAM3D::SurfaceMesh::FaceListPointer_t trianglesPtr = DREAM3D::SurfaceMesh::FaceList_t::CreateArray(nTriangles, DREAM3D::FaceData::SurfaceMeshFaces);
  trianglesPtr->initializeWithZeros();
  DREAM3D::SurfaceMesh::Face_t* triangles = trianglesPtr->GetPointer(0);

  DataArray<int32_t>::Pointer faceLabelPtr = DataArray<int32_t>::CreateArray(nTriangles, 2, DREAM3D::FaceData::SurfaceMeshFaceLabels);
  faceLabelPtr->initializeWithZeros();
  int32_t* faceLabels = faceLabelPtr->GetPointer(0);

  DoubleArrayType::Pointer triNormalsPtr = DoubleArrayType::CreateArray(nTriangles, 3, DREAM3D::FaceData::SurfaceMeshFaceNormals);
  double* triNormals = triNormalsPtr->GetPointer(0);

  for(int t = 0; t < nTriangles; ++t)
  {
    fscanf(f, "%f %f %f %f %f %f", &x, &y, &z, &n0, &n1, &n2);
    triangles[t].verts[0] = x;
    triangles[t].verts[1] = y;
    triangles[t].verts[2] = z;
  //  triangles[t].tIndex = t;
    faceLabels[t*2] = 0;
    faceLabels[t*2+1] = 1;
    triNormals[t*3+0] = n0;
    triNormals[t*3+1] = n1;
    triNormals[t*3+2] = n2;
  }

  m->setFaces(trianglesPtr);
  m->addFaceData(faceLabelPtr->GetName(), faceLabelPtr);
  m->addFaceData(triNormalsPtr->GetName(), triNormalsPtr);

  /* Let the GUI know we are done with this filter */
  notifyStatusMessage("Complete");
}