/* splits an edge into 2 edges. The new vertex and edge are added * to the sshape list of vertices and edges * a new chain is also created. * returns the new edge. * ioEdge * The edge that gets splitted * newpoint * x,y,z coordinates of the new point. */ FEdge* SShape::SplitEdgeIn2(FEdge* ioEdge, SVertex * ioNewVertex) { SVertex *A = ioEdge->vertexA(); SVertex *B = ioEdge->vertexB(); // We split edge AB into AA' and A'B. A' and A'B are created. // AB becomes (address speaking) AA'. B is updated. //-------------------------------------------------- // a new edge, A'B is created. FEdge *newEdge; if (ioEdge->getNature() & Nature::ALL_INTERSECTION) { newEdge = new FEdgeIntersection(ioNewVertex, B); FEdgeIntersection * se = dynamic_cast<FEdgeIntersection*>(newEdge); FEdgeIntersection * fes = dynamic_cast<FEdgeIntersection*>(ioEdge); se->SetMaterialIndex(fes->materialIndex()); se->SetFaces(fes->getFace1(), fes->getFace2()); #ifdef DEBUG_INTERSECTION void debugFES(FEdgeIntersection * newEdge); debugFES(se); debugFES(fes); #endif }else if(ioEdge->isSmooth()){ newEdge = new FEdgeSmooth(ioNewVertex, B); FEdgeSmooth * se = dynamic_cast<FEdgeSmooth*>(newEdge); FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(ioEdge); se->SetMaterialIndex(fes->materialIndex()); se->SetFace(fes->face()); }else{ newEdge = new FEdgeSharp(ioNewVertex, B); FEdgeSharp * se = dynamic_cast<FEdgeSharp*>(newEdge); FEdgeSharp * fes = dynamic_cast<FEdgeSharp*>(ioEdge); se->SetaMaterialIndex(fes->aMaterialIndex()); se->SetbMaterialIndex(fes->bMaterialIndex()); se->SetEdge(fes->edge()); } newEdge->SetNature(ioEdge->getNature()); if(ioEdge->nextEdge() != 0) ioEdge->nextEdge()->SetPreviousEdge(newEdge); // update edge A'B for the next pointing edge newEdge->SetNextEdge(ioEdge->nextEdge()); // update edge A'B for the previous pointing edge newEdge->SetPreviousEdge(0); // because it is now a ViewVertex Id id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond()+1); newEdge->SetId(ioEdge->getId()); ioEdge->SetId(id); // update edge AA' for the next pointing edge ioEdge->SetNextEdge(0); // because it is now a TVertex // update vertex pointing edges list: // -- vertex B -- B->Replace(ioEdge, newEdge); // -- vertex A' -- ioNewVertex->AddFEdge(ioEdge); ioNewVertex->AddFEdge(newEdge); // to build a new chain: AddChain(newEdge); AddEdge(newEdge); // FIXME ?? // The edge AB becomes edge AA'. ioEdge->SetVertexB(ioNewVertex); // added by Aaron (looks redundant now, can probably be deleted) newEdge->SetVertexA(ioNewVertex); newEdge->SetVertexB(B); // if(ioEdge->isSmooth()){ // ((FEdgeSmooth*)newEdge)->SetFace(((FEdgeSmooth*)ioEdge)->face()); //} return newEdge; }
/* splits an edge into several edges. * The edge's vertices are passed rather than * the edge itself. This way, all feature edges (SILHOUETTE, * CREASE, BORDER) are splitted in the same time. * The processed edges are flagged as done (using the userdata * flag).One single new vertex is created whereas * several splitted edges might created for the different * kinds of edges. These new elements are added to the lists * maintained by the shape. * new chains are also created. * ioA * The first vertex for the edge that gets splitted * ioB * The second vertex for the edge that gets splitted * iParameters * A vector containing 2D real vectors indicating the parameters * giving the intersections coordinates in 3D and in 2D. * These intersections points must be sorted from B to A. * Each parameter defines the intersection point I as I=A+T*AB. * T<0 and T>1 are then incorrect insofar as they give intersections * points that lie outside the segment. * ioNewEdges * The edges that are newly created (the initial edges are not * included) are added to this list. */ void SShape::SplitEdge(FEdge *fe, const vector<Vec2r>& iParameters, vector<FEdge*>& ioNewEdges) { SVertex *ioA = fe->vertexA(); SVertex *ioB = fe->vertexB(); Vec3r A = ioA->point3D(); Vec3r B = ioB->point3D(); Vec3r a = ioA->point2D(); Vec3r b = ioB->point2D(); SVertex *svA, *svB; Vec3r newpoint3d,newpoint2d; vector<SVertex*> intersections; real t,T; for(vector<Vec2r>::const_iterator p=iParameters.begin(),pend=iParameters.end(); p!=pend; p++) { T=(*p)[0]; t=(*p)[1]; if((t < 0) || (t > 1)) cerr << "Warning: Intersection out of range for edge " << ioA->getId() << " - " << ioB->getId() << endl; // compute the 3D and 2D coordinates for the intersections points: newpoint3d = Vec3r(A + T*(B-A)); newpoint2d = Vec3r(a + t*(b-a)); // create new SVertex: // (we keep B's id) SVertex* newVertex = new SVertex(newpoint3d, ioB->getId()); newVertex->SetPoint2D(newpoint2d); // Add this vertex to the intersections list: intersections.push_back(newVertex); // Add this vertex to this sshape: AddNewVertex(newVertex); } for(vector<SVertex*>::iterator sv=intersections.begin(),svend=intersections.end(); sv!=svend; sv++) { svA = fe->vertexA(); svB = fe->vertexB(); // We split edge AB into AA' and A'B. A' and A'B are created. // AB becomes (address speaking) AA'. B is updated. //-------------------------------------------------- // The edge AB becomes edge AA'. (fe)->SetVertexB((*sv)); // a new edge, A'B is created. FEdge *newEdge; if (fe->getNature() & Nature::ALL_INTERSECTION) { newEdge = new FEdgeIntersection((*sv), svB); FEdgeIntersection * se = dynamic_cast<FEdgeIntersection*>(newEdge); FEdgeIntersection * fes = dynamic_cast<FEdgeIntersection*>(fe); se->SetMaterialIndex(fes->materialIndex()); se->SetFaces(fes->getFace1(), fes->getFace2()); #ifdef DEBUG_INTERSECTION void debugFES(FEdgeIntersection * newEdge); debugFES(se); debugFES(fes); #endif } else if(fe->isSmooth()){ newEdge = new FEdgeSmooth((*sv), svB); FEdgeSmooth * se = dynamic_cast<FEdgeSmooth*>(newEdge); FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe); se->SetMaterialIndex(fes->materialIndex()); }else{ newEdge = new FEdgeSharp((*sv), svB); FEdgeSharp * se = dynamic_cast<FEdgeSharp*>(newEdge); FEdgeSharp * fes = dynamic_cast<FEdgeSharp*>(fe); se->SetaMaterialIndex(fes->aMaterialIndex()); se->SetbMaterialIndex(fes->bMaterialIndex()); se->SetEdge(fes->edge()); } newEdge->SetNature((fe)->getNature()); // to build a new chain: AddChain(newEdge); // add the new edge to the sshape edges list. AddEdge(newEdge); // add new edge to the list of new edges passed as argument: ioNewEdges.push_back(newEdge); // update edge A'B for the next pointing edge newEdge->SetNextEdge((fe)->nextEdge()); fe->nextEdge()->SetPreviousEdge(newEdge); Id id(fe->getId().getFirst(), fe->getId().getSecond()+1); newEdge->SetId(fe->getId()); fe->SetId(id); // update edge AA' for the next pointing edge //ioEdge->SetNextEdge(newEdge); (fe)->SetNextEdge(NULL); // update vertex pointing edges list: // -- vertex B -- svB->Replace((fe), newEdge); // -- vertex A' -- (*sv)->AddFEdge((fe)); (*sv)->AddFEdge(newEdge); } }