// ****************************************************************** // Berechnung des Schattenvolumens tbResult tbShadowVolume::ComputeVolume(const tbMatrix& mInvModelMatrix, const D3DLIGHT9& Light, const float fLength, // = 1000.0f const BOOL bNormalize) // = FALSE { tbVector3 vLight; tbVector3 vDir; tbEdge* pEdge; tbVector3 vPointA; tbVector3 vPointB; tbVector3 vPointC; tbVector3 vPointD; if(Light.Type == D3DLIGHT_DIRECTIONAL) { // Ein Richtungslicht kann gesondert behandelt werden. // Erst transformieren wir die Richtung des Lichts mit der // inversen Transformationsmatrix des Modells. vDir = tbVector3TransformNormal(tbVector3NormalizeEx(Light.Direction), mInvModelMatrix); // Alle Dreiecke durchgehen und das Punktprodukt aus dem // Dreiecksnormalvektor und vDir berechnen. Nur wenn ein Wert größer // gleich null herauskommt, ist das Dreieck aus der Sicht des // Lichts sichtbar (Culling!). m_dwNumEdges = 0; for(DWORD t = 0; t < m_pModel->m_dwNumIndices / 3; t++) { // Punktprodukt berechnen und daraus die Sichtbarkeit bestimmen if(tbVector3Dot(m_pModel->m_pTrianglePlanes[t * 4].n, vDir) >= 0.0f) { // Die drei Seiten dieses Dreiecks hinzufügen AddEdge(m_pModel->m_pdwIndices[t * 3], m_pModel->m_pdwIndices[t * 3 + 1]); AddEdge(m_pModel->m_pdwIndices[t * 3 + 1], m_pModel->m_pdwIndices[t * 3 + 2]); AddEdge(m_pModel->m_pdwIndices[t * 3 + 2], m_pModel->m_pdwIndices[t * 3]); } } // Die verbliebenen Seiten durchgehen vDir *= fLength; m_dwNumVertices = 0; for(DWORD dwEdge = 0; dwEdge < m_dwNumEdges; dwEdge++) { pEdge = &m_pEdges[dwEdge]; // Jetzt fügen wir 6 Vertizes zur Vertexliste hinzu, // um die Seite zu verlängern. vPointA = m_pModel->m_pvVectors[pEdge->dwPointA]; vPointB = m_pModel->m_pvVectors[pEdge->dwPointB]; vPointC = vPointB + vDir; vPointD = vPointA + vDir; m_pvVertices[m_dwNumVertices++] = vPointA; m_pvVertices[m_dwNumVertices++] = vPointD; m_pvVertices[m_dwNumVertices++] = vPointC; m_pvVertices[m_dwNumVertices++] = vPointA; m_pvVertices[m_dwNumVertices++] = vPointC; m_pvVertices[m_dwNumVertices++] = vPointB; } } else { // Bei den anderen Lichttypen hat das Licht eine Position. // Das heißt, dass der Richtungsvektor vom Licht zu den Dreiecken // bei jedem Dreieck unterschiedlich ist. // Die Lichtposition in das Modellkoordinatensystem umrechnen vLight = tbVector3TransformCoords(Light.Position, mInvModelMatrix); // Alle Dreiecke durchgehen. Wir verfahren fast wie oben, nur dass // vDir bei jedem Dreieck neu berechnet wird. m_dwNumEdges = 0; for(DWORD t = 0; t < m_pModel->m_dwNumIndices / 3; t++) { // Richtungsvektor vom Licht zum Mittelpunkt des Dreiecks berechnen vDir = tbVector3NormalizeEx(m_pvTriangleCenters[t] - vLight); // Punktprodukt berechnen und daraus die Sichtbarkeit bestimmen if(tbVector3Dot(m_pModel->m_pTrianglePlanes[t * 4].n, vDir) >= 0.0f) { // Die drei Seiten dieses Dreiecks hinzufügen AddEdge(m_pModel->m_pdwIndices[t * 3], m_pModel->m_pdwIndices[t * 3 + 1]); AddEdge(m_pModel->m_pdwIndices[t * 3 + 1], m_pModel->m_pdwIndices[t * 3 + 2]); AddEdge(m_pModel->m_pdwIndices[t * 3 + 2], m_pModel->m_pdwIndices[t * 3]); } } // Die verbliebenen Seiten durchgehen m_dwNumVertices = 0; if(bNormalize) { for(DWORD dwEdge = 0; dwEdge < m_dwNumEdges; dwEdge++) { pEdge = &m_pEdges[dwEdge]; // Jetzt fügen wir 6 Vertizes zur Vertexliste hinzu, // um diese Seite zu verlängern. vPointA = m_pModel->m_pvVectors[pEdge->dwPointA]; vPointB = m_pModel->m_pvVectors[pEdge->dwPointB]; vPointC = vPointB + tbVector3NormalizeEx(vPointB - vLight) * fLength; vPointD = vPointA + tbVector3NormalizeEx(vPointA - vLight) * fLength; m_pvVertices[m_dwNumVertices++] = vPointA; m_pvVertices[m_dwNumVertices++] = vPointD; m_pvVertices[m_dwNumVertices++] = vPointC; m_pvVertices[m_dwNumVertices++] = vPointA; m_pvVertices[m_dwNumVertices++] = vPointC; m_pvVertices[m_dwNumVertices++] = vPointB; } } else { for(DWORD dwEdge = 0; dwEdge < m_dwNumEdges; dwEdge++) { pEdge = &m_pEdges[dwEdge]; // Jetzt fügen wir 6 Vertizes zur Vertexliste hinzu, // um diese Seite zu verlängern. vPointA = m_pModel->m_pvVectors[pEdge->dwPointA]; vPointB = m_pModel->m_pvVectors[pEdge->dwPointB]; vPointC = vPointB + (vPointB - vLight) * fLength; vPointD = vPointA + (vPointA - vLight) * fLength; m_pvVertices[m_dwNumVertices++] = vPointA; m_pvVertices[m_dwNumVertices++] = vPointD; m_pvVertices[m_dwNumVertices++] = vPointC; m_pvVertices[m_dwNumVertices++] = vPointA; m_pvVertices[m_dwNumVertices++] = vPointC; m_pvVertices[m_dwNumVertices++] = vPointB; } } } return TB_OK; }
//--------------------------------------------------------------- void Tracker::AddTrackerConeVerts(ovrSession Session, Model* m, bool isItEdges) { //Get attributes of camera cone std::vector<ovrTrackerDesc> TrackerDescArray; unsigned int trackerCount = std::max<unsigned int>(1, ovr_GetTrackerCount(Session)); // Make sure there's always at least one. for (unsigned int i = 0; i < trackerCount; ++i) TrackerDescArray.push_back(ovr_GetTrackerDesc(Session, i)); // v4-------v5 float hFOV = TrackerDescArray[0].FrustumHFovInRadians; // | \ / | float vFOV = TrackerDescArray[0].FrustumVFovInRadians; // | v0-v1 | float nearZ = TrackerDescArray[0].FrustumNearZInMeters; // | | C | | float farZ = TrackerDescArray[0].FrustumFarZInMeters; // | v2-v3 | // | / \ | // v6-------v7 // MA: Having the lines/pyramid start closer to camera looks better. nearZ = 0.08f; Vector3f baseVec3(tan(0.5f * hFOV), tan(0.5f * vFOV), 1.0f); v[0] = v[4] = Vector3f(baseVec3.x, -baseVec3.y, 1.0f); v[1] = v[5] = Vector3f(-baseVec3.x, -baseVec3.y, 1.0f); v[2] = v[6] = Vector3f(baseVec3.x, baseVec3.y, 1.0f); v[3] = v[7] = Vector3f(-baseVec3.x, baseVec3.y, 1.0f); v[8] = Vector3f(0, 0, 0.5f*lengthOfTrackerHead); //front of tracker location // Project to near and far planes for (int i = 0; i < 8; i++) { float depth = (i < 4 ? nearZ : farZ); v[i].x *= depth; v[i].y *= depth; v[i].z *= depth; } Color c = Color(255, 255, 255, 255); if (isItEdges) //Wire parts { #define AddEdge(i0,i1) m->AddQuad( \ Vertex(v[i0],c,0,0),Vertex(v[i1],c,0,0), \ Vertex(v[i1], c, 0, 0), Vertex(v[i1], c, 0, 0)); if (drawWalls) { // Add wireframe fronty and back outlines if we have walls AddEdge(0, 1); AddEdge(1, 3); AddEdge(3, 2); AddEdge(2, 0); AddEdge(4, 5); AddEdge(5, 7); AddEdge(7, 6); AddEdge(6, 4); } AddEdge(4, 0); AddEdge(5, 1); AddEdge(7, 3); AddEdge(6, 2); if (extendLinesToTracker) { AddEdge(8, 0); AddEdge(8, 1); AddEdge(8, 2); AddEdge(8, 3); } } else //Solid planes { float gridDensity = 6.0f; #define AddPlane(i0,i1,i2,i3,U,V,dense) m->AddQuad( \ Vertex(v[i0], c, dense*v[i0].U, dense*v[i0].V), \ Vertex(v[i1], c, dense*v[i1].U, dense*v[i1].V), \ Vertex(v[i2], c, dense*v[i2].U, dense*v[i2].V), \ Vertex(v[i3], c, dense*v[i3].U, dense*v[i3].V)) AddPlane(4, 0, 6, 2, z, y, gridDensity); // Left AddPlane(1, 5, 3, 7, z, y, gridDensity); // Right AddPlane(4, 5, 0, 1, x, z, gridDensity); // Top AddPlane(2, 3, 6, 7, x, z, gridDensity); // Bot AddPlane(5, 4, 7, 6, x, y, gridDensity); // Back if (frontOfGridAsWell) { AddPlane(0, 1, 2, 3, x, y, gridDensity); } // Front } }
void AddEdge2(int a,int b) { AddEdge(a,b); AddEdge(b,a); }
WShape::WShape(WShape& iBrother) { _Id = iBrother.GetId(); _Name = iBrother._Name; _FrsMaterials = iBrother._FrsMaterials; #if 0 _meanEdgeSize = iBrother._meanEdgeSize; iBrother.bbox(_min, _max); #endif vector<WVertex *>& vertexList = iBrother.getVertexList(); vector<WVertex *>::iterator v = vertexList.begin(), vend = vertexList.end(); for (; v != vend; ++v) { //WVertex *newVertex = new WVertex(*(*v)); WVertex *newVertex = (*v)->duplicate(); newVertex->setShape(this); AddVertex(newVertex); } vector<WEdge *>& edgeList = iBrother.getEdgeList(); vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end(); for (; e != eend; ++e) { //WEdge *newEdge = new WEdge(*(*e)); WEdge *newEdge = (*e)->duplicate(); AddEdge(newEdge); } vector<WFace *>& faceList = iBrother.GetFaceList(); vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end(); for (; f != fend; ++f) { //WFace *newFace = new WFace(*(*f)); WFace *newFace = (*f)->duplicate(); AddFace(newFace); } // update all pointed addresses thanks to the newly created objects: vend = _VertexList.end(); for (v = _VertexList.begin(); v != vend; ++v) { const vector<WEdge *>& vedgeList = (*v)->GetEdges(); vector<WEdge *> newvedgelist; unsigned int i; for (i = 0; i < vedgeList.size(); i++) { WEdge *current = vedgeList[i]; edgedata *currentvedata = (edgedata *)current->userdata; newvedgelist.push_back(currentvedata->_copy); } (*v)->setEdges(newvedgelist); } eend = _EdgeList.end(); for (e = _EdgeList.begin(); e != eend; ++e) { // update aOedge: WOEdge *aoEdge = (*e)->GetaOEdge(); aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy); aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy); if (aoEdge->GetaFace()) aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy); aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy); aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy); // update bOedge: WOEdge *boEdge = (*e)->GetbOEdge(); if (boEdge) { boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy); boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy); if (boEdge->GetaFace()) boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy); boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy); boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy); } } fend = _FaceList.end(); for (f = _FaceList.begin(); f != fend; ++f) { unsigned int i; const vector<WOEdge *>& oedgeList = (*f)->getEdgeList(); vector<WOEdge *> newoedgelist; unsigned int n = oedgeList.size(); for (i = 0; i < n; i++) { WOEdge *current = oedgeList[i]; oedgedata *currentoedata = (oedgedata *)current->userdata; newoedgelist.push_back(currentoedata->_copy); //oedgeList[i] = currentoedata->_copy; //oedgeList[i] = ((oedgedata *)(oedgeList[i]->userdata))->_copy; } (*f)->setEdgeList(newoedgelist); } // Free all memory (arghh!) // Vertex vend = iBrother.getVertexList().end(); for (v = iBrother.getVertexList().begin(); v != vend; ++v) { delete (vertexdata *)((*v)->userdata); (*v)->userdata = NULL; } // Edges and OEdges: eend = iBrother.getEdgeList().end(); for (e = iBrother.getEdgeList().begin(); e != eend; ++e) { delete (edgedata *)((*e)->userdata); (*e)->userdata = NULL; // OEdge a: delete (oedgedata *)((*e)->GetaOEdge()->userdata); (*e)->GetaOEdge()->userdata = NULL; // OEdge b: WOEdge *oedgeb = (*e)->GetbOEdge(); if (oedgeb) { delete (oedgedata *)(oedgeb->userdata); oedgeb->userdata = NULL; } } // Faces fend = iBrother.GetFaceList().end(); for (f = iBrother.GetFaceList().begin(); f != fend; ++f) { delete (facedata *)((*f)->userdata); (*f)->userdata = NULL; } }
WFace *WShape::MakeFace(vector<WVertex *>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial, WFace *face) { int id = _FaceList.size(); face->setFrsMaterialIndex(iMaterial); // Check whether we have a degenerated face: // LET'S HACK IT FOR THE TRIANGLE CASE: if (3 == iVertexList.size()) { if ((iVertexList[0] == iVertexList[1]) || (iVertexList[0] == iVertexList[2]) || (iVertexList[2] == iVertexList[1])) { cerr << "Warning: degenerated triangle detected, correcting" << endl; return NULL; } } vector<WVertex *>::iterator it; // compute the face normal (v1v2 ^ v1v3) WVertex *v1, *v2, *v3; it = iVertexList.begin(); v1 = *it; it++; v2 = *it; it++; v3 = *it; Vec3f vector1(v2->GetVertex() - v1->GetVertex()); Vec3f vector2(v3->GetVertex() - v1->GetVertex()); Vec3f normal(vector1 ^ vector2); normal.normalize(); face->setNormal(normal); vector<bool>::iterator mit = iFaceEdgeMarksList.begin(); face->setMark(*mit); mit++; // vertex pointers used to build each edge vector<WVertex *>::iterator va, vb; va = iVertexList.begin(); vb = va; for (; va != iVertexList.end(); va = vb) { ++vb; // Adds va to the vertex list: //face->AddVertex(*va); WOEdge *oedge; if (*va == iVertexList.back()) oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge else oedge = face->MakeEdge(*va, *vb); if (!oedge) return NULL; WEdge *edge = oedge->GetOwner(); if (1 == edge->GetNumberOfOEdges()) { // means that we just created a new edge and that we must add it to the shape's edges list edge->setId(_EdgeList.size()); AddEdge(edge); #if 0 // compute the mean edge value: _meanEdgeSize += edge->GetaOEdge()->GetVec().norm(); #endif } edge->setMark(*mit); ++mit; } // Add the face to the shape's faces list: face->setId(id); AddFace(face); return face; }
int main() { ptrGraph G; Indegree inDegree[MAXVEX]; int tmp; G = InitializeGraph(7); AddVertex(1, 0, G); AddVertex(2, 1, G); AddVertex(3, 2, G); AddVertex(4, 3, G); AddVertex(5, 4, G); AddVertex(6, 5, G); AddVertex(7, 6, G); AddEdge(1, 2, G); AddEdge(1, 3, G); AddEdge(1, 4, G); AddEdge(2, 4, G); AddEdge(2, 5, G); AddEdge(3, 6, G); AddEdge(4, 7, G); AddEdge(4, 3, G); AddEdge(4, 6, G); AddEdge(5, 4, G); AddEdge(5, 7, G); AddEdge(7, 6, G); GetIndegree(inDegree, G->numVertexes, G); //tmp = FindNewVertexOfIndegreeZero(inDegree, G->numVertexes); TopSort(inDegree, G->numVertexes, G); }
WOEdge *WFace::MakeEdge(WVertex *v1, WVertex *v2) { // First check whether the same oriented edge already exists or not: vector<WEdge *>& v1Edges = v1->GetEdges(); for (vector<WEdge*>::iterator it1 = v1Edges.begin(), end = v1Edges.end(); it1 != end; it1++) { WEdge *we = (*it1); WOEdge *woea = we->GetaOEdge(); if ((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2)) { // The oriented edge already exists cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl; // Adds the edge to the face AddEdge(woea); (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges() + 1); //sets these vertices as border: v1->setBorder(true); v2->setBorder(true); return woea; } WOEdge *woeb = we->GetbOEdge(); if (woeb && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2)) { // The oriented edge already exists cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl; // Adds the edge to the face AddEdge(woeb); (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges() + 1); //sets these vertices as border: v1->setBorder(true); v2->setBorder(true); return woeb; } } // the oriented edge we're about to build WOEdge *pOEdge = new WOEdge; // The edge containing the oriented edge. WEdge *edge; // checks whether this edge already exists or not // If it exists, it points outward v2 bool exist = false; WOEdge *pInvertEdge = NULL; // The inverted edge if it exists vector<WEdge *>& v2Edges = v2->GetEdges(); vector<WEdge *>::iterator it; for (it = v2Edges.begin(); it != v2Edges.end(); it++) { if ((*it)->GetbVertex() == v1) { // The invert edge already exists exist = true; pInvertEdge = (*it)->GetaOEdge(); break; } } //DEBUG: if (true == exist) { // The invert edge already exists // Retrieves the corresponding edge edge = pInvertEdge->GetOwner(); // Sets the a Face (retrieved from pInvertEdge pOEdge->setaFace(pInvertEdge->GetbFace()); // Updates the invert edge: pInvertEdge->setaFace(this); } else { // The invert edge does not exist yet // we must create a new edge //edge = new WEdge; edge = instanciateEdge(); // updates the a,b vertex edges list: v1->AddEdge(edge); v2->AddEdge(edge); } pOEdge->setOwner(edge); // Add the vertices: pOEdge->setaVertex(v1); pOEdge->setbVertex(v2); // Debug: if (v1->GetId() == v2->GetId()) cerr << "Warning: edge " << this << " null with vertex " << v1->GetId() << endl; edge->AddOEdge(pOEdge); //edge->setNumberOfOEdges(edge->GetNumberOfOEdges() + 1); // Add this face (the b face) pOEdge->setbFace(this); // Adds the edge to the face AddEdge(pOEdge); return pOEdge; }
void AddEdge(int u, int v, T weight) { AddEdge(WeightedEdge<T>(u, v, weight)); }
/* Add edges with the same value bool if inserting one edge failed (if already exists) */ bool AddEdges(int vertex_1, int vertex_2, EV value) { return AddEdge(vertex_1, vertex_2, value) && AddEdge(vertex_2, vertex_1, value); }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- int CreateOrigFace( face_t *f ) { int i, j; dface_t *of; side_t *side; int vIndices[128]; int eIndex[2]; winding_t *pWinding; // not a real face! if( !f->w ) return -1; // get the original face -- the "side" side = f->originalface; // get the original face winding if( !side->winding ) { return -1; } // // get the next original face // if( numorigfaces >= MAX_MAP_FACES ) Error( "Too many faces in map, max = %d", MAX_MAP_FACES ); of = &dorigfaces[numorigfaces]; numorigfaces++; // set original face to -1 -- it is an origianl face! of->origFace = -1; // // add side to plane list // side->next = pOrigFaceSideList[f->planenum]; pOrigFaceSideList[f->planenum] = side; side->origIndex = numorigfaces - 1; pWinding = CopyWinding( side->winding ); // // plane info // of->planenum = side->planenum; if ( side->contents & CONTENTS_DETAIL ) of->onNode = 0; else of->onNode = 1; of->side = side->planenum & 1; // // edge info // of->firstedge = numsurfedges; of->numedges = side->winding->numpoints; // // material info // of->texinfo = side->texinfo; of->dispinfo = f->dispinfo; // // save the vertices // for( i = 0; i < pWinding->numpoints; i++ ) { // // compare vertices // vIndices[i] = GetVertexnum( pWinding->p[i] ); } // // save off points -- as edges // for( i = 0; i < pWinding->numpoints; i++ ) { // // look for matching edges first // eIndex[0] = vIndices[i]; eIndex[1] = vIndices[(i+1)%pWinding->numpoints]; for( j = firstmodeledge; j < numedges; j++ ) { if( ( eIndex[0] == dedges[j].v[1] ) && ( eIndex[1] == dedges[j].v[0] ) && ( edgefaces[j][0]->contents == f->contents ) ) { // check for multiple backward edges!! -- shouldn't have if( edgefaces[j][1] ) continue; // set back edge edgefaces[j][1] = f; // // get next surface edge // if( numsurfedges >= MAX_MAP_SURFEDGES ) Error( "Too much brush geometry in bsp, numsurfedges == MAX_MAP_SURFEDGES" ); dsurfedges[numsurfedges] = -j; numsurfedges++; break; } } if( j == numedges ) { // // get next edge // AddEdge( eIndex[0], eIndex[1], f ); // // get next surface edge // if( numsurfedges >= MAX_MAP_SURFEDGES ) Error( "Too much brush geometry in bsp, numsurfedges == MAX_MAP_SURFEDGES" ); dsurfedges[numsurfedges] = ( numedges - 1 ); numsurfedges++; } } // return the index return ( numorigfaces - 1 ); }
/* 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); } }