Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
KennethVanhoey
CGoGN
Commits
c5958723
Commit
c5958723
authored
Aug 08, 2011
by
Sylvain Thery
Browse files
ajout rendu face concave par methode des oreilles
parent
85fd18da
Changes
3
Hide whitespace changes
Inline
Side-by-side
include/Algo/Render/GL2/mapRender.h
View file @
c5958723
...
...
@@ -89,6 +89,129 @@ protected:
typedef
std
::
pair
<
GLuint
*
,
unsigned
int
>
buffer_array
;
class
VertexPoly
{
public:
int
id
;
float
value
;
VertexPoly
*
prev
;
VertexPoly
*
next
;
VertexPoly
*
store_link
;
VertexPoly
(
int
i
,
float
v
,
VertexPoly
*
p
=
NULL
)
:
id
(
i
),
value
(
v
),
prev
(
p
),
next
(
NULL
),
store_link
(
NULL
)
{
if
(
prev
!=
NULL
)
{
prev
->
next
=
this
;
prev
->
store_link
=
this
;
}
}
static
void
close
(
VertexPoly
*
first
,
VertexPoly
*
last
)
{
last
->
next
=
first
;
last
->
store_link
=
first
;
first
->
prev
=
last
;
}
VertexPoly
*
unlink
()
{
this
->
prev
->
next
=
this
->
next
;
this
->
next
->
prev
=
this
->
prev
;
this
->
value
=
20.0
f
;
return
this
->
prev
;
}
static
void
erasePoly
(
VertexPoly
*
vp
)
{
VertexPoly
*
curr
=
vp
;
do
{
VertexPoly
*
tmp
=
curr
;
curr
=
curr
->
store_link
;
delete
tmp
;
}
while
(
curr
!=
vp
);
}
};
// struct VertexPoly
// {
// int id;
// float value;
// unsigned int prev;
// unsigned int next;
// VertexPoly(int i, float v): id(i),value(v) {}
// };
//
// class Polygon
// {
// protected:
// std::vector<VertexPoly> m_vertices;
// public:
// Polygon()
// {
// m_vertices.reserve(256);
// }
//
// inline void addVertex(int id, float val)
// {
// m_vertices.push_back(VertexPoly(id,val));
// }
//
// inline void link_all()
// {
// unsigned int sz = m_vertices.size()-1;
// for (unsigned int i = 1; i<sz; ++i)
// {
// m_vertices[i].next = i+1;
// m_vertices[i].prev = i-1;
// }
// m_vertices[0].next = 1;
// m_vertices[0].prev = m_vertices.size();
// m_vertices[sz].next = 0;
// m_vertices[sz].prev = sz-1;
// }
//
// inline void unlink(unsigned int v)
// {
// m_vertices[ m_vertices[v].prev].next = m_vertices[v].next;
// m_vertices[ m_vertices[v].next].prev = m_vertices[v].prev;
// }
//
// inline const VertexPoly& prev(unsigned int v) const
// {
// return m_vertices[m_vertices[v].prev];
// }
//
// inline const VertexPoly& next(unsigned int v) const
// {
// return m_vertices[m_vertices[v].next];
// }
//
// inline unsigned int prevId(unsigned int v) const
// {
// return m_vertices[v].prev;
// }
//
// inline unsigned int nextId(unsigned int v) const
// {
// return m_vertices[v].next;
// }
//
// inline VertexPoly& operator()(unsigned int v)
// {
// return m_vertices[v];
// }
// };
public:
/**
* Constructor
...
...
@@ -109,6 +232,7 @@ public:
buffer_array
get_nb_index_buffer
()
{
return
std
::
make_pair
(
m_nbIndices
,
SIZE_BUFFER
);
}
protected:
/**
* addition of indices table of one triangle
* @param d a dart of the triangle
...
...
@@ -117,6 +241,19 @@ protected:
template
<
typename
PFP
>
void
addTri
(
typename
PFP
::
MAP
&
map
,
Dart
d
,
std
::
vector
<
GLuint
>&
tableIndices
)
;
template
<
typename
PFP
>
inline
void
addEarTri
(
typename
PFP
::
MAP
&
map
,
Dart
d
,
std
::
vector
<
GLuint
>&
tableIndices
);
template
<
typename
PFP
>
float
computeEarAngle
(
AttributeHandler
<
typename
PFP
::
VEC3
>&
position
,
const
typename
PFP
::
VEC3
&
normalPoly
,
unsigned
int
i
,
unsigned
int
j
,
unsigned
int
k
);
template
<
typename
PFP
>
bool
computeEarIntersection
(
AttributeHandler
<
typename
PFP
::
VEC3
>&
position
,
VertexPoly
*
vp
,
const
typename
PFP
::
VEC3
&
normalPoly
);
template
<
typename
PFP
>
void
recompute2Ears
(
AttributeHandler
<
typename
PFP
::
VEC3
>&
position
,
VertexPoly
*
vp
,
const
typename
PFP
::
VEC3
&
normalPoly
,
std
::
multimap
<
float
,
VertexPoly
*>&
ears
,
bool
convex
);
public:
/**
* creation of indices table of triangles (optimized order)
...
...
@@ -162,6 +299,8 @@ public:
* draw the VBO (function to call in the drawing callback)
*/
void
draw
(
Utils
::
GLSLShader
*
sh
,
int
prim
)
;
unsigned
int
drawSub
(
Utils
::
GLSLShader
*
sh
,
int
prim
,
unsigned
int
nb_elm
);
}
;
}
// namespace GL2
...
...
include/Algo/Render/GL2/mapRender.hpp
View file @
c5958723
...
...
@@ -26,6 +26,11 @@
#include
"Topology/generic/cellmarker.h"
#include
"Utils/vbo.h"
#include
"Topology/generic/attributeHandler.h"
#include
"Geometry/intersection.h"
#include
"Algo/Geometry/normal.h"
#include
<stdlib.h>
namespace
CGoGN
{
...
...
@@ -38,6 +43,263 @@ namespace Render
namespace
GL2
{
template
<
typename
PFP
>
void
MapRender
::
recompute2Ears
(
AttributeHandler
<
typename
PFP
::
VEC3
>&
position
,
VertexPoly
*
vp
,
const
typename
PFP
::
VEC3
&
normalPoly
,
std
::
multimap
<
float
,
VertexPoly
*>&
ears
,
bool
convex
)
{
VertexPoly
*
vprev
=
vp
->
prev
;
VertexPoly
*
vp2
=
vp
->
next
;
VertexPoly
*
vnext
=
vp2
->
next
;
const
typename
PFP
::
VEC3
&
Ta
=
position
[
vp
->
id
];
const
typename
PFP
::
VEC3
&
Tb
=
position
[
vp2
->
id
];
const
typename
PFP
::
VEC3
&
Tc
=
position
[
vprev
->
id
];
const
typename
PFP
::
VEC3
&
Td
=
position
[
vnext
->
id
];
// compute angle
typename
PFP
::
VEC3
v1
=
Tb
-
Ta
;
typename
PFP
::
VEC3
v2
=
Tc
-
Ta
;
typename
PFP
::
VEC3
v3
=
Td
-
Tb
;
v1
.
normalize
();
v2
.
normalize
();
v3
.
normalize
();
// from -1 for sharp angle to 1 for flat
float
dotpr1
=
1.0
f
-
(
v1
*
v2
);
typename
PFP
::
VEC3
nv1
=
v1
^
v2
;
float
dotpr2
=
1.0
f
+
(
v1
*
v3
);
typename
PFP
::
VEC3
nv2
=
v1
^
v3
;
if
(
nv1
*
normalPoly
<
0.0
)
dotpr1
=
10.0
f
-
dotpr1
;
// not an ears (concave)
if
(
nv2
*
normalPoly
<
0.0
)
dotpr2
=
10.0
f
-
dotpr2
;
// not an ears (concave)
if
((
!
convex
)
&&
(
dotpr1
<
5.0
f
)
&&
(
dotpr2
<
5.0
f
))
{
typename
PFP
::
VEC3
inter
;
Geom
::
Intersection
res
=
Geom
::
intersectionRayTriangle
<
typename
PFP
::
VEC3
>
(
Td
,
normalPoly
,
Ta
,
Tb
,
Tc
,
inter
);
if
(
res
>=
Geom
::
VERTEX_INTERSECTION
)
dotpr1
=
5.0
f
;
// not an ears !
VertexPoly
*
curr
=
vnext
->
next
;
bool
finished
=
false
;
while
((
!
finished
)
&&
(
curr
!=
vprev
))
{
if
(
curr
->
value
>=
5.0
f
)
{
const
typename
PFP
::
VEC3
&
P
=
position
[
curr
->
id
];
if
(
dotpr1
<
5.0
f
)
{
Geom
::
Intersection
res
=
Geom
::
intersectionRayTriangle
<
typename
PFP
::
VEC3
>
(
P
,
normalPoly
,
Ta
,
Tb
,
Tc
,
inter
);
if
(
res
>
Geom
::
VERTEX_INTERSECTION
)
dotpr1
=
5.0
f
;
}
if
(
dotpr2
<
5.0
f
)
{
Geom
::
Intersection
res
=
Geom
::
intersectionRayTriangle
<
typename
PFP
::
VEC3
>
(
P
,
normalPoly
,
Tb
,
Td
,
Ta
,
inter
);
if
(
res
>
Geom
::
VERTEX_INTERSECTION
)
dotpr2
=
5.0
f
;
// not an ears !
}
finished
=
((
dotpr1
==
5.0
f
)
&&
(
dotpr2
==
5.0
f
));
}
curr
=
curr
->
next
;
}
if
(
dotpr2
<
5.0
f
)
{
Geom
::
Intersection
res
=
Geom
::
intersectionRayTriangle
<
typename
PFP
::
VEC3
>
(
Tc
,
normalPoly
,
Tb
,
Td
,
Ta
,
inter
);
if
(
res
>
Geom
::
VERTEX_INTERSECTION
)
dotpr2
=
5.0
f
;
// not an ears !
}
// bool finished = false;
// for (std::multimap<float, VertexPoly*>::reverse_iterator it = ears.rbegin(); (!finished)&&(it != ears.rend()) ; ++it)
// { //&&(it->first > 5.0f
// if (it->first != it ->second->value) // use only valid ears
// {
// int id = it->second->id;
// if ((id != vp->id) && (id != vp2->id))
// {
// const typename PFP::VEC3& P = position[id];
// typename PFP::VEC3 inter;
// if ((id !=vprev->id) && (dotpr1 != 5.0f))
// if (Geom::intersectionRayTriangle<typename PFP::VEC3>(P, normalPoly, Ta,Tb,Tc, inter) != Geom::NO_INTERSECTION)
// dotpr1 = 5.0f;// not an ears !
// if ((id !=vnext->id) && (dotpr2 != 5.0f))
// if (Geom::intersectionRayTriangle<typename PFP::VEC3>(P, normalPoly, Tb,Td,Ta, inter) != Geom::NO_INTERSECTION)
// dotpr2 = 5.0f;// not an ears !
// }
// }
// finished = ((dotpr1 == 5.0f)&&(dotpr2 == 5.0f));
// }
}
vp
->
value
=
dotpr1
;
ears
.
insert
(
std
::
pair
<
float
,
VertexPoly
*>
(
dotpr1
,
vp
));
vp2
->
value
=
dotpr2
;
ears
.
insert
(
std
::
pair
<
float
,
VertexPoly
*>
(
dotpr2
,
vp2
));
}
template
<
typename
PFP
>
float
MapRender
::
computeEarAngle
(
AttributeHandler
<
typename
PFP
::
VEC3
>&
position
,
const
typename
PFP
::
VEC3
&
normalPoly
,
unsigned
int
i
,
unsigned
int
j
,
unsigned
int
k
)
{
// compute angle
typename
PFP
::
VEC3
v1
=
position
[
i
]
-
position
[
j
];
typename
PFP
::
VEC3
v2
=
position
[
k
]
-
position
[
j
];
v1
.
normalize
();
v2
.
normalize
();
float
dotpr
=
1.0
f
-
(
v1
*
v2
);
typename
PFP
::
VEC3
v3
=
v1
^
v2
;
if
(
v3
*
normalPoly
>
0.0
)
{
// not an ears (concave, store at the end for optimized use for intersections)
dotpr
=
10.0
f
-
dotpr
;
}
return
dotpr
;
}
template
<
typename
PFP
>
bool
MapRender
::
computeEarIntersection
(
AttributeHandler
<
typename
PFP
::
VEC3
>&
position
,
VertexPoly
*
vp
,
const
typename
PFP
::
VEC3
&
normalPoly
)
{
VertexPoly
*
endV
=
vp
->
prev
;
VertexPoly
*
curr
=
vp
->
next
;
const
typename
PFP
::
VEC3
&
Ta
=
position
[
vp
->
id
];
const
typename
PFP
::
VEC3
&
Tb
=
position
[
curr
->
id
];
const
typename
PFP
::
VEC3
&
Tc
=
position
[
endV
->
id
];
curr
=
curr
->
next
;
while
(
curr
!=
endV
)
{
typename
PFP
::
VEC3
inter
;
Geom
::
Intersection
res
=
Geom
::
intersectionRayTriangle
<
typename
PFP
::
VEC3
>
(
position
[
curr
->
id
],
normalPoly
,
Ta
,
Tb
,
Tc
,
inter
);
if
(
res
>
Geom
::
VERTEX_INTERSECTION
)
{
vp
->
value
=
5.0
f
;
// not an ears !
return
false
;
}
curr
=
curr
->
next
;
}
return
true
;
}
template
<
typename
PFP
>
inline
void
MapRender
::
addEarTri
(
typename
PFP
::
MAP
&
map
,
Dart
d
,
std
::
vector
<
GLuint
>&
tableIndices
)
{
std
::
multimap
<
float
,
VertexPoly
*
>
ears
;
AttributeHandler
<
typename
PFP
::
VEC3
>
position
=
map
.
template
getAttribute
<
typename
PFP
::
VEC3
>(
VERTEX
,
"position"
);
// compute normal to polygon
typename
PFP
::
VEC3
normalPoly
=
Algo
::
Geometry
::
newellNormal
<
PFP
>
(
map
,
d
,
position
);
// first pass create polygon in chained list witht angle computation
VertexPoly
*
vpp
=
NULL
;
VertexPoly
*
prem
=
NULL
;
unsigned
int
nbv
=
0
;
unsigned
int
nbe
=
0
;
Dart
a
=
d
;
Dart
b
=
map
.
phi1
(
a
);
Dart
c
=
map
.
phi1
(
b
);
do
{
float
val
=
computeEarAngle
<
PFP
>
(
position
,
normalPoly
,
map
.
getEmbedding
(
VERTEX
,
a
),
map
.
getEmbedding
(
VERTEX
,
b
),
map
.
getEmbedding
(
VERTEX
,
c
));
VertexPoly
*
vp
=
new
VertexPoly
(
map
.
getEmbedding
(
VERTEX
,
b
),
val
,
vpp
);
if
(
vp
->
value
<
5.0
f
)
nbe
++
;
if
(
vpp
==
NULL
)
prem
=
vp
;
vpp
=
vp
;
a
=
b
;
b
=
c
;
c
=
map
.
phi1
(
c
);
nbv
++
;
}
while
(
a
!=
d
);
VertexPoly
::
close
(
prem
,
vpp
);
bool
convex
=
nbe
==
nbv
;
if
(
convex
)
{
vpp
=
prem
;
for
(
unsigned
int
i
=
0
;
i
<
nbv
;
++
i
)
{
ears
.
insert
(
std
::
pair
<
float
,
VertexPoly
*
>
(
vpp
->
value
,
vpp
));
vpp
=
vpp
->
next
;
}
}
else
{
// second pass test intersection with polygons
vpp
=
prem
;
for
(
unsigned
int
i
=
0
;
i
<
nbv
;
++
i
)
{
if
(
vpp
->
value
<
5.0
f
)
{
computeEarIntersection
<
PFP
>
(
position
,
vpp
,
normalPoly
);
if
(
vpp
->
value
!=
5.0
f
)
ears
.
insert
(
std
::
pair
<
float
,
VertexPoly
*
>
(
vpp
->
value
,
vpp
));
}
else
ears
.
insert
(
std
::
pair
<
float
,
VertexPoly
*
>
(
vpp
->
value
,
vpp
));
vpp
=
vpp
->
next
;
}
}
// DBG: AFF ears
// for (std::multimap< float, VertexPoly* >::iterator it = ears.begin(); it != ears.end(); ++it )
// std::cout << it->first <<" , "<< it->second->id<<" , "<< it->second->value<< " / ";
// std::cout << std::endl;
// NO WE HAVE THE POLYGON AND EARS
// LET'S REMOVE THEM
while
(
nbv
>
3
)
{
// take best (and valid!) ear
std
::
multimap
<
float
,
VertexPoly
*
>::
iterator
be_it
=
ears
.
begin
();
// best ear is big value cos -> last in map
VertexPoly
*
be
=
be_it
->
second
;
while
(
be
->
value
!=
be_it
->
first
)
// test ear validiy (!= means recomputed: to be destroyed)
{
ears
.
erase
(
be_it
);
be_it
=
ears
.
begin
();
be
=
be_it
->
second
;
}
tableIndices
.
push_back
(
be
->
id
);
tableIndices
.
push_back
(
be
->
next
->
id
);
tableIndices
.
push_back
(
be
->
prev
->
id
);
//remove ears
ears
.
erase
(
be_it
);
// from map of ears
be
=
be
->
unlink
();
// and from polygon
nbv
--
;
if
(
nbv
>
3
)
// do not recompute if only one triangle left
recompute2Ears
<
PFP
>
(
position
,
be
,
normalPoly
,
ears
,
convex
);
else
// finish
{
tableIndices
.
push_back
(
be
->
id
);
tableIndices
.
push_back
(
be
->
next
->
id
);
// last triangle
tableIndices
.
push_back
(
be
->
prev
->
id
);
VertexPoly
::
erasePoly
(
be
);
// release memory of polygon
}
}
}
template
<
typename
PFP
>
inline
void
MapRender
::
addTri
(
typename
PFP
::
MAP
&
map
,
Dart
d
,
std
::
vector
<
GLuint
>&
tableIndices
)
{
...
...
@@ -45,6 +307,12 @@ inline void MapRender::addTri(typename PFP::MAP& map, Dart d, std::vector<GLuint
Dart
b
=
map
.
phi1
(
a
);
Dart
c
=
map
.
phi1
(
b
);
if
(
map
.
phi1
(
c
)
!=
a
)
{
addEarTri
<
PFP
>
(
map
,
d
,
tableIndices
);
//TODO version optimisee pour 4 cotes ?
return
;
}
// loop to cut a polygon in triangle on the fly (works only with convex faces)
do
{
...
...
src/Algo/Render/mapRender.cpp
View file @
c5958723
...
...
@@ -103,6 +103,40 @@ void MapRender::draw(Utils::GLSLShader* sh, int prim)
sh
->
disableVertexAttribs
();
}
unsigned
int
MapRender
::
drawSub
(
Utils
::
GLSLShader
*
sh
,
int
prim
,
unsigned
int
nb_elm
)
{
sh
->
enableVertexAttribs
();
switch
(
prim
)
{
case
POINTS
:
if
(
nb_elm
>
m_nbIndices
[
POINT_INDICES
])
nb_elm
=
m_nbIndices
[
POINT_INDICES
];
glBindBuffer
(
GL_ELEMENT_ARRAY_BUFFER
,
m_indexBuffers
[
POINT_INDICES
]);
glDrawElements
(
GL_POINTS
,
nb_elm
,
GL_UNSIGNED_INT
,
0
)
;
break
;
case
LINES
:
if
(
2
*
nb_elm
>
m_nbIndices
[
LINE_INDICES
])
nb_elm
=
m_nbIndices
[
LINE_INDICES
]
/
2
;
glBindBuffer
(
GL_ELEMENT_ARRAY_BUFFER
,
m_indexBuffers
[
LINE_INDICES
]);
glDrawElements
(
GL_LINES
,
2
*
nb_elm
,
GL_UNSIGNED_INT
,
0
);
break
;
case
TRIANGLES
:
if
(
3
*
nb_elm
>
m_nbIndices
[
TRIANGLE_INDICES
])
nb_elm
=
m_nbIndices
[
TRIANGLE_INDICES
]
/
3
;
glBindBuffer
(
GL_ELEMENT_ARRAY_BUFFER
,
m_indexBuffers
[
TRIANGLE_INDICES
]);
glDrawElements
(
GL_TRIANGLES
,
3
*
nb_elm
,
GL_UNSIGNED_INT
,
0
);
break
;
default:
break
;
}
sh
->
disableVertexAttribs
();
return
nb_elm
;
}
}
// namespace GL2
}
// namespace Render
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment