Esempio n. 1
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void ReadStlFile::eliminate_duplicate_nodes()
{
  DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(m_SurfaceMeshDataContainerName);

  TriangleGeom::Pointer triangleGeom = sm->getGeometryAs<TriangleGeom>();
  float* vertex = triangleGeom->getVertexPointer(0);
  int64_t nNodes = triangleGeom->getNumberOfVertices();
  int64_t* triangles = triangleGeom->getTriPointer(0);
  int64_t nTriangles = triangleGeom->getNumberOfTris();

  float stepX = (m_maxXcoord - m_minXcoord) / 100.0f;
  float stepY = (m_maxYcoord - m_minYcoord) / 100.0f;
  float stepZ = (m_maxZcoord - m_minZcoord) / 100.0f;

  QVector<QVector<size_t> > nodesInBin(100 * 100 * 100);

  // determine (xyz) bin each node falls in - used to speed up node comparison
  int32_t bin = 0, xBin = 0, yBin = 0, zBin = 0;
  for (int64_t i = 0; i < nNodes; i++)
  {
    xBin = (vertex[i * 3] - m_minXcoord) / stepX;
    yBin = (vertex[i * 3 + 1] - m_minYcoord) / stepY;
    zBin = (vertex[i * 3 + 2] - m_minZcoord) / stepZ;
    if (xBin == 100) { xBin = 99; }
    if (yBin == 100) { yBin = 99; }
    if (zBin == 100) { zBin = 99; }
    bin = (zBin * 10000) + (yBin * 100) + xBin;
    nodesInBin[bin].push_back(i);
  }

  // Create array to hold unique node numbers
  Int64ArrayType::Pointer uniqueIdsPtr = Int64ArrayType::CreateArray(nNodes, "uniqueIds");
  int64_t* uniqueIds = uniqueIdsPtr->getPointer(0);
  for (int64_t i = 0; i < nNodes; i++)
  {
    uniqueIds[i] = i;
  }

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

  //Parallel algorithm to find duplicate nodes
#ifdef SIMPLib_USE_PARALLEL_ALGORITHMS
  if (doParallel == true)
  {
    tbb::parallel_for(tbb::blocked_range<size_t>(0, 100 * 100 * 100),
                      FindUniqueIdsImpl(triangleGeom->getVertices(), nodesInBin, uniqueIds), tbb::auto_partitioner());

  }
  else
#endif
  {
    FindUniqueIdsImpl serial(triangleGeom->getVertices(), nodesInBin, uniqueIds);
    serial.convert(0, 100 * 100 * 100);
  }

  //renumber the unique nodes
  int64_t uniqueCount = 0;
  for (int64_t i = 0; i < nNodes; i++)
  {
    if(uniqueIds[i] == i)
    {
      uniqueIds[i] = uniqueCount;
      uniqueCount++;
    }
    else
    {
      uniqueIds[i] = uniqueIds[uniqueIds[i]];
    }
  }

  // Move nodes to unique Id and then resize nodes array
  for (int64_t i = 0; i < nNodes; i++)
  {
    vertex[uniqueIds[i] * 3] = vertex[i * 3];
    vertex[uniqueIds[i] * 3 + 1] = vertex[i * 3 + 1];
    vertex[uniqueIds[i] * 3 + 2] = vertex[i * 3 + 2];
  }
  triangleGeom->resizeVertexList(uniqueCount);

  // Update the triangle nodes to reflect the unique ids
  int64_t node1 = 0, node2 = 0, node3 = 0;
  for (int64_t i = 0; i < nTriangles; i++)
  {
    node1 = triangles[i * 3];
    node2 = triangles[i * 3 + 1];
    node3 = triangles[i * 3 + 2];

    triangles[i * 3] = uniqueIds[node1];
    triangles[i * 3 + 1] = uniqueIds[node2];
    triangles[i * 3 + 2] = uniqueIds[node3];
  }
}
Esempio n. 2
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void ReadStlFile::readFile()
{
  DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(m_SurfaceMeshDataContainerName);

  // Open File
  FILE* f = fopen(m_StlFilePath.toLatin1().data(), "rb");
  if (NULL == f)
  {
    setErrorCondition(-1003);
    notifyErrorMessage(getHumanLabel(), "Error opening STL file", -1003);
    return;
  }

  // Read Header
  char h[80];
  int32_t triCount = 0;
  fread(h, sizeof(int32_t), 20, f);
  fread(&triCount, sizeof(int32_t), 1, f);

  TriangleGeom::Pointer triangleGeom = sm->getGeometryAs<TriangleGeom>();
  triangleGeom->resizeTriList(triCount);
  triangleGeom->resizeVertexList(triCount * 3);
  float* nodes = triangleGeom->getVertexPointer(0);
  int64_t* triangles = triangleGeom->getTriPointer(0);

  // Resize the triangle attribute matrix to hold the normals and update the normals pointer
  QVector<size_t> tDims(1, triCount);
  sm->getAttributeMatrix(getFaceAttributeMatrixName())->resizeAttributeArrays(tDims);
  updateFaceInstancePointers();

  // Read the triangles
  static const size_t k_StlElementCount = 12;
  float v[k_StlElementCount];
  unsigned short attr;
  for (int32_t t = 0; t < triCount; ++t)
  {
    fread(reinterpret_cast<void*>(v), sizeof(float), k_StlElementCount, f);

    fread(reinterpret_cast<void*>(&attr), sizeof(unsigned short), 1, f);
    if (attr > 0)
    {
      std::vector<unsigned char> buffer(attr); // Allocate a buffer for the STL attribute data to be placed into
      fread( reinterpret_cast<void*>(&(buffer.front())), attr, 1, f); // Read the bytes into the buffer so that we can skip it.
    }
    if(v[3] < m_minXcoord) { m_minXcoord = v[3]; }
    if(v[3] > m_maxXcoord) { m_maxXcoord = v[3]; }
    if(v[4] < m_minYcoord) { m_minYcoord = v[4]; }
    if(v[4] > m_maxYcoord) { m_maxYcoord = v[4]; }
    if(v[5] < m_minZcoord) { m_minZcoord = v[5]; }
    if(v[5] > m_maxZcoord) { m_maxZcoord = v[5]; }
    if(v[6] < m_minXcoord) { m_minXcoord = v[6]; }
    if(v[6] > m_maxXcoord) { m_maxXcoord = v[6]; }
    if(v[7] < m_minYcoord) { m_minYcoord = v[7]; }
    if(v[7] > m_maxYcoord) { m_maxYcoord = v[7]; }
    if(v[8] < m_minZcoord) { m_minZcoord = v[8]; }
    if(v[8] > m_maxZcoord) { m_maxZcoord = v[8]; }
    if(v[9] < m_minXcoord) { m_minXcoord = v[9]; }
    if(v[9] > m_maxXcoord) { m_maxXcoord = v[9]; }
    if(v[10] < m_minYcoord) { m_minYcoord = v[10]; }
    if(v[10] > m_maxYcoord) { m_maxYcoord = v[10]; }
    if(v[11] < m_minZcoord) { m_minZcoord = v[11]; }
    if(v[11] > m_maxZcoord) { m_maxZcoord = v[11]; }
    m_FaceNormals[3 * t + 0] = v[0];
    m_FaceNormals[3 * t + 1] = v[1];
    m_FaceNormals[3 * t + 2] = v[2];
    nodes[3 * (3 * t + 0) + 0] = v[3];
    nodes[3 * (3 * t + 0) + 1] = v[4];
    nodes[3 * (3 * t + 0) + 2] = v[5];
    nodes[3 * (3 * t + 1) + 0] = v[6];
    nodes[3 * (3 * t + 1) + 1] = v[7];
    nodes[3 * (3 * t + 1) + 2] = v[8];
    nodes[3 * (3 * t + 2) + 0] = v[9];
    nodes[3 * (3 * t + 2) + 1] = v[10];
    nodes[3 * (3 * t + 2) + 2] = v[11];
    triangles[t * 3] = 3 * t + 0;
    triangles[t * 3 + 1] = 3 * t + 1;
    triangles[t * 3 + 2] = 3 * t + 2;
  }

  return;
}