TVertex *ViewMap::CreateTVertex(const Vec3r& iA3D, const Vec3r& iA2D, FEdge *iFEdgeA, const Vec3r& iB3D, const Vec3r& iB2D, FEdge *iFEdgeB, const Id& id) { ViewShape *vshapeA = iFEdgeA->viewedge()->viewShape(); SShape *shapeA = iFEdgeA->shape(); ViewShape *vshapeB = iFEdgeB->viewedge()->viewShape(); SShape *shapeB = iFEdgeB->shape(); SVertex *Ia = shapeA->CreateSVertex(iA3D, iA2D, iFEdgeA->vertexA()->getId()); SVertex *Ib = shapeB->CreateSVertex(iB3D, iB2D, iFEdgeB->vertexA()->getId()); // depending on which of these 2 svertices is the nearest from the viewpoint, we're going to build the TVertex // by giving them in an order or another (the first one must be the nearest) real dista = Ia->point2D()[2]; real distb = Ib->point2D()[2]; TVertex *tvertex; if (dista < distb) tvertex = new TVertex(Ia, Ib); else tvertex = new TVertex(Ib, Ia); tvertex->setId(id); // add these vertices to the view map AddViewVertex(tvertex); AddSVertex(Ia); AddSVertex(Ib); // and this T Vertex to the view shapes: vshapeA->AddVertex(tvertex); vshapeB->AddVertex(tvertex); return tvertex; }
FEdge* SVertex::getFEdge(Interface0D& inter) { FEdge * result = 0; SVertex* iVertexB = dynamic_cast<SVertex*>(&inter); if (!iVertexB) return result; vector<FEdge*>::const_iterator fe=_FEdges.begin(), feend=_FEdges.end(); for(; fe!=feend; ++fe) { if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB)) || (((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB))) result = (*fe); } if((result == 0) && (getNature() & Nature::T_VERTEX)) { SVertex *brother; ViewVertex *vvertex = viewvertex(); TVertex * tvertex = dynamic_cast<TVertex*>(vvertex); if(tvertex) { brother = tvertex->frontSVertex(); if(this == brother) brother = tvertex->backSVertex(); const vector<FEdge*>& fedges = brother->fedges(); for(fe=fedges.begin(),feend=fedges.end(); fe!=feend; ++fe) { if( (((*fe)->vertexA() == brother) && ((*fe)->vertexB() == iVertexB)) || (((*fe)->vertexB() == brother) && ((*fe)->vertexA() == iVertexB))) result = (*fe); } } } if((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX)) { SVertex *brother; ViewVertex *vvertex = iVertexB->viewvertex(); TVertex * tvertex = dynamic_cast<TVertex*>(vvertex); if(tvertex) { brother = tvertex->frontSVertex(); if(iVertexB == brother) brother = tvertex->backSVertex(); for(fe=_FEdges.begin(),feend=_FEdges.end(); fe!=feend; ++fe) { if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == brother)) || (((*fe)->vertexB() == this) && ((*fe)->vertexA() == brother))) result = (*fe); } } } return result; }
static PyObject *CurvePoint_fedge_get(BPy_CurvePoint *self, void *UNUSED(closure)) { SVertex *A = self->cp->A(); Interface0D *B = (Interface0D *)self->cp->B(); // B can be NULL under certain circumstances if (B) return Any_BPy_Interface1D_from_Interface1D(*(A->getFEdge(*B))); Py_RETURN_NONE; }
Vec2f ImageSpaceNormalF0D::operator()(Interface0DIterator& iter) { SVertex * sv = (*iter).castToSVertex(); return sv->ImageSpaceNormal(); }
real IsophoteDistanceF0D::operator()(Interface0DIterator& iter) { SVertex * sv = (*iter).castToSVertex(); return sv->GetIsophoteDistance(_isovalue, _maxDistance); }
/* 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); } }