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/winged_edge/WEdge.h
Jacques Lucke 91694b9b58 Code Style: use "#pragma once" in source directory
This replaces header include guards with `#pragma once`.
A couple of include guards are not removed yet (e.g. `__RNA_TYPES_H__`),
because they are used in other places.

This patch has been generated by P1561 followed by `make format`.

Differential Revision: https://developer.blender.org/D8466
2020-08-07 09:50:34 +02:00

1430 lines
30 KiB
C++

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#pragma once
/** \file
* \ingroup freestyle
* \brief Classes to define a Winged Edge data structure.
*/
#include <iterator>
#include <vector>
#include "../geometry/Geom.h"
#include "../scene_graph/FrsMaterial.h"
#include "../system/FreestyleConfig.h"
#include "BLI_math.h"
#ifdef WITH_CXX_GUARDEDALLOC
# include "MEM_guardedalloc.h"
#endif
using namespace std;
namespace Freestyle {
using namespace Geometry;
/**********************************
* *
* *
* WVertex *
* *
* *
**********************************/
class WOEdge;
class WEdge;
class WShape;
class WFace;
class WVertex {
protected:
int _Id; // an identificator
Vec3f _Vertex;
vector<WEdge *> _EdgeList;
WShape *_Shape; // the shape to which the vertex belongs
bool _Smooth; // flag to indicate whether the Vertex belongs to a smooth edge or not
short _Border; // 1 -> border, 0 -> no border, -1 -> not set
public:
void *userdata; // designed to store specific user data
inline WVertex(const Vec3f &v)
{
_Id = 0;
_Vertex = v;
userdata = NULL;
_Shape = NULL;
_Smooth = true;
_Border = -1;
}
/*! Copy constructor */
WVertex(WVertex &iBrother);
virtual WVertex *duplicate();
virtual ~WVertex()
{
}
/*! accessors */
inline Vec3f &GetVertex()
{
return _Vertex;
}
inline vector<WEdge *> &GetEdges()
{
return _EdgeList;
}
inline int GetId()
{
return _Id;
}
inline WShape *shape() const
{
return _Shape;
}
inline bool isSmooth() const
{
return _Smooth;
}
bool isBoundary();
/*! modifiers */
inline void setVertex(const Vec3f &v)
{
_Vertex = v;
}
inline void setEdges(const vector<WEdge *> &iEdgeList)
{
_EdgeList = iEdgeList;
}
inline void setId(int id)
{
_Id = id;
}
inline void setShape(WShape *iShape)
{
_Shape = iShape;
}
inline void setSmooth(bool b)
{
_Smooth = b;
}
inline void setBorder(bool b)
{
if (b) {
_Border = 1;
}
else {
_Border = 0;
}
}
/*! Adds an edge to the edges list */
void AddEdge(WEdge *iEdge);
virtual void ResetUserData()
{
userdata = NULL;
}
public:
/*! Iterator to iterate over a vertex incoming edges in the CCW order*/
#if defined(__GNUC__) && (__GNUC__ < 3)
class incoming_edge_iterator : public input_iterator<WOEdge *, ptrdiff_t>
#else
class incoming_edge_iterator : public iterator<input_iterator_tag, WOEdge *, ptrdiff_t>
#endif
{
private:
WVertex *_vertex;
//
WOEdge *_begin;
WOEdge *_current;
public:
#if defined(__GNUC__) && (__GNUC__ < 3)
inline incoming_edge_iterator() : input_iterator<WOEdge *, ptrdiff_t>()
{
}
#else
inline incoming_edge_iterator() : iterator<input_iterator_tag, WOEdge *, ptrdiff_t>()
{
}
#endif
virtual ~incoming_edge_iterator(){}; // soc
protected:
friend class WVertex;
inline incoming_edge_iterator(WVertex *iVertex, WOEdge *iBegin, WOEdge *iCurrent)
#if defined(__GNUC__) && (__GNUC__ < 3)
: input_iterator<WOEdge *, ptrdiff_t>()
#else
: iterator<input_iterator_tag, WOEdge *, ptrdiff_t>()
#endif
{
_vertex = iVertex;
_begin = iBegin;
_current = iCurrent;
}
public:
inline incoming_edge_iterator(const incoming_edge_iterator &iBrother)
#if defined(__GNUC__) && (__GNUC__ < 3)
: input_iterator<WOEdge *, ptrdiff_t>(iBrother)
#else
: iterator<input_iterator_tag, WOEdge *, ptrdiff_t>(iBrother)
#endif
{
_vertex = iBrother._vertex;
_begin = iBrother._begin;
_current = iBrother._current;
}
public:
// operators
// operator corresponding to ++i
virtual incoming_edge_iterator &operator++()
{
increment();
return *this;
}
// operator corresponding to i++
virtual incoming_edge_iterator operator++(int)
{
incoming_edge_iterator tmp = *this;
increment();
return tmp;
}
// comparibility
virtual bool operator!=(const incoming_edge_iterator &b) const
{
return ((_current) != (b._current));
}
virtual bool operator==(const incoming_edge_iterator &b) const
{
return ((_current) == (b._current));
}
// dereferencing
virtual WOEdge *operator*();
// virtual WOEdge **operator->();
protected:
virtual void increment();
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex:incoming_edge_iterator")
#endif
};
/*! Iterator to iterate over a vertex faces in the CCW order */
#if defined(__GNUC__) && (__GNUC__ < 3)
class face_iterator : public input_iterator<WFace *, ptrdiff_t>
#else
class face_iterator : public iterator<input_iterator_tag, WFace *, ptrdiff_t>
#endif
{
private:
incoming_edge_iterator _edge_it;
public:
#if defined(__GNUC__) && (__GNUC__ < 3)
inline face_iterator() : input_iterator<WFace *, ptrdiff_t>()
{
}
#else
inline face_iterator() : iterator<input_iterator_tag, WFace *, ptrdiff_t>()
{
}
#endif
virtual ~face_iterator(){}; // soc
protected:
friend class WVertex;
inline face_iterator(incoming_edge_iterator it)
#if defined(__GNUC__) && (__GNUC__ < 3)
: input_iterator<WFace *, ptrdiff_t>()
#else
: iterator<input_iterator_tag, WFace *, ptrdiff_t>()
#endif
{
_edge_it = it;
}
public:
inline face_iterator(const face_iterator &iBrother)
#if defined(__GNUC__) && (__GNUC__ < 3)
: input_iterator<WFace *, ptrdiff_t>(iBrother)
#else
: iterator<input_iterator_tag, WFace *, ptrdiff_t>(iBrother)
#endif
{
_edge_it = iBrother._edge_it;
}
public:
// operators
// operator corresponding to ++i
virtual face_iterator &operator++()
{
increment();
return *this;
}
// operator corresponding to i++
virtual face_iterator operator++(int)
{
face_iterator tmp = *this;
increment();
return tmp;
}
// comparibility
virtual bool operator!=(const face_iterator &b) const
{
return ((_edge_it) != (b._edge_it));
}
virtual bool operator==(const face_iterator &b) const
{
return ((_edge_it) == (b._edge_it));
}
// dereferencing
virtual WFace *operator*();
// virtual WOEdge **operator->();
protected:
inline void increment()
{
++_edge_it;
}
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex:face_iterator")
#endif
};
public:
/*! iterators access */
virtual incoming_edge_iterator incoming_edges_begin();
virtual incoming_edge_iterator incoming_edges_end();
virtual face_iterator faces_begin()
{
return face_iterator(incoming_edges_begin());
}
virtual face_iterator faces_end()
{
return face_iterator(incoming_edges_end());
}
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WVertex")
#endif
};
/**********************************
* *
* *
* WOEdge *
* *
* *
**********************************/
class WFace;
class WEdge;
class WOEdge {
protected:
#if 0
WOEdge *_paCWEdge; // edge reached when traveling clockwise on aFace from the edge
WOEdge *_pbCWEdge; // edge reached when traveling clockwise on bFace from the edge
WOEdge *_paCCWEdge; // edge reached when traveling counterclockwise on aFace from the edge
WOEdge *_pbCCWEdge; // edge reached when traveling counterclockwise on bFace from the edge
#endif
WVertex *_paVertex; // starting vertex
WVertex *_pbVertex; // ending vertex
WFace *_paFace; // when following the edge, face on the right
WFace *_pbFace; // when following the edge, face on the left
WEdge *_pOwner; // Edge
Vec3f _vec;
float _angle;
public:
void *userdata;
inline WOEdge()
{
#if 0
_paCWEdge = NULL;
_pbCWEdge = NULL;
_paCCWEdge = NULL;
_pbCCWEdge = NULL;
#endif
_paVertex = NULL;
_pbVertex = NULL;
_paFace = NULL;
_pbFace = NULL;
_pOwner = NULL;
userdata = NULL;
}
virtual ~WOEdge(){}; // soc
/*! copy constructor */
WOEdge(WOEdge &iBrother);
virtual WOEdge *duplicate();
/*! accessors */
#if 0
inline WOEdge *GetaCWEdge()
{
return _paCWEdge;
}
inline WOEdge *GetbCWEdge()
{
return _pbCWEdge;
}
inline WOEdge *GetaCCWEdge()
{
return _paCCWEdge;
}
inline WOEdge *GetbCCWEdge()
{
return _pbCCWEdge;
}
#endif
inline WVertex *GetaVertex()
{
return _paVertex;
}
inline WVertex *GetbVertex()
{
return _pbVertex;
}
inline WFace *GetaFace()
{
return _paFace;
}
inline WFace *GetbFace()
{
return _pbFace;
}
inline WEdge *GetOwner()
{
return _pOwner;
}
inline const Vec3f &GetVec()
{
return _vec;
}
inline const float GetAngle()
{
return _angle;
}
/*! modifiers */
#if 0
inline void SetaCWEdge(WOEdge *pe)
{
_paCWEdge = pe;
}
inline void SetbCWEdge(WOEdge *pe)
{
_pbCWEdge = pe;
}
inline void SetaCCWEdge(WOEdge *pe)
{
_paCCWEdge = pe;
}
inline void SetbCCCWEdge(WOEdge *pe)
{
_pbCCWEdge = pe;
}
#endif
inline void setVecAndAngle();
inline void setaVertex(WVertex *pv)
{
_paVertex = pv;
setVecAndAngle();
}
inline void setbVertex(WVertex *pv)
{
_pbVertex = pv;
setVecAndAngle();
}
inline void setaFace(WFace *pf)
{
_paFace = pf;
setVecAndAngle();
}
inline void setbFace(WFace *pf)
{
_pbFace = pf;
setVecAndAngle();
}
inline void setOwner(WEdge *pe)
{
_pOwner = pe;
}
/*! Retrieves the list of edges in CW order */
inline void RetrieveCWOrderedEdges(vector<WEdge *> &oEdges);
WOEdge *twin();
WOEdge *getPrevOnFace();
virtual void ResetUserData()
{
userdata = NULL;
}
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WOEdge")
#endif
};
/**********************************
* *
* *
* WEdge *
* *
* *
**********************************/
class WEdge {
protected:
WOEdge *_paOEdge; // first oriented edge
WOEdge *_pbOEdge; // second oriented edge
short _nOEdges; // number of oriented edges associated with this edge. (1 means border edge)
bool _Mark; // user-specified edge mark for feature edge detection
int _Id; // Identifier for the edge
public:
void *userdata; // designed to store specific user data
inline WEdge()
{
_paOEdge = NULL;
_pbOEdge = NULL;
_nOEdges = 0;
userdata = NULL;
}
inline WEdge(WOEdge *iOEdge)
{
_paOEdge = iOEdge;
_pbOEdge = NULL;
_nOEdges = 1;
userdata = NULL;
}
inline WEdge(WOEdge *iaOEdge, WOEdge *ibOEdge)
{
_paOEdge = iaOEdge;
_pbOEdge = ibOEdge;
_nOEdges = 2;
userdata = NULL;
}
/*! Copy constructor */
WEdge(WEdge &iBrother);
virtual WEdge *duplicate();
virtual ~WEdge()
{
if (_paOEdge) {
delete _paOEdge;
_paOEdge = NULL;
}
if (_pbOEdge) {
delete _pbOEdge;
_pbOEdge = NULL;
}
}
/*! checks whether two WEdge have a common vertex.
* Returns a pointer on the common vertex if it exists, NULL otherwise.
*/
static inline WVertex *CommonVertex(WEdge *iEdge1, WEdge *iEdge2)
{
if (!iEdge1 || !iEdge2) {
return NULL;
}
WVertex *wv1 = iEdge1->GetaOEdge()->GetaVertex();
WVertex *wv2 = iEdge1->GetaOEdge()->GetbVertex();
WVertex *wv3 = iEdge2->GetaOEdge()->GetaVertex();
WVertex *wv4 = iEdge2->GetaOEdge()->GetbVertex();
if ((wv1 == wv3) || (wv1 == wv4)) {
return wv1;
}
else if ((wv2 == wv3) || (wv2 == wv4)) {
return wv2;
}
return NULL;
}
/*! accessors */
inline WOEdge *GetaOEdge()
{
return _paOEdge;
}
inline WOEdge *GetbOEdge()
{
return _pbOEdge;
}
inline short GetNumberOfOEdges()
{
return _nOEdges;
}
inline bool GetMark()
{
return _Mark;
}
inline int GetId()
{
return _Id;
}
inline WVertex *GetaVertex()
{
return _paOEdge->GetaVertex();
}
inline WVertex *GetbVertex()
{
return _paOEdge->GetbVertex();
}
inline WFace *GetaFace()
{
return _paOEdge->GetaFace();
}
inline WFace *GetbFace()
{
return _paOEdge->GetbFace();
}
inline WOEdge *GetOtherOEdge(WOEdge *iOEdge)
{
if (iOEdge == _paOEdge) {
return _pbOEdge;
}
else {
return _paOEdge;
}
}
/*! modifiers */
inline void setaOEdge(WOEdge *iEdge)
{
_paOEdge = iEdge;
}
inline void setbOEdge(WOEdge *iEdge)
{
_pbOEdge = iEdge;
}
inline void AddOEdge(WOEdge *iEdge)
{
if (!_paOEdge) {
_paOEdge = iEdge;
_nOEdges++;
return;
}
if (!_pbOEdge) {
_pbOEdge = iEdge;
_nOEdges++;
return;
}
}
inline void setNumberOfOEdges(short n)
{
_nOEdges = n;
}
inline void setMark(bool mark)
{
_Mark = mark;
}
inline void setId(int id)
{
_Id = id;
}
virtual void ResetUserData()
{
userdata = NULL;
}
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WEdge")
#endif
};
/**********************************
* *
* *
* WFace *
* *
* *
**********************************/
class WFace {
protected:
vector<WOEdge *> _OEdgeList; // list of oriented edges of bording the face
Vec3f _Normal; // normal to the face
// in case there is a normal per vertex.
// The normal number i corresponds to the aVertex of the oedge number i, for that face
vector<Vec3f> _VerticesNormals;
vector<Vec2f> _VerticesTexCoords;
int _Id;
unsigned _FrsMaterialIndex;
bool _Mark; // Freestyle face mark (if true, feature edges on this face are ignored)
public:
void *userdata;
inline WFace()
{
userdata = NULL;
_FrsMaterialIndex = 0;
}
/*! copy constructor */
WFace(WFace &iBrother);
virtual WFace *duplicate();
virtual ~WFace()
{
}
/*! accessors */
inline const vector<WOEdge *> &getEdgeList()
{
return _OEdgeList;
}
inline WOEdge *GetOEdge(int i)
{
return _OEdgeList[i];
}
inline Vec3f &GetNormal()
{
return _Normal;
}
inline int GetId()
{
return _Id;
}
inline unsigned frs_materialIndex() const
{
return _FrsMaterialIndex;
}
inline bool GetMark() const
{
return _Mark;
}
const FrsMaterial &frs_material();
/*! The vertex of index i corresponds to the a vertex of the edge of index i */
inline WVertex *GetVertex(unsigned int index)
{
#if 0
if (index >= _OEdgeList.size()) {
return NULL;
}
#endif
return _OEdgeList[index]->GetaVertex();
}
/*! returns the index at which iVertex is stored in the array.
* returns -1 if iVertex doesn't belong to the face.
*/
inline int GetIndex(WVertex *iVertex)
{
int index = 0;
for (vector<WOEdge *>::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end();
woe != woend;
woe++) {
if ((*woe)->GetaVertex() == iVertex) {
return index;
}
++index;
}
return -1;
}
inline void RetrieveVertexList(vector<WVertex *> &oVertices)
{
for (vector<WOEdge *>::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end();
woe != woend;
woe++) {
oVertices.push_back((*woe)->GetaVertex());
}
}
inline void RetrieveBorderFaces(vector<const WFace *> &oWFaces)
{
for (vector<WOEdge *>::iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end();
woe != woend;
woe++) {
WFace *af;
if ((af = (*woe)->GetaFace())) {
oWFaces.push_back(af);
}
}
}
inline WFace *GetBordingFace(int index)
{
#if 0
if (index >= _OEdgeList.size()) {
return NULL;
}
#endif
return _OEdgeList[index]->GetaFace();
}
inline WFace *GetBordingFace(WOEdge *iOEdge)
{
return iOEdge->GetaFace();
}
inline vector<Vec3f> &GetPerVertexNormals()
{
return _VerticesNormals;
}
inline vector<Vec2f> &GetPerVertexTexCoords()
{
return _VerticesTexCoords;
}
/*! Returns the normal of the vertex of index index */
inline Vec3f &GetVertexNormal(int index)
{
return _VerticesNormals[index];
}
/*! Returns the tex coords of the vertex of index index */
inline Vec2f &GetVertexTexCoords(int index)
{
return _VerticesTexCoords[index];
}
/*! Returns the normal of the vertex iVertex for that face */
inline Vec3f &GetVertexNormal(WVertex *iVertex)
{
int i = 0;
int index = 0;
for (vector<WOEdge *>::const_iterator woe = _OEdgeList.begin(), woend = _OEdgeList.end();
woe != woend;
woe++) {
if ((*woe)->GetaVertex() == iVertex) {
index = i;
break;
}
++i;
}
return _VerticesNormals[index];
}
inline WOEdge *GetNextOEdge(WOEdge *iOEdge)
{
bool found = false;
vector<WOEdge *>::iterator woe, woend, woefirst;
woefirst = _OEdgeList.begin();
for (woe = woefirst, woend = _OEdgeList.end(); woe != woend; ++woe) {
if (found) {
return (*woe);
}
if ((*woe) == iOEdge) {
found = true;
}
}
// We left the loop. That means that the first OEdge was the good one:
if (found) {
return (*woefirst);
}
return NULL;
}
WOEdge *GetPrevOEdge(WOEdge *iOEdge);
inline int numberOfEdges() const
{
return _OEdgeList.size();
}
inline int numberOfVertices() const
{
return _OEdgeList.size();
}
/*! Returns true if the face has one ot its edge which is a border edge */
inline bool isBorder() const
{
for (vector<WOEdge *>::const_iterator woe = _OEdgeList.begin(), woeend = _OEdgeList.end();
woe != woeend;
++woe) {
if ((*woe)->GetOwner()->GetbOEdge() == 0) {
return true;
}
}
return false;
}
/*! modifiers */
inline void setEdgeList(const vector<WOEdge *> &iEdgeList)
{
_OEdgeList = iEdgeList;
}
inline void setNormal(const Vec3f &iNormal)
{
_Normal = iNormal;
}
inline void setNormalList(const vector<Vec3f> &iNormalsList)
{
_VerticesNormals = iNormalsList;
}
inline void setTexCoordsList(const vector<Vec2f> &iTexCoordsList)
{
_VerticesTexCoords = iTexCoordsList;
}
inline void setId(int id)
{
_Id = id;
}
inline void setFrsMaterialIndex(unsigned iMaterialIndex)
{
_FrsMaterialIndex = iMaterialIndex;
}
inline void setMark(bool iMark)
{
_Mark = iMark;
}
/*! designed to build a specialized WEdge for use in MakeEdge */
virtual WEdge *instanciateEdge() const
{
return new WEdge;
}
/*! Builds an oriented edge
* Returns the built edge.
* v1, v2
* Vertices at the edge's extremities
* The edge is oriented from v1 to v2.
*/
virtual WOEdge *MakeEdge(WVertex *v1, WVertex *v2);
/*! Adds an edge to the edges list */
inline void AddEdge(WOEdge *iEdge)
{
_OEdgeList.push_back(iEdge);
}
/*! For triangles, returns the edge opposite to the vertex in e.
* returns false if the face is not a triangle or if the vertex is not found
*/
bool getOppositeEdge(const WVertex *v, WOEdge *&e);
/*! compute the area of the face */
float getArea();
WShape *getShape();
virtual void ResetUserData()
{
userdata = NULL;
}
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WFace")
#endif
};
/**********************************
* *
* *
* WShape *
* *
* *
**********************************/
class WShape {
protected:
vector<WVertex *> _VertexList;
vector<WEdge *> _EdgeList;
vector<WFace *> _FaceList;
int _Id;
string _Name;
string _LibraryPath;
static unsigned _SceneCurrentId;
#if 0
Vec3f _min;
Vec3f _max;
#endif
vector<FrsMaterial> _FrsMaterials;
#if 0
float _meanEdgeSize;
#endif
public:
inline WShape()
{
#if 0
_meanEdgeSize = 0;
#endif
_Id = _SceneCurrentId;
_SceneCurrentId++;
}
/*! copy constructor */
WShape(WShape &iBrother);
virtual WShape *duplicate();
virtual ~WShape()
{
if (_EdgeList.size() != 0) {
vector<WEdge *>::iterator e;
for (e = _EdgeList.begin(); e != _EdgeList.end(); ++e) {
delete (*e);
}
_EdgeList.clear();
}
if (_VertexList.size() != 0) {
vector<WVertex *>::iterator v;
for (v = _VertexList.begin(); v != _VertexList.end(); ++v) {
delete (*v);
}
_VertexList.clear();
}
if (_FaceList.size() != 0) {
vector<WFace *>::iterator f;
for (f = _FaceList.begin(); f != _FaceList.end(); ++f) {
delete (*f);
}
_FaceList.clear();
}
}
/*! accessors */
inline vector<WEdge *> &getEdgeList()
{
return _EdgeList;
}
inline vector<WVertex *> &getVertexList()
{
return _VertexList;
}
inline vector<WFace *> &GetFaceList()
{
return _FaceList;
}
inline unsigned GetId()
{
return _Id;
}
#if 0
inline void bbox(Vec3f &min, Vec3f &max)
{
min = _min;
max = _max;
}
#endif
inline const FrsMaterial &frs_material(unsigned i) const
{
return _FrsMaterials[i];
}
inline const vector<FrsMaterial> &frs_materials() const
{
return _FrsMaterials;
}
#if 0
inline const float getMeanEdgeSize() const
{
return _meanEdgeSize;
}
#endif
inline const string &getName() const
{
return _Name;
}
inline const string &getLibraryPath() const
{
return _LibraryPath;
}
/*! modifiers */
static inline void setCurrentId(const unsigned id)
{
_SceneCurrentId = id;
}
inline void setEdgeList(const vector<WEdge *> &iEdgeList)
{
_EdgeList = iEdgeList;
}
inline void setVertexList(const vector<WVertex *> &iVertexList)
{
_VertexList = iVertexList;
}
inline void setFaceList(const vector<WFace *> &iFaceList)
{
_FaceList = iFaceList;
}
inline void setId(int id)
{
_Id = id;
}
#if 0
inline void setBBox(const Vec3f &min, const Vec3f &max)
{
_min = min;
_max = max;
}
#endif
inline void setFrsMaterial(const FrsMaterial &frs_material, unsigned i)
{
_FrsMaterials[i] = frs_material;
}
inline void setFrsMaterials(const vector<FrsMaterial> &iMaterials)
{
_FrsMaterials = iMaterials;
}
inline void setName(const string &name)
{
_Name = name;
}
inline void setLibraryPath(const string &path)
{
_LibraryPath = path;
}
/*! designed to build a specialized WFace for use in MakeFace */
virtual WFace *instanciateFace() const
{
return new WFace;
}
/*! adds a new face to the shape
* returns the built face.
* iVertexList
* List of face's vertices. These vertices are not added to the WShape vertex list; they are
* supposed to be already stored when calling MakeFace. The order in which the vertices are
* stored in the list determines the face's edges orientation and (so) the face orientation.
* iMaterialIndex
* The material index for this face
*/
virtual WFace *MakeFace(vector<WVertex *> &iVertexList,
vector<bool> &iFaceEdgeMarksList,
unsigned iMaterialIndex);
/*! adds a new face to the shape. The difference with the previous method is that this one is
* designed to build a WingedEdge structure for which there are per vertex normals, opposed to
* per face normals. returns the built face. iVertexList List of face's vertices. These vertices
* are not added to the WShape vertex list; they are supposed to be already stored when calling
* MakeFace. The order in which the vertices are stored in the list determines the face's edges
* orientation and (so) the face orientation. iMaterialIndex The materialIndex for this face
* iNormalsList
* The list of normals, iNormalsList[i] corresponding to the normal of the vertex
* iVertexList[i] for that face. iTexCoordsList The list of tex coords, iTexCoordsList[i]
* corresponding to the normal of the vertex iVertexList[i] for that face.
*/
virtual WFace *MakeFace(vector<WVertex *> &iVertexList,
vector<Vec3f> &iNormalsList,
vector<Vec2f> &iTexCoordsList,
vector<bool> &iFaceEdgeMarksList,
unsigned iMaterialIndex);
inline void AddEdge(WEdge *iEdge)
{
_EdgeList.push_back(iEdge);
}
inline void AddFace(WFace *iFace)
{
_FaceList.push_back(iFace);
}
inline void AddVertex(WVertex *iVertex)
{
iVertex->setShape(this);
_VertexList.push_back(iVertex);
}
inline void ResetUserData()
{
for (vector<WVertex *>::iterator v = _VertexList.begin(), vend = _VertexList.end(); v != vend;
v++) {
(*v)->ResetUserData();
}
for (vector<WEdge *>::iterator e = _EdgeList.begin(), eend = _EdgeList.end(); e != eend; e++) {
(*e)->ResetUserData();
// manages WOEdge:
WOEdge *oe = (*e)->GetaOEdge();
if (oe) {
oe->ResetUserData();
}
oe = (*e)->GetbOEdge();
if (oe) {
oe->ResetUserData();
}
}
for (vector<WFace *>::iterator f = _FaceList.begin(), fend = _FaceList.end(); f != fend; f++) {
(*f)->ResetUserData();
}
}
#if 0
inline void ComputeBBox()
{
_min = _VertexList[0]->GetVertex();
_max = _VertexList[0]->GetVertex();
Vec3f v;
for (vector<WVertex *>::iterator wv = _VertexList.begin(), wvend = _VertexList.end();
wv != wvend;
wv++) {
for (unsigned int i = 0; i < 3; i++) {
v = (*wv)->GetVertex();
if (v[i] < _min[i]) {
_min[i] = v[i];
}
if (v[i] > _max[i]) {
_max[i] = v[i];
}
}
}
}
#endif
#if 0
inline float ComputeMeanEdgeSize()
{
_meanEdgeSize = _meanEdgeSize / _EdgeList.size();
return _meanEdgeSize;
}
#else
real ComputeMeanEdgeSize() const;
#endif
protected:
/*!
* Builds the face passed as argument (which as already been allocated)
* - iVertexList
* List of face's vertices. These vertices are not added to the WShape vertex list;
* they are supposed to be already stored when calling MakeFace.
* The order in which the vertices are stored in the list determines
* the face's edges orientation and (so) the face orientation.
* - iMaterialIndex
* The material index for this face
* - face
* The Face that is filled in
*/
virtual WFace *MakeFace(vector<WVertex *> &iVertexList,
vector<bool> &iFaceEdgeMarksList,
unsigned iMaterialIndex,
WFace *face);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WShape")
#endif
};
/**********************************
* *
* *
* WingedEdge *
* *
* *
**********************************/
class WingedEdge {
public:
WingedEdge()
{
_numFaces = 0;
}
~WingedEdge()
{
clear();
}
void clear()
{
for (vector<WShape *>::iterator it = _wshapes.begin(); it != _wshapes.end(); it++) {
delete *it;
}
_wshapes.clear();
_numFaces = 0;
}
void addWShape(WShape *wshape)
{
_wshapes.push_back(wshape);
_numFaces += wshape->GetFaceList().size();
}
vector<WShape *> &getWShapes()
{
return _wshapes;
}
unsigned getNumFaces()
{
return _numFaces;
}
private:
vector<WShape *> _wshapes;
unsigned _numFaces;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WingedEdge")
#endif
};
/*
* #############################################
* #############################################
* #############################################
* ###### ######
* ###### I M P L E M E N T A T I O N ######
* ###### ######
* #############################################
* #############################################
* #############################################
*/
/* for inline functions */
void WOEdge::RetrieveCWOrderedEdges(vector<WEdge *> &oEdges)
{
WOEdge *currentOEdge = this;
do {
WOEdge *nextOEdge = currentOEdge->GetbFace()->GetNextOEdge(currentOEdge);
oEdges.push_back(nextOEdge->GetOwner());
currentOEdge = nextOEdge->GetOwner()->GetOtherOEdge(nextOEdge);
} while (currentOEdge && (currentOEdge->GetOwner() != GetOwner()));
}
inline void WOEdge::setVecAndAngle()
{
if (_paVertex && _pbVertex) {
_vec = _pbVertex->GetVertex() - _paVertex->GetVertex();
if (_paFace && _pbFace) {
float sine = (_pbFace->GetNormal() ^ _paFace->GetNormal()) * _vec / _vec.norm();
if (sine >= 1.0) {
_angle = M_PI / 2.0;
return;
}
if (sine <= -1.0) {
_angle = -M_PI / 2.0;
return;
}
_angle = ::asin(sine);
}
}
}
} /* namespace Freestyle */