Mesh::Mesh(const HalfedgeMesh& mesh, BSDF* bsdf) { unordered_map<const Vertex *, int> vertexLabels; vector<const Vertex *> verts; size_t vertexI = 0; for (VertexCIter it = mesh.verticesBegin(); it != mesh.verticesEnd(); it++) { const Vertex *v = &*it; verts.push_back(v); vertexLabels[v] = vertexI; vertexI++; } positions = new Vector3D[vertexI]; normals = new Vector3D[vertexI]; for (int i = 0; i < vertexI; i++) { positions[i] = verts[i]->position; normals[i] = verts[i]->normal; } for (FaceCIter f = mesh.facesBegin(); f != mesh.facesEnd(); f++) { HalfedgeCIter h = f->halfedge(); indices.push_back(vertexLabels[&*h->vertex()]); indices.push_back(vertexLabels[&*h->next()->vertex()]); indices.push_back(vertexLabels[&*h->next()->next()->vertex()]); } this->bsdf = bsdf; }
Vector3D Face::normal(void) const { Vector3D N(0., 0., 0.); HalfedgeCIter h = halfedge(); do { Vector3D pi = h->vertex()->position; Vector3D pj = h->next()->vertex()->position; N += cross(pi, pj); h = h->next(); } while (h != halfedge()); return N.unit(); }
Vector3D Vertex::normal( void ) const // TODO Returns an approximate unit normal at this vertex, computed by // TODO taking the area-weighted average of the normals of neighboring // TODO triangles, then normalizing. { // TODO Compute and return the area-weighted unit normal. //no boundary polygon HalfedgeCIter h = this->halfedge(); Vector3D nrm(0, 0, 0); double totalarea = 0; do { h = h->twin(); FaceCIter f = h->face(); if(!f->isBoundary()) { VertexCIter v1 = h->vertex(); VertexCIter v2 = h->next()->twin()->vertex(); Vector3D out = cross(v1->position - position, v2->position - position); nrm += out; totalarea += out.norm(); } h = h->next(); } while(h != this->halfedge()); nrm /= totalarea; nrm.normalize(); return nrm; }