示例#1
0
Vector3<float> HalfEdgeMesh::VertexNormal(unsigned int vertexIndex) const
{

  Vector3<float> n(0,0,0);
  std::vector<unsigned int> fa = FindNeighborFaces(vertexIndex);
  
  for(int i = 0; i < fa.size(); i++) {
	n += f(fa.at(i)).normal;
  }

  return n.Normalize();
}
示例#2
0
//-----------------------------------------------------------------------------
Vector3<float> SimpleMesh::VertexNormal(unsigned int vertexIndex) const{

  std::vector<unsigned int> neighborFaces = FindNeighborFaces(vertexIndex);

  Vector3<float> n(0,0,0);

  const unsigned int numCandidates = neighborFaces.size();
  for (unsigned int i = 0; i < numCandidates; i++){
    const Face& triangle = mFaces.at(neighborFaces.at(i));

    // NB Assumes face normals already calculated
    n += triangle.normal;
  }
  n.Normalize();
  return n;
}
/*!
 * \param[in] indx vertex index, points into HalfEdgeMesh::mVerts
*/
Matrix4x4<float> QuadricDecimationMesh::createQuadricForVert(unsigned int indx) const{
  
	float q[4][4] = {{0,0,0,0},
                   {0,0,0,0},
                   {0,0,0,0},
                   {0,0,0,0}};
 
  Matrix4x4<float> Q(q);
  std::vector<unsigned int> faces = FindNeighborFaces(indx);

  for(int i = 0; i < faces.size(); i++){
    Q += createQuadricForFace(faces[i]);
  }
  // The quadric for a vertex is the sum of all the quadrics for the adjacent faces
  // Tip: Matrix4x4 has an operator +=
  return Q;
}
/*! Computes a new vertex, replacing a vertex in the old mesh
  If any of the neighboring faces have subdividability == false
  then we should not move this vertex, else use the rules from loop subdivision
*/
Vector3<float> AdaptiveLoopSubdivisionMesh::VertexRule(unsigned int vertexIndex)
{
  // Get the current vertex
  Vector3<float> vtx = v(vertexIndex).pos;

  // Get face neighborhood
  std::vector<unsigned int> nb = FindNeighborFaces(vertexIndex);

  for(unsigned int i=0; i<nb.size(); i++){
    if(Subdividable(nb.at(i)) == false){
      // don't move position
      return vtx;
    }
  }

  // else return VertexRule for LSMesh
  return LoopSubdivisionMesh::VertexRule(vertexIndex);
}
示例#5
0
/*! Loops over the neighborhood of a vertex and collects all the vertices sorted counter clockwise.
 * \param [in] vertexIndex  the index to vertex, unsigned int
 * \return a vector containing the indices to all the found vertices.
 */
std::vector<unsigned int> SimpleMesh::FindNeighborVertices(unsigned int vertexIndex) const{
  std::vector<unsigned int> neighborFaces = FindNeighborFaces(vertexIndex);
  std::vector<unsigned int> oneRing;
  unsigned int currVert;

  // pick next counter clock wise vert
  if(mFaces.at(neighborFaces.at(0)).v1 == vertexIndex) currVert = mFaces.at(neighborFaces.at(0)).v2;
  if(mFaces.at(neighborFaces.at(0)).v2 == vertexIndex) currVert = mFaces.at(neighborFaces.at(0)).v3;
  if(mFaces.at(neighborFaces.at(0)).v3 == vertexIndex) currVert = mFaces.at(neighborFaces.at(0)).v1;
  oneRing.push_back(currVert);

  // collect one ring vertices
  for(unsigned int i=0; i< neighborFaces.size() - 1; i++){
    if(mFaces.at(neighborFaces.at(i)).v1 == currVert)
      currVert = mFaces.at(neighborFaces.at(i)).v2;
    else if(mFaces.at(neighborFaces.at(i)).v2 == currVert)
      currVert = mFaces.at(neighborFaces.at(i)).v3;
    else if(mFaces.at(neighborFaces.at(i)).v3 == currVert)
      currVert = mFaces.at(neighborFaces.at(i)).v1;
    oneRing.push_back(currVert);
  }
  return oneRing;
}
示例#6
0
/*! Proceeds to check if the mesh is valid. All indices are inspected and
 * checked to see that they are initialized. The method checks: mEdges, mFaces and mVerts.
 * Also checks to see if all verts have a neighborhood using the findNeighbourFaces method.
 */
void HalfEdgeMesh::Validate()
{
  std::vector<HalfEdge>::iterator iterEdge = mEdges.begin();
  std::vector<HalfEdge>::iterator iterEdgeEnd = mEdges.end();
  while (iterEdge != iterEdgeEnd) {
    if ((*iterEdge).face == UNINITIALIZED ||
        (*iterEdge).next == UNINITIALIZED ||
        (*iterEdge).pair == UNINITIALIZED ||
        (*iterEdge).prev == UNINITIALIZED ||
        (*iterEdge).vert == UNINITIALIZED)
        std::cerr << "HalfEdge " << iterEdge - mEdges.begin() << " not properly initialized" << std::endl;

    iterEdge++;
  }
  std::cerr << "Done with edge check (checked " << GetNumEdges() << " edges)" << std::endl;

  std::vector<Face>::iterator iterTri = mFaces.begin();
  std::vector<Face>::iterator iterTriEnd = mFaces.end();
  while (iterTri != iterTriEnd) {
    if ((*iterTri).edge == UNINITIALIZED)
        std::cerr << "Tri " << iterTri - mFaces.begin() << " not properly initialized" << std::endl;

    iterTri++;
  }
  std::cerr << "Done with face check (checked " << GetNumFaces() << " faces)" << std::endl;

  std::vector<Vertex>::iterator iterVertex = mVerts.begin();
  std::vector<Vertex>::iterator iterVertexEnd = mVerts.end();
  while (iterVertex != iterVertexEnd) {
    if ((*iterVertex).edge == UNINITIALIZED)
        std::cerr << "Vertex " << iterVertex - mVerts.begin() << " not properly initialized" << std::endl;

    iterVertex++;
  }
  std::cerr << "Done with vertex check (checked " << GetNumVerts() << " vertices)" << std::endl;

  std::cerr << "Looping through triangle neighborhood of each vertex... ";
  iterVertex = mVerts.begin();
  iterVertexEnd = mVerts.end();
  int emptyCount = 0;
  std::vector<unsigned int> problemVerts;
  while (iterVertex != iterVertexEnd) {
    std::vector<unsigned int> foundFaces = FindNeighborFaces(iterVertex - mVerts.begin());
    std::vector<unsigned int> foundVerts = FindNeighborVertices(iterVertex - mVerts.begin());
    if (foundFaces.empty() || foundVerts.empty())
      emptyCount++;
    std::set<unsigned int> uniqueFaces(foundFaces.begin(), foundFaces.end());
    std::set<unsigned int> uniqueVerts(foundVerts.begin(), foundVerts.end());
        if ( foundFaces.size() != uniqueFaces.size() ||
         foundVerts.size() != uniqueVerts.size() )
      problemVerts.push_back(iterVertex - mVerts.begin());
    iterVertex++;
  }
  std::cerr << std::endl << "Done: " << emptyCount << " isolated vertices found" << std::endl;
  if(problemVerts.size()){
    std::cerr << std::endl << "Found " << problemVerts.size() << " duplicate faces in vertices: ";
    std::copy(problemVerts.begin(), problemVerts.end(), std::ostream_iterator<unsigned int>(std::cerr, ", "));
    std::cerr << "\n";
  }
  std::cerr << std::endl << "The mesh has genus " << Genus() << ", and consists of " << Shells() << " shells.\n";
}