ViewEdge *ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) { // Start a new sharp chain edges ViewEdge *newVEdge = new ViewEdge; newVEdge->setId(_currentViewId); ++_currentViewId; unsigned size = 0; _pCurrentVShape->AddEdge(newVEdge); // Find first edge: OWXEdge firstWEdge = iWEdge; /* OWXEdge previousWEdge = firstWEdge; */ /* UNUSED */ OWXEdge currentWEdge = firstWEdge; list<OWXEdge> edgesChain; #if 0 /* TK 02-Sep-2012 Experimental fix for incorrect view edge visibility. */ // bidirectional chaining // first direction: while (!stopSharpViewEdge(currentWEdge.e)) { edgesChain.push_back(currentWEdge); ++size; currentWEdge.e->userdata = (void *)1; // processed // Find the next edge! currentWEdge = FindNextWEdge(currentWEdge); } OWXEdge endWEdge = edgesChain.back(); // second direction currentWEdge = FindPreviousWEdge(firstWEdge); while (!stopSharpViewEdge(currentWEdge.e)) { edgesChain.push_front(currentWEdge); ++size; currentWEdge.e->userdata = (void *)1; // processed // Find the previous edge! currentWEdge = FindPreviousWEdge(currentWEdge); } #else edgesChain.push_back(currentWEdge); ++size; currentWEdge.e->userdata = (void *)1; // processed OWXEdge endWEdge = edgesChain.back(); #endif firstWEdge = edgesChain.front(); // build FEdges FEdge *feprevious = NULL; FEdge *fefirst = NULL; FEdge *fe = NULL; for (list<OWXEdge>::iterator we = edgesChain.begin(), weend = edgesChain.end(); we != weend; ++we) { fe = BuildSharpFEdge(feprevious, (*we)); fe->setViewEdge(newVEdge); if (!fefirst) fefirst = fe; feprevious = fe; } // Store the chain starting edge: _pCurrentSShape->AddChain(fefirst); newVEdge->setNature(iWEdge.e->nature()); newVEdge->setFEdgeA(fefirst); newVEdge->setFEdgeB(fe); // is it a closed loop ? if ((firstWEdge == endWEdge) && (size != 1)) { fefirst->setPreviousEdge(fe); fe->setNextEdge(fefirst); newVEdge->setA(0); newVEdge->setB(0); } else { ViewVertex *vva = MakeViewVertex(fefirst->vertexA()); ViewVertex *vvb = MakeViewVertex(fe->vertexB()); ((NonTVertex *)vva)->AddOutgoingViewEdge(newVEdge); ((NonTVertex *)vvb)->AddIncomingViewEdge(newVEdge); newVEdge->setA(vva); newVEdge->setB(vvb); } return newVEdge; }
ViewVertex *ViewMap::InsertViewVertex(SVertex *iVertex, vector<ViewEdge*>& newViewEdges) { NonTVertex *vva = dynamic_cast<NonTVertex*>(iVertex->viewvertex()); if (vva) return vva; // because it is not already a ViewVertex, this SVertex must have only 2 FEdges. The incoming one still belongs // to ioEdge, the outgoing one now belongs to newVEdge const vector<FEdge *>& fedges = iVertex->fedges(); if (fedges.size() != 2) { cerr << "ViewMap warning: Can't split the ViewEdge" << endl; return NULL; } FEdge *fend(NULL), *fbegin(NULL); for (vector<FEdge *>::const_iterator fe = fedges.begin(), feend = fedges.end(); fe != feend; ++fe) { if ((*fe)->vertexB() == iVertex) { fend = (*fe); } if ((*fe)->vertexA() == iVertex) { fbegin = (*fe); } if ((fbegin != NULL) && (fend != NULL)) break; } ViewEdge *ioEdge = fbegin->viewedge(); ViewShape *vshape = ioEdge->viewShape(); vva = new NonTVertex(iVertex); // if the ViewEdge is a closed loop, we don't create a new VEdge if (ioEdge->A() == 0) { // closed loop ioEdge->setA(vva); ioEdge->setB(vva); // update sshape vshape->sshape()->RemoveEdgeFromChain(ioEdge->fedgeA()); vshape->sshape()->RemoveEdgeFromChain(ioEdge->fedgeB()); ioEdge->setFEdgeA(fbegin); ioEdge->setFEdgeB(fend); // Update FEdges fend->setNextEdge(NULL); fbegin->setPreviousEdge(NULL); // update new View Vertex: vva->AddOutgoingViewEdge(ioEdge); vva->AddIncomingViewEdge(ioEdge); vshape->sshape()->AddChain(ioEdge->fedgeA()); vshape->sshape()->AddChain(ioEdge->fedgeB()); } else { // Create new ViewEdge ViewEdge *newVEdge = new ViewEdge(vva, ioEdge->B(), fbegin, ioEdge->fedgeB(), vshape); newVEdge->setId(Id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond() + 1)); newVEdge->setNature(ioEdge->getNature()); //newVEdge->UpdateFEdges(); // done in the ViewEdge constructor // Update old ViewEdge ioEdge->setB(vva); ioEdge->setFEdgeB(fend); // Update FEdges fend->setNextEdge(NULL); fbegin->setPreviousEdge(NULL); // update new View Vertex: vva->AddOutgoingViewEdge(newVEdge); vva->AddIncomingViewEdge(ioEdge); NonTVertex *vvb = dynamic_cast<NonTVertex*>(newVEdge->B()); if (vvb) vvb->Replace(ioEdge, newVEdge); // update ViewShape //vshape->AddEdge(newVEdge); // update SShape vshape->sshape()->AddChain(fbegin); // update ViewMap //_VEdges.push_back(newVEdge); newViewEdges.push_back(newVEdge); } // update ViewShape vshape->AddVertex(vva); // update ViewMap _VVertices.push_back(vva); return vva; }
ViewEdge *ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer) { // Find first edge: OWXFaceLayer first = iFaceLayer; OWXFaceLayer currentFace = first; // bidirectional chaining. // first direction list<OWXFaceLayer> facesChain; unsigned size = 0; while (!stopSmoothViewEdge(currentFace.fl)) { facesChain.push_back(currentFace); ++size; currentFace.fl->userdata = (void *)1; // processed // Find the next edge! currentFace = FindNextFaceLayer(currentFace); } OWXFaceLayer end = facesChain.back(); // second direction currentFace = FindPreviousFaceLayer(first); while (!stopSmoothViewEdge(currentFace.fl)) { facesChain.push_front(currentFace); ++size; currentFace.fl->userdata = (void *)1; // processed // Find the previous edge! currentFace = FindPreviousFaceLayer(currentFace); } first = facesChain.front(); if (iFaceLayer.fl->nature() & Nature::RIDGE) { if (size < 4) { return 0; } } // Start a new chain edges ViewEdge *newVEdge = new ViewEdge; newVEdge->setId(_currentViewId); ++_currentViewId; _pCurrentVShape->AddEdge(newVEdge); // build FEdges FEdge *feprevious = NULL; FEdge *fefirst = NULL; FEdge *fe = NULL; for (list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend = facesChain.end(); fl != flend; ++fl) { fe = BuildSmoothFEdge(feprevious, (*fl)); if (feprevious && fe == feprevious) continue; fe->setViewEdge(newVEdge); if (!fefirst) fefirst = fe; feprevious = fe; } // Store the chain starting edge: _pCurrentSShape->AddChain(fefirst); newVEdge->setNature(iFaceLayer.fl->nature()); newVEdge->setFEdgeA(fefirst); newVEdge->setFEdgeB(fe); // is it a closed loop ? if ((first == end) && (size != 1)) { fefirst->setPreviousEdge(fe); fe->setNextEdge(fefirst); newVEdge->setA(0); newVEdge->setB(0); } else { ViewVertex *vva = MakeViewVertex(fefirst->vertexA()); ViewVertex *vvb = MakeViewVertex(fe->vertexB()); ((NonTVertex *)vva)->AddOutgoingViewEdge(newVEdge); ((NonTVertex *)vvb)->AddIncomingViewEdge(newVEdge); newVEdge->setA(vva); newVEdge->setB(vvb); } return newVEdge; }