Visualization Library 2.0.0-b3

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
EdgeExtractor.cpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2017, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
33 #include <vlGraphics/Rendering.hpp>
36 #include <vlCore/Log.hpp>
37 #include <vlGraphics/Array.hpp>
38 #include <vlGraphics/Geometry.hpp>
39 
40 using namespace vl;
41 
42 //-----------------------------------------------------------------------------
43 void EdgeExtractor::addEdge(std::set<EdgeExtractor::Edge>& edges, const EdgeExtractor::Edge& e, const fvec3& n)
44 {
45  std::set<EdgeExtractor::Edge>::iterator it = edges.find(e);
46  if (it != edges.end())
47  {
48  VL_CHECK(!it->normal1().isNull())
49  if (mWarnNonManifold && !it->normal2().isNull())
50  vl::Log::error("EdgeExtractor: non-manifold mesh detected!\n");
51  EdgeExtractor::Edge edge = e;
52  edge.setNormal1(it->normal1());
53  edge.setNormal2(n);
54  edges.erase( it );
55  edges.insert(edge);
56  }
57  else
58  {
59  VL_CHECK(!n.isNull());
60  EdgeExtractor::Edge edge = e;
61  edge.setNormal1(n);
62  edges.insert(edge);
63  }
64 }
65 //-----------------------------------------------------------------------------
68 {
69  ArrayAbstract* verts = geom->vertexArray();
70 
71  // mic fixme:
72  // here the bottle-neck seems to be the continuous allocation/deallocation and insertion/search time,
73  // maybe a memory-pool-managed hash table would help?
74  if (!verts)
75  {
76  vl::Log::error("EdgeExtractor::extractEdges(geom): 'geom' must have a vertex array of type ArrayFloat3.\n");
77  return;
78  }
79 
80  std::set<Edge> edges;
81 
82  // iterate all primitives
83  for(int iprim=0; iprim<geom->drawCalls().size(); ++iprim)
84  {
85  DrawCall* prim = geom->drawCalls().at(iprim);
86  // iterate triangles (if present)
87  for(TriangleIterator trit = prim->triangleIterator(); trit.hasNext(); trit.next())
88  {
89  size_t a = trit.a();
90  size_t b = trit.b();
91  size_t c = trit.c();
92  if (a == b || b == c || c == a)
93  continue;
94  // compute normal
95  fvec3 v0 = (fvec3)verts->getAsVec3(a);
96  fvec3 v1 = (fvec3)verts->getAsVec3(b) - v0;
97  fvec3 v2 = (fvec3)verts->getAsVec3(c) - v0;
98  fvec3 n = cross(v1,v2).normalize();
99  if (n.isNull())
100  continue;
101  addEdge(edges, Edge( (fvec3)verts->getAsVec3(a), (fvec3)verts->getAsVec3(b) ), n );
102  addEdge(edges, Edge( (fvec3)verts->getAsVec3(b), (fvec3)verts->getAsVec3(c) ), n );
103  addEdge(edges, Edge( (fvec3)verts->getAsVec3(c), (fvec3)verts->getAsVec3(a) ), n );
104  }
105  }
106 
107  for(std::set<Edge>::iterator it = edges.begin(); it != edges.end(); ++it)
108  {
109  Edge e = *it;
110  // boundary edge
111  if (e.normal2().isNull())
112  e.setIsCrease(true);
113  else
114  // crease edge
115  {
116  float cos1 = dot(e.normal1(), e.normal2());
117  cos1 = vl::clamp(cos1,-1.0f,+1.0f);
118  // return value in the interval [0,pi] radians
119  float a1 = acos(cos1) / fPi * 180.0f;
120  if( a1 > creaseAngle() )
121  e.setIsCrease(true);
122  }
123  mEdges.push_back(e);
124  }
125 }
126 //-----------------------------------------------------------------------------
128 {
129  ref<Geometry> geom = new Geometry;
130  geom->setBufferObjectEnabled(false);
131  ref<ArrayFloat3> vert_array = new ArrayFloat3;
132  geom->setVertexArray(vert_array.get());
133  #ifdef SHOW_NORMALS
134  vert_array->resize(edges().size()*6);
135  #else
136  vert_array->resize(edges().size()*2);
137  #endif
138  for(unsigned i=0; i<edges().size(); ++i)
139  {
140  vert_array->at(i*2+0) = edges()[i].vertex1();
141  vert_array->at(i*2+1) = edges()[i].vertex2();
142  }
143  #ifdef SHOW_NORMALS
144  int start = edges().size()*2;
145  for(unsigned i=0; i<edges().size(); ++i)
146  {
147  fvec3 v = (edges()[i].vertex1() + edges()[i].vertex2()) * 0.5f;
148  vert_array->at(start+i*2+0) = v;
149  vert_array->at(start+i*2+1) = v + edges()[i].normal1()*0.25f;
150  }
151  start = edges().size()*4;
152  for(unsigned i=0; i<edges().size(); ++i)
153  {
154  fvec3 v = (edges()[i].vertex1() + edges()[i].vertex2()) * 0.5f;
155  vert_array->at(start+i*2+0) = v;
156  vert_array->at(start+i*2+1) = v + edges()[i].normal2()*0.25f;
157  }
158  #endif
159  geom->drawCalls().push_back( new vl::DrawArrays(vl::PT_LINES, 0, (int)vert_array->size()) );
160  return geom;
161 }
162 //-----------------------------------------------------------------------------
164 {
165  Geometry* geom = cast<Geometry>(actor->lod(0));
166  if (geom)
167  extractEdges(geom);
168  return geom != NULL;
169 }
170 //-----------------------------------------------------------------------------
172 {
173  for(int i=0; i<actors->size(); ++i)
174  {
175  Geometry* geom = cast<Geometry>(actors->at(i)->lod(0));
176  if (geom)
177  extractEdges(geom);
178  }
179 }
180 //-----------------------------------------------------------------------------
182 {
184  scene_manager->extractVisibleActors( *actors, NULL );
185  extractEdges(actors.get());
186 }
187 //-----------------------------------------------------------------------------
189 {
190  for(int i=0; i<rendering->sceneManagers()->size(); ++i) {
191  extractEdges( rendering->sceneManagers()->at(i) );
192  }
193 }
194 //-----------------------------------------------------------------------------
The ArrayAbstract class defines an abstract interface to conveniently manipulate data stored in a Buf...
Definition: Array.hpp:58
const fvec3 & normal2() const
Associates a Renderable object to an Effect and Transform.
Definition: Actor.hpp:130
bool hasNext()
Returns false if the iterator has reached the end of the triangle list.
const Renderable * lod(int lod_index) const
Returns the Renderable object representing the LOD level specifed by lod_index.
Definition: Actor.hpp:173
float clamp(float x, float minval, float maxval)
Definition: Vector2.hpp:315
const fvec3 & normal1() const
const T * at(int i) const
Definition: Collection.hpp:100
const Vector3 & normalize(T_Scalar *len=NULL)
Definition: Vector3.hpp:227
Vector3< float > fvec3
A 3 components vector with float precision.
Definition: Vector3.hpp:252
const T * get() const
Definition: Object.hpp:128
void setNormal2(const fvec3 &v)
float creaseAngle() const
The minimum angle (in degrees) considered to generate crease-edges.
int size() const
Definition: Collection.hpp:82
const ArrayAbstract * vertexArray() const
Conventional vertex array.
Definition: Geometry.hpp:248
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Definition: Log.cpp:164
void setVertexArray(ArrayAbstract *data)
Conventional vertex array.
Definition: Geometry.cpp:155
virtual void extractVisibleActors(ActorCollection &list, const Camera *camera)=0
Extracts all the enabled and visible Actors contained in the ActorTree hierarchy and appends them to ...
void resize(size_t dim)
Definition: Array.hpp:233
void extractEdges(Geometry *geom)
Extracts the edges from the given Geometry and appends them to edges().
fvec3 cross(const fvec3 &v1, const fvec3 &v2)
Definition: Vector3.hpp:277
virtual vec3 getAsVec3(size_t vector_index) const =0
Returns a vector from the buffer as a vec3 value.
size_t size() const
Returns the number of elements of an array.
Definition: Array.hpp:235
The Geometry class is a Renderable that implements a polygonal mesh made of polygons, lines and points.
Definition: Geometry.hpp:66
Visualization Library main namespace.
const float fPi
Greek Pi constant using float precision.
Definition: std_types.hpp:71
float dot(float a, float b)
Definition: glsl_math.hpp:1111
void setIsCrease(bool iscrease)
virtual TriangleIterator triangleIterator() const =0
Returns a TriangleIterator used to iterate through the triangles of a DrawCall.
void setNormal1(const fvec3 &v)
The SceneManager class is the base class for all the scene managers.
Iterator used to extract the indices of every single triangle of a DrawCall regardless of the primiti...
A single edge as extracted from the EdgeExtractor class.
#define NULL
Definition: OpenGLDefs.hpp:81
The Rendering class collects all the information to perform the rendering of a scene.
Definition: Rendering.hpp:69
T_VectorType & at(size_t i)
Definition: Array.hpp:255
Defined as a simple subclass of Collection<Actor>, see Collection for more information.
Definition: Actor.hpp:479
const std::vector< Edge > & edges() const
The base class of DrawArrays, DrawElements, MultiDrawElements and DrawRangeElements.
Definition: DrawCall.hpp:90
std::vector< Edge > mEdges
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
bool isNull() const
Definition: Vector3.hpp:226
An array of vl::fvec3.
Definition: Array.hpp:414
T acos(T a)
Definition: glsl_math.hpp:329
Wraps the OpenGL function glDrawArrays().
Definition: DrawArrays.hpp:57
ref< Geometry > generateEdgeGeometry() const
void setBufferObjectEnabled(bool enabled)
Enable/disable BufferObject (vertex buffer object) (enabled by default).
Definition: Renderable.hpp:204
#define VL_CHECK(expr)
Definition: checks.hpp:73
void addEdge(std::set< EdgeExtractor::Edge > &edges, const EdgeExtractor::Edge &e, const fvec3 &n)
Collection< SceneManager > * sceneManagers()
Returns the list of SceneManager[s] containing the Actor[s] to be rendered.
Definition: Rendering.hpp:137
Collection< DrawCall > & drawCalls()
Returns the list of DrawCall objects bound to a Geometry.
Definition: Geometry.hpp:102