This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/freestyle/intern/view_map/ViewMap.cpp
Brecht Van Lommel 1840f44666 Fix build error on Windows without precompiled headers
Recent refactoring to use uint relied on indirect includes and precompiled
headers for uint to be defined. Explicitly include BLI_sys_types where this
type is used now.
2022-10-26 19:59:55 +02:00

831 lines
23 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup freestyle
* \brief Classes to define a View Map (ViewVertex, ViewEdge, etc.)
*/
#include <cfloat>
#include "ViewMap.h"
#include "ViewMapAdvancedIterators.h"
#include "ViewMapIterators.h"
#include "../geometry/GeomUtils.h"
#include "BLI_sys_types.h"
namespace Freestyle {
/**********************************/
/* */
/* */
/* ViewMap */
/* */
/* */
/**********************************/
ViewMap *ViewMap::_pInstance = nullptr;
ViewMap::~ViewMap()
{
// The view vertices must be deleted here as some of them are shared between two shapes:
for (vector<ViewVertex *>::iterator vv = _VVertices.begin(), vvend = _VVertices.end();
vv != vvend;
vv++) {
delete (*vv);
}
_VVertices.clear();
for (vector<ViewShape *>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend;
vs++) {
delete (*vs);
}
_VShapes.clear();
_FEdges.clear();
_SVertices.clear();
_VEdges.clear();
}
void ViewMap::Clean()
{
vector<FEdge *> tmpEdges;
for (vector<ViewShape *>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend;
vs++) {
vector<FEdge *> &edges = (*vs)->sshape()->getEdgeList();
for (vector<FEdge *>::iterator it = edges.begin(), itend = edges.end(); it != itend; it++) {
if ((*it)->isTemporary()) {
(*it)->setTemporary(false); // avoid being counted multiple times
tmpEdges.push_back(*it);
}
}
}
for (vector<FEdge *>::iterator it = tmpEdges.begin(), itend = tmpEdges.end(); it != itend;
it++) {
for (vector<ViewShape *>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend;
vs++) {
(*vs)->sshape()->RemoveEdge(*it);
}
(*it)->vertexA()->RemoveFEdge(*it);
(*it)->vertexB()->RemoveFEdge(*it);
delete (*it);
}
}
ViewShape *ViewMap::viewShape(uint id)
{
int index = _shapeIdToIndex[id];
return _VShapes[index];
}
void ViewMap::AddViewShape(ViewShape *iVShape)
{
_shapeIdToIndex[iVShape->getId().getFirst()] = _VShapes.size();
_VShapes.push_back(iVShape);
}
const FEdge *ViewMap::getClosestFEdge(real x, real y) const
{
// find the closest of this candidates:
real minDist = DBL_MAX;
FEdge *winner = nullptr;
for (fedges_container::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend;
fe++) {
Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]);
Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]);
real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B);
if (dist < minDist) {
minDist = dist;
winner = (*fe);
}
}
return winner;
}
const ViewEdge *ViewMap::getClosestViewEdge(real x, real y) const
{
// find the closest of this candidates:
real minDist = DBL_MAX;
FEdge *winner = nullptr;
for (fedges_container::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend;
fe++) {
Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]);
Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]);
real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B);
if (dist < minDist) {
minDist = dist;
winner = (*fe);
}
}
if (!winner) {
return nullptr;
}
return winner->viewedge();
}
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;
}
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 nullptr;
}
FEdge *fend(nullptr), *fbegin(nullptr);
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 != nullptr) && (fend != nullptr)) {
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() == nullptr) {
// 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(nullptr);
fbegin->setPreviousEdge(nullptr);
// 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(nullptr);
fbegin->setPreviousEdge(nullptr);
// 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;
}
#if 0
FEdge *ViewMap::Connect(FEdge *ioEdge, SVertex *ioVertex, vector<ViewEdge *> &oNewVEdges)
{
SShape *sshape = ioEdge->shape();
FEdge *newFEdge = sshape->SplitEdgeIn2(ioEdge, ioVertex);
AddFEdge(newFEdge);
InsertViewVertex(ioVertex, oNewVEdges);
return newFEdge;
}
#endif
/**********************************/
/* */
/* */
/* TVertex */
/* */
/* */
/**********************************/
// is dve1 before dve2 ? (does it have a smaller angle ?)
static bool ViewEdgeComp(ViewVertex::directedViewEdge &dve1, ViewVertex::directedViewEdge &dve2)
{
FEdge *fe1;
if (dve1.second) {
fe1 = dve1.first->fedgeB();
}
else {
fe1 = dve1.first->fedgeA();
}
FEdge *fe2;
if (dve2.second) {
fe2 = dve2.first->fedgeB();
}
else {
fe2 = dve2.first->fedgeA();
}
Vec3r V1 = fe1->orientation2d();
Vec2r v1(V1.x(), V1.y());
v1.normalize();
Vec3r V2 = fe2->orientation2d();
Vec2r v2(V2.x(), V2.y());
v2.normalize();
if (v1.y() > 0) {
if (v2.y() < 0) {
return true;
}
return (v1.x() > v2.x());
}
if (v2.y() > 0) {
return false;
}
return (v1.x() < v2.x());
}
void TVertex::setFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming)
{
if (!iFrontEdgeA) {
cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeA()" << endl;
return;
}
_FrontEdgeA = directedViewEdge(iFrontEdgeA, incoming);
if (!_sortedEdges.empty()) {
edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
for (; (dve != dveend) && ViewEdgeComp(**dve, _FrontEdgeA); ++dve) {
/* pass */
}
_sortedEdges.insert(dve, &_FrontEdgeA);
}
else {
_sortedEdges.push_back(&_FrontEdgeA);
}
}
void TVertex::setFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming)
{
if (!iFrontEdgeB) {
cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeB()" << endl;
return;
}
_FrontEdgeB = directedViewEdge(iFrontEdgeB, incoming);
if (!_sortedEdges.empty()) {
edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
for (; (dve != dveend) && ViewEdgeComp(**dve, _FrontEdgeB); ++dve) {
/* pass */
}
_sortedEdges.insert(dve, &_FrontEdgeB);
}
else {
_sortedEdges.push_back(&_FrontEdgeB);
}
}
void TVertex::setBackEdgeA(ViewEdge *iBackEdgeA, bool incoming)
{
if (!iBackEdgeA) {
cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeA()" << endl;
return;
}
_BackEdgeA = directedViewEdge(iBackEdgeA, incoming);
if (!_sortedEdges.empty()) {
edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
for (; (dve != dveend) && ViewEdgeComp(**dve, _BackEdgeA); ++dve) {
/* pass */
}
_sortedEdges.insert(dve, &_BackEdgeA);
}
else {
_sortedEdges.push_back(&_BackEdgeA);
}
}
void TVertex::setBackEdgeB(ViewEdge *iBackEdgeB, bool incoming)
{
if (!iBackEdgeB) {
cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeB()" << endl;
return;
}
_BackEdgeB = directedViewEdge(iBackEdgeB, incoming);
if (!_sortedEdges.empty()) {
edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end();
for (; (dve != dveend) && ViewEdgeComp(**dve, _BackEdgeB); ++dve) {
/* pass */
}
_sortedEdges.insert(dve, &_BackEdgeB);
}
else {
_sortedEdges.push_back(&_BackEdgeB);
}
}
void TVertex::Replace(ViewEdge *iOld, ViewEdge *iNew)
{
// theoretically, we only replace edges for which this
// view vertex is the B vertex
if ((iOld == _FrontEdgeA.first) && (_FrontEdgeA.first->B() == this)) {
_FrontEdgeA.first = iNew;
return;
}
if ((iOld == _FrontEdgeB.first) && (_FrontEdgeB.first->B() == this)) {
_FrontEdgeB.first = iNew;
return;
}
if ((iOld == _BackEdgeA.first) && (_BackEdgeA.first->B() == this)) {
_BackEdgeA.first = iNew;
return;
}
if ((iOld == _BackEdgeB.first) && (_BackEdgeB.first->B() == this)) {
_BackEdgeB.first = iNew;
return;
}
}
/** iterators access */
ViewVertex::edge_iterator TVertex::edges_begin()
{
// return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA);
return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
}
ViewVertex::const_edge_iterator TVertex::edges_begin() const
{
// return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA);
return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
}
ViewVertex::edge_iterator TVertex::edges_end()
{
// return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB,
// directedViewEdge(0,true));
return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
}
ViewVertex::const_edge_iterator TVertex::edges_end() const
{
// return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB,
// directedViewEdge(0, true));
return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
}
ViewVertex::edge_iterator TVertex::edges_iterator(ViewEdge *iEdge)
{
for (edge_pointers_container::iterator it = _sortedEdges.begin(), itend = _sortedEdges.end();
it != itend;
it++) {
if ((*it)->first == iEdge) {
return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it);
}
}
return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
#if 0
directedViewEdge dEdge;
if (_FrontEdgeA.first == iEdge) {
dEdge = _FrontEdgeA;
}
else if (_FrontEdgeB.first == iEdge) {
dEdge = _FrontEdgeB;
}
else if (_BackEdgeA.first == iEdge) {
dEdge = _BackEdgeA;
}
else if (_BackEdgeB.first == iEdge) {
dEdge = _BackEdgeB;
}
return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge);
#endif
}
ViewVertex::const_edge_iterator TVertex::edges_iterator(ViewEdge *iEdge) const
{
for (edge_pointers_container::const_iterator it = _sortedEdges.begin(),
itend = _sortedEdges.end();
it != itend;
it++) {
if ((*it)->first == iEdge) {
return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it);
}
}
return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
#if 0
directedViewEdge dEdge;
if (_FrontEdgeA.first == iEdge) {
dEdge = _FrontEdgeA;
}
else if (_FrontEdgeB.first == iEdge) {
dEdge = _FrontEdgeB;
}
else if (_BackEdgeA.first == iEdge) {
dEdge = _BackEdgeA;
}
else if (_BackEdgeB.first == iEdge) {
dEdge = _BackEdgeB;
}
return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge);
#endif
}
ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesBegin()
{
return ViewVertexInternal::orientedViewEdgeIterator(
_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
}
ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesEnd()
{
return ViewVertexInternal::orientedViewEdgeIterator(
_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end());
}
ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesIterator(ViewEdge *iEdge)
{
for (edge_pointers_container::iterator it = _sortedEdges.begin(), itend = _sortedEdges.end();
it != itend;
it++) {
if ((*it)->first == iEdge) {
return ViewVertexInternal::orientedViewEdgeIterator(
_sortedEdges.begin(), _sortedEdges.end(), it);
}
}
return ViewVertexInternal::orientedViewEdgeIterator(
_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin());
}
/**********************************/
/* */
/* */
/* NonTVertex */
/* */
/* */
/**********************************/
void NonTVertex::AddOutgoingViewEdge(ViewEdge *iVEdge)
{
// let's keep the viewedges ordered in CCW order in the 2D image plan
directedViewEdge idve(iVEdge, false);
if (!_ViewEdges.empty()) {
edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end();
for (; (dve != dveend) && ViewEdgeComp(*dve, idve); ++dve) {
/* pass */
}
_ViewEdges.insert(dve, idve);
}
else {
_ViewEdges.push_back(idve);
}
}
void NonTVertex::AddIncomingViewEdge(ViewEdge *iVEdge)
{
// let's keep the viewedges ordered in CCW order in the 2D image plan
directedViewEdge idve(iVEdge, true);
if (!_ViewEdges.empty()) {
edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end();
for (; (dve != dveend) && ViewEdgeComp(*dve, idve); ++dve) {
/* pass */
}
_ViewEdges.insert(dve, idve);
}
else {
_ViewEdges.push_back(idve);
}
}
/** iterators access */
ViewVertex::edge_iterator NonTVertex::edges_begin()
{
return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
ViewVertex::const_edge_iterator NonTVertex::edges_begin() const
{
return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
ViewVertex::edge_iterator NonTVertex::edges_end()
{
return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
}
ViewVertex::const_edge_iterator NonTVertex::edges_end() const
{
return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
}
ViewVertex::edge_iterator NonTVertex::edges_iterator(ViewEdge *iEdge)
{
for (edges_container::iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend;
it++) {
if ((it)->first == iEdge) {
return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it);
}
}
return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
ViewVertex::const_edge_iterator NonTVertex::edges_iterator(ViewEdge *iEdge) const
{
for (edges_container::const_iterator it = _ViewEdges.begin(), itend = _ViewEdges.end();
it != itend;
it++) {
if ((it)->first == iEdge) {
return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it);
}
}
return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesBegin()
{
return ViewVertexInternal::orientedViewEdgeIterator(
_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesEnd()
{
return ViewVertexInternal::orientedViewEdgeIterator(
_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end());
}
ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesIterator(ViewEdge *iEdge)
{
for (edges_container::iterator it = _ViewEdges.begin(), itend = _ViewEdges.end(); it != itend;
it++) {
if ((it)->first == iEdge) {
return ViewVertexInternal::orientedViewEdgeIterator(
_ViewEdges.begin(), _ViewEdges.end(), it);
}
}
return ViewVertexInternal::orientedViewEdgeIterator(
_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin());
}
/**********************************/
/* */
/* */
/* ViewEdge */
/* */
/* */
/**********************************/
real ViewEdge::getLength2D() const
{
float length = 0.0f;
ViewEdge::const_fedge_iterator itlast = fedge_iterator_last();
ViewEdge::const_fedge_iterator it = fedge_iterator_begin(), itend = fedge_iterator_end();
Vec2r seg;
do {
seg = Vec2r((*it)->orientation2d()[0], (*it)->orientation2d()[1]);
length += seg.norm();
++it;
} while ((it != itend) && (it != itlast));
return length;
}
//! view edge iterator
ViewEdge::edge_iterator ViewEdge::ViewEdge_iterator()
{
return edge_iterator(this);
}
ViewEdge::const_edge_iterator ViewEdge::ViewEdge_iterator() const
{
return const_edge_iterator((ViewEdge *)this);
}
//! feature edge iterator
ViewEdge::fedge_iterator ViewEdge::fedge_iterator_begin()
{
return fedge_iterator(this->_FEdgeA, this->_FEdgeB);
}
ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_begin() const
{
return const_fedge_iterator(this->_FEdgeA, this->_FEdgeB);
}
ViewEdge::fedge_iterator ViewEdge::fedge_iterator_last()
{
return fedge_iterator(this->_FEdgeB, this->_FEdgeB);
}
ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_last() const
{
return const_fedge_iterator(this->_FEdgeB, this->_FEdgeB);
}
ViewEdge::fedge_iterator ViewEdge::fedge_iterator_end()
{
return fedge_iterator(nullptr, this->_FEdgeB);
}
ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_end() const
{
return const_fedge_iterator(nullptr, this->_FEdgeB);
}
//! embedding vertex iterator
ViewEdge::const_vertex_iterator ViewEdge::vertices_begin() const
{
return const_vertex_iterator(this->_FEdgeA->vertexA(), nullptr, _FEdgeA);
}
ViewEdge::vertex_iterator ViewEdge::vertices_begin()
{
return vertex_iterator(this->_FEdgeA->vertexA(), nullptr, _FEdgeA);
}
ViewEdge::const_vertex_iterator ViewEdge::vertices_last() const
{
return const_vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, nullptr);
}
ViewEdge::vertex_iterator ViewEdge::vertices_last()
{
return vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, nullptr);
}
ViewEdge::const_vertex_iterator ViewEdge::vertices_end() const
{
return const_vertex_iterator(nullptr, _FEdgeB, nullptr);
}
ViewEdge::vertex_iterator ViewEdge::vertices_end()
{
return vertex_iterator(nullptr, _FEdgeB, nullptr);
}
Interface0DIterator ViewEdge::verticesBegin()
{
Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(
this->_FEdgeA->vertexA(), this->_FEdgeA->vertexA(), nullptr, _FEdgeA, 0.0f));
return ret;
}
Interface0DIterator ViewEdge::verticesEnd()
{
Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(
nullptr, this->_FEdgeA->vertexA(), _FEdgeB, nullptr, getLength2D()));
return ret;
}
Interface0DIterator ViewEdge::pointsBegin(float /*t*/)
{
return verticesBegin();
}
Interface0DIterator ViewEdge::pointsEnd(float /*t*/)
{
return verticesEnd();
}
/**********************************/
/* */
/* */
/* ViewShape */
/* */
/* */
/**********************************/
ViewShape::~ViewShape()
{
_Vertices.clear();
if (!_Edges.empty()) {
for (vector<ViewEdge *>::iterator e = _Edges.begin(), eend = _Edges.end(); e != eend; e++) {
delete (*e);
}
_Edges.clear();
}
if (_SShape) {
delete _SShape;
_SShape = nullptr;
}
}
void ViewShape::RemoveEdge(ViewEdge *iViewEdge)
{
FEdge *fedge = iViewEdge->fedgeA();
for (vector<ViewEdge *>::iterator ve = _Edges.begin(), veend = _Edges.end(); ve != veend; ve++) {
if (iViewEdge == (*ve)) {
_Edges.erase(ve);
_SShape->RemoveEdge(fedge);
break;
}
}
}
void ViewShape::RemoveVertex(ViewVertex *iViewVertex)
{
for (vector<ViewVertex *>::iterator vv = _Vertices.begin(), vvend = _Vertices.end(); vv != vvend;
vv++) {
if (iViewVertex == (*vv)) {
_Vertices.erase(vv);
break;
}
}
}
/**********************************/
/* */
/* */
/* ViewEdge */
/* */
/* */
/**********************************/
void ViewEdge::UpdateFEdges()
{
FEdge *currentEdge = _FEdgeA;
do {
currentEdge->setViewEdge(this);
currentEdge = currentEdge->nextEdge();
} while (!ELEM(currentEdge, NULL, _FEdgeB));
// last one
_FEdgeB->setViewEdge(this);
}
} /* namespace Freestyle */