const HalfedgeMesh& HalfedgeMesh::operator=(const HalfedgeMesh& mesh) // The assignment operator does a "deep" copy of the halfedge mesh data // structure; in other words, it makes new instances of each mesh element, and // ensures that pointers in the copy point to the newly allocated elements // rather than elements in the original mesh. This behavior is especially // important for making assignments, since the mesh on the right-hand side of an // assignment may be temporary (hence any pointers to elements in this mesh will // become invalid as soon as it is released.) { // Clear any existing elements. halfedges.clear(); vertices.clear(); edges.clear(); faces.clear(); boundaries.clear(); // These maps will be used to identify elements of the old mesh // with elements of the new mesh. (Note that we can use a single // map for both interior and boundary faces, because the map // doesn't care which list of faces these iterators come from.) map<HalfedgeCIter, HalfedgeIter> halfedgeOldToNew; map<VertexCIter, VertexIter> vertexOldToNew; map<EdgeCIter, EdgeIter> edgeOldToNew; map<FaceCIter, FaceIter> faceOldToNew; // Copy geometry from the original mesh and create a map from // pointers in the original mesh to those in the new mesh. for (HalfedgeCIter h = mesh.halfedgesBegin(); h != mesh.halfedgesEnd(); h++) halfedgeOldToNew[h] = halfedges.insert(halfedges.end(), *h); for (VertexCIter v = mesh.verticesBegin(); v != mesh.verticesEnd(); v++) vertexOldToNew[v] = vertices.insert(vertices.end(), *v); for (EdgeCIter e = mesh.edgesBegin(); e != mesh.edgesEnd(); e++) edgeOldToNew[e] = edges.insert(edges.end(), *e); for (FaceCIter f = mesh.facesBegin(); f != mesh.facesEnd(); f++) faceOldToNew[f] = faces.insert(faces.end(), *f); for (FaceCIter b = mesh.boundariesBegin(); b != mesh.boundariesEnd(); b++) faceOldToNew[b] = boundaries.insert(boundaries.end(), *b); // "Search and replace" old pointers with new ones. for (HalfedgeIter he = halfedgesBegin(); he != halfedgesEnd(); he++) { he->next() = halfedgeOldToNew[he->next()]; he->twin() = halfedgeOldToNew[he->twin()]; he->vertex() = vertexOldToNew[he->vertex()]; he->edge() = edgeOldToNew[he->edge()]; he->face() = faceOldToNew[he->face()]; } for (VertexIter v = verticesBegin(); v != verticesEnd(); v++) v->halfedge() = halfedgeOldToNew[v->halfedge()]; for (EdgeIter e = edgesBegin(); e != edgesEnd(); e++) e->halfedge() = halfedgeOldToNew[e->halfedge()]; for (FaceIter f = facesBegin(); f != facesEnd(); f++) f->halfedge() = halfedgeOldToNew[f->halfedge()]; for (FaceIter b = boundariesBegin(); b != boundariesEnd(); b++) b->halfedge() = halfedgeOldToNew[b->halfedge()]; // Return a reference to the new mesh. return *this; }
EdgeIter HalfedgeMesh::flipEdge( EdgeIter e0 ) { // TODO This method should flip the given edge and return an iterator to the flipped edge. //1. collect elements //Halfedges HalfedgeIter h0 = e0->halfedge(); HalfedgeIter h3 = h0->twin(); //Faces FaceIter f0 = h0->face(); FaceIter f1 = h3->face(); //Early Exit #1: Ignore requests to flip boundary edges if(f0->isBoundary() || f1->isBoundary()) return edgesEnd(); HalfedgeIter h1 = h0->next(); HalfedgeIter h2 = h1->next(); HalfedgeIter h4 = h3->next(); HalfedgeIter h5 = h4->next(); //Vertices VertexIter v0 = h0->vertex(); VertexIter v1 = h3->vertex(); VertexIter v2 = h2->vertex(); VertexIter v3 = h5->vertex(); //Early Exit #2: Does the flipped edge already exist? HalfedgeIter h = v2->halfedge(); do { h = h->twin(); if(h->vertex() == v3) return edgesEnd(); h = h->next(); } while(h != v2->halfedge()); //Edges //e0 is given //2. reassign elements //HalfEdges h0->next() = h5; h0->vertex() = v2; h5->next() = h1; h5->face() = f0; h1->next() = h0; h3->next() = h2; h3->vertex() = v3; h2->next() = h4; h2->face() = f1; h4->next() = h3; //Vertices v0->halfedge() = h4; v1->halfedge() = h1; v2->halfedge() = h0; v3->halfedge() = h3; //Faces f0->halfedge() = h0; f1->halfedge() = h3; return e0; }