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
Etienne Schmitt
CGoGN
Commits
3526329c
Commit
3526329c
authored
Nov 16, 2011
by
David Cazier
Browse files
Mise a jour de tp_master
parent
c867b436
Changes
2
Hide whitespace changes
Inline
Side-by-side
Apps/Tuto/tp_master.cpp
View file @
3526329c
...
...
@@ -22,10 +22,6 @@
* *
*******************************************************************************/
#include
<iostream>
#include
<time.h>
#include
<algorithm>
#include
"tp_master.h"
#include
"Topology/generic/parameters.h"
...
...
@@ -48,167 +44,224 @@
#include
"Utils/drawer.h"
//
/
pour simplifier l'ecriture du code
// pour simplifier l'ecriture du code
using
namespace
CGoGN
;
/// definition de la structure qui decrit le type de carte utilise
// déclaration de la classe utilisée pour le TP
class
Map2TP
;
// definition de la structure qui decrit le type de carte utilise
struct
PFP
:
public
PFP_STANDARD
{
// definition of the map
typedef
Embedded
Map2
MAP
;
typedef
Map2
TP
MAP
;
};
// fonction qui renvoit vrai (pour sélectioner tous les brins)
SelectorTrue
allDarts
;
/// definition de la carte en global, plus facile
PFP
::
MAP
myMap
;
// handler d'attribut de position par sommet
AttributeHandler
<
PFP
::
VEC3
>
position
;
// handler d'attribut de normale par sommet
AttributeHandler
<
PFP
::
VEC3
>
normal
;
/// fonction qui renvoit vrai (appliquée à un brin)
//SelectorTrue allDarts;
/// encore 1 typedef pour simplifier l'ecriture du code
// typedef pour le plongement des sommets
typedef
PFP
::
VEC3
Point3D
;
/// pile des brins selectionnes (6 max)
std
::
vector
<
Dart
>
selected_darts
;
// Variables pour la gestion des plongements
// handler d'attribut de position par sommet
AttributeHandler
<
Point3D
>
position
;
// handler d'attribut de normale par sommet
AttributeHandler
<
PFP
::
VEC3
>
normal
;
/// 3 brins de la carte encore en global pour pouvoir utiliser le callback clavier de glut !
Dart
d_carre
;
Dart
d_tri
;
Dart
d_maison
;
///Fonctions a connaitre:
///
Fonctions a connaitre:
///
/// phi1(d), phi2(d) : evident ?
/// phi<21>(d) equivalent a phi2(phi1(d)), phi<121212> equivalent a ....
/// phi1(d), phi2(d) : les parcours topologiques
///
///
Creer un face: newOrientedFace(nb_cotes); renvoit un Dart
/// Creer un face: newOrientedFace(nb_cotes); renvoit un Dart
///
/// Fonction Carre: construit un carre et renvoit un brin
/// Creer un plongement de sommet :
/// Point3D P = Point3D(0.0f,0.0f,0.0f);
///
/// Lire le plongement d'un sommet (celui du brin d)
/// P = position[d];
///
/// Assigner un plongement à un sommet (celui du brin d)
/// embedVertex(d,P);
Dart
Carre
()
{
return
Dart
::
nil
();
}
/// Fonction Triangle: construit un triangle et renvoit un brin
Dart
Triangle
()
{
return
Dart
::
nil
();
}
/// Fonction Colle: effectue la couture du carre et du triangle, le carre ne bouge pas
/// Attention aux plongements des sommets topologiquement modifies
/// Fonction a utiliser: sewFaces(d,e): colle deux faces par d et e
/// appel clavier touche 'c'
void
Colle
(
Dart
d
,
Dart
e
)
{
}
/// Fonction Colle: effectue la couture du carre et du triangle, les points de l'arete commune
/// se placent a mi-chemin
/// appel clavier touche 'C'
void
ColleMilieu
(
Dart
d
,
Dart
e
)
{
}
/// Fonction qui construite une "maison" (un carré et un triangle collé)
/// faire la topologie puis plonger le tout
/// on renvoit le brin du carre qui est colle au triangle
/// Utiliser embedCell
Dart
Maison
()
{
return
Dart
::
nil
();
}
/// decouper le carre de la maison en 2 carre (un a gauche un a droite)
/// le triangle du haut devient un carre (de forme triangulaire
/// essayer de couper d'abord uniquement les arêtes pour voir ce qui se passe.
/// deplacer les deux nouveaux sommets
/// Fonctions à utiliser:
/// cutEdge(brin): coupe une arête en deux: *--- devient *---*---
/// cutFace(b1,b2): coupe une face en deux, la nouvelle arête relie les deux sommets portes par b1 et b2
///touche 'x' on selectionne les 2 aretes a couper
void
Decoupage
(
Dart
d
,
Dart
dd
)
class
Map2TP
:
public
Map2
{
}
private:
// 3 brins de la carte
Dart
d_carre
;
Dart
d_tri
;
Dart
d_multiFaces
;
// Assigne un nouveau plongement au sommet. Les anciens plongements sont libérés.
void
newVertex
(
Dart
d
)
{
embedNewCell
(
VERTEX
,
d
);
}
/// appliquer une homothetie a une face (0.95 par ex) a partir d'un brin
/// Attention on ne connait pas le nombre de cotes de face !!
/// Indice: 2 passes: calculer le centre, puis bouger les sommets
/// appel clavier touche 'r' pout le carre
/// appel clavier touche 'R' pout le triangle
void
Reduction
(
Dart
e
)
{
public:
// Fonction Carre: construit un carre et renvoit un brin
Dart
Carre
()
{
Point3D
P
[
4
];
P
[
0
]
=
Point3D
(
0.0
f
,
0.0
f
,
0.0
f
);
P
[
1
]
=
Point3D
(
1.0
f
,
0.0
f
,
0.0
f
);
P
[
2
]
=
Point3D
(
1.0
f
,
1.0
f
,
0.0
f
);
P
[
3
]
=
Point3D
(
0.0
f
,
1.0
f
,
0.0
f
);
return
NIL
;
}
}
// Fonction Triangle: construit un triangle et renvoit un brin
Dart
Triangle
()
{
Point3D
P
[
3
];
P
[
0
]
=
Point3D
(
0.0
f
,
1.1
f
,
0.0
f
);
P
[
1
]
=
Point3D
(
1.0
f
,
1.1
f
,
0.0
f
);
P
[
2
]
=
Point3D
(
0.5
f
,
2.0
f
,
0.0
f
);
return
NIL
;
}
/// faire touner une face !!!
/// chaque sommet avance vers le suivant
/// appel clavier touche 'T' pout le carre
/// appel clavier touche 'U' pout le triangle
// Construit un polygone de taille "size"
Dart
Polygone
(
Point3D
*
P
,
unsigned
size
)
{
return
NIL
;
}
// appel clavier touche 'c'
void
Colle
(
Dart
d
,
Dart
e
)
{
}
void
Tourne
(
Dart
d
)
{
// appel clavier touche 'm'
void
ColleMilieu
(
Dart
d
,
Dart
e
)
{
}
}
// Construit une figure
Dart
MultiFaces
()
{
Point3D
P
[
6
];
P
[
0
]
=
Point3D
(
2.0
f
,
0.0
f
,
0.0
f
);
P
[
1
]
=
Point3D
(
3.0
f
,
0.0
f
,
0.0
f
);
P
[
2
]
=
Point3D
(
3.5
f
,
1.0
f
,
0.0
f
);
P
[
3
]
=
Point3D
(
3.0
f
,
1.8
f
,
0.0
f
);
P
[
4
]
=
Point3D
(
2.0
f
,
1.8
f
,
0.0
f
);
P
[
5
]
=
Point3D
(
1.5
f
,
1.0
f
,
0.0
f
);
Dart
hexa
=
Polygone
(
P
,
6
);
Point3D
Q
[
3
];
Q
[
0
]
=
Point3D
(
2.0
f
,
2.0
f
,
0.0
f
);
Q
[
1
]
=
Point3D
(
3.0
f
,
2.0
f
,
0.0
f
);
Q
[
2
]
=
Point3D
(
2.5
f
,
3.0
f
,
0.0
f
);
Dart
triangle
=
Polygone
(
Q
,
3
);
Point3D
R
[
4
];
R
[
0
]
=
Point3D
(
4.0
f
,
0.0
f
,
0.0
f
);
R
[
1
]
=
Point3D
(
5.0
f
,
0.0
f
,
0.0
f
);
R
[
2
]
=
Point3D
(
5.0
f
,
1.0
f
,
0.0
f
);
R
[
3
]
=
Point3D
(
4.0
f
,
1.0
f
,
0.0
f
);
Dart
carre
=
Polygone
(
R
,
4
);
Point3D
S
[
3
];
S
[
0
]
=
Point3D
(
4.0
f
,
1.2
f
,
0.0
f
);
S
[
1
]
=
Point3D
(
5.0
f
,
1.2
f
,
0.0
f
);
S
[
2
]
=
Point3D
(
4.5
f
,
2.2
f
,
0.0
f
);
Dart
triangle2
=
Polygone
(
S
,
3
);
Dart
haut_carre
=
phi1
(
phi1
(
carre
));
Dart
hexa2
=
phi1
(
phi1
(
phi1
(
hexa
)));
// Test du phi1Sew
// myMap.phi1sew(hexa,hexa2);
// myMap.phi1sew(myMap.phi1(hexa),myMap.phi_1(carre));
// Génére un maillage à la fin
// Colle(haut_carre,triangle2);
// Colle(hexa2,triangle);
// Colle(phi_1(triangle2),phi_1(hexa2));
// Colle(phi1(hexa),phi_1(carre));
return
hexa
;
}
// Fonction de creation de la carte (appelee par le main)
void
createMap
()
{
d_carre
=
Carre
();
d_tri
=
Triangle
();
// d_multiFaces = MultiFaces();
// Colle(phi1(phi1(d_carre)),d_tri);
// Colle(phi_1(d_multiFaces),phi1(d_carre));
// Colle(phi_1(phi_1(d_multiFaces)),phi1(d_tri));
}
/// Fonction de creation de la carte (appelee par le main)
// Touche x
void
coupeFace
(
Dart
d
,
Dart
e
)
{
}
void
createMap
()
{
// d_carre = Carre();
// d_tri = Triangle();
// d_maison = Maison();
// Touche y
void
coupeArete
(
Dart
d
)
{
Point3D
p
=
position
[
d
];
Point3D
q
=
position
[
phi1
(
d
)];
Point3D
milieu
=
(
p
+
q
+
Point3D
(
0.2
f
,
0.2
f
,
0.0
f
)
/* decalage pour voir le point */
)
/
2
;
}
}
// Touche z
void
arrondi
(
Dart
d
)
{
Dart
e
=
phi_1
(
d
);
coupeArete
(
d
);
coupeArete
(
e
);
e
=
phi1
(
e
);
Point3D
P
=
position
[
d
];
Point3D
Q
=
position
[
e
];
Point3D
R
=
position
[
phi1
(
d
)];
Point3D
M
=
(
P
+
P
+
Q
+
R
)
/
4
;
position
[
d
]
=
M
;
}
unsigned
face_size
(
Dart
d
)
{
return
0
;
}
/
//
C
ou
pe une face carre en 2 en utilisant cutEdge et splitFace
/// splitFace(d1,d2): le suivant (phi1) de d1 devient celui de d2
/// et inversement: faire un dessin
//
T
ou
che p
void
triangule
()
{
}
void
coupe_carre
(
Dart
dd
)
{
// Touche q
void
fusionSommet
(
Dart
d
)
{
Point3D
P
=
position
[
d
];
Point3D
Q
=
position
[
phi1
(
d
)];
Point3D
M
=
(
P
+
Q
)
/
2
;
}
}
// Longueur d'une arête
double
longueur
(
Dart
d
)
{
Point3D
P
=
position
[
d
];
Point3D
Q
=
position
[
phi1
(
d
)];
Point3D
V
=
P
-
Q
;
return
V
.
norm
();
}
// Simplification touche k
void
simplifie
()
{
}
};
// definition de la carte comme variable globale
PFP
::
MAP
myMap
;
// pile des brins selectionnes (6 max)
std
::
vector
<
Dart
>
selected_darts
;
//
/
Variables pour le picking
// Variables pour le picking
(sélection de brins à la souris)
PFP
::
VEC3
rayA
;
PFP
::
VEC3
rayB
;
std
::
vector
<
PFP
::
VEC3
>
inters
;
...
...
@@ -216,8 +269,6 @@ std::vector<Dart> d_faces;
std
::
vector
<
Dart
>
d_edges
;
std
::
vector
<
Dart
>
d_vertices
;
void
MyQT
::
drawSelected
()
{
...
...
@@ -314,7 +365,6 @@ void MyQT::drawSelected()
}
void
MyQT
::
cb_initGL
()
{
// choose to use GL version 2
...
...
@@ -344,11 +394,20 @@ void MyQT::cb_initGL()
registerShader
(
m_shader2
);
}
void
MyQT
::
cb_redraw
()
{
// update des normales aux sommets
Algo
::
Geometry
::
computeNormalVertices
<
PFP
>
(
myMap
,
position
,
normal
)
;
// update du VBO position (contexte GL necessaire)
m_positionVBO
->
updateData
(
position
);
m_normalVBO
->
updateData
(
normal
);
// update des primitives du renderer
m_render
->
initPrimitives
<
PFP
>
(
myMap
,
allDarts
,
Algo
::
Render
::
GL2
::
TRIANGLES
);
m_render
->
initPrimitives
<
PFP
>
(
myMap
,
allDarts
,
Algo
::
Render
::
GL2
::
LINES
);
void
MyQT
::
cb_redraw
()
{
m_render_topo
->
updateData
<
PFP
>
(
myMap
,
position
,
0.9
f
,
0.9
f
);
drawSelected
();
if
(
renderTopo
)
...
...
@@ -381,65 +440,39 @@ void MyQT::cb_redraw()
void
MyQT
::
cb_keyPress
(
int
keycode
)
{
typedef
Dart
Dart
;
// coordonnées du clic et calcul du rayon dans l'espace 3D
int
x
,
y
;
glMousePosition
(
x
,
y
);
CGoGNout
<<
x
<<
" , "
<<
y
<<
CGoGNendl
;
float
dist
=
getOrthoScreenRay
(
x
,
y
,
rayA
,
rayB
);
PFP
::
VEC3
AB
=
rayB
-
rayA
;
// tableau de brins pour la sélection
std
::
vector
<
Dart
>
darts
;
switch
(
keycode
)
{
// Bascule affichage topologie - normal
case
't'
:
renderTopo
=
!
renderTopo
;
if
(
renderTopo
)
statusMsg
(
"Render Topology"
);
else
statusMsg
(
""
);
updateGL
();
break
;
// Oublie les brins sélectionnés
case
'0'
:
selected_darts
.
clear
();
statusMsg
(
"Cleanning selected darts"
);
updateGL
();
break
;
// Sélectionne un brin
case
'd'
:
{
if
(
selected_darts
.
size
()
>
5
)
{
statusMsg
(
"Already six darts selected"
);
break
;
}
/// calcul du rayon
getOrthoScreenRay
(
x
,
y
,
rayA
,
rayB
);
PFP
::
VEC3
AB
=
rayB
-
rayA
;
/// recuperation des faces intersectees
d_faces
.
clear
();
d_edges
.
clear
();
d_vertices
.
clear
();
std
::
vector
<
Dart
>
darts
;
Algo
::
Selection
::
dartsRaySelection
<
PFP
>
(
myMap
,
position
,
rayA
,
AB
,
darts
,
SelectorTrue
());
selected_darts
.
push_back
(
darts
[
0
]);
updateGL
();
if
(
!
darts
.
empty
()
&&
selected_darts
.
size
()
<
6
)
{
selected_darts
.
push_back
(
darts
[
0
]);
}
break
;
}
// Affiche les informations sur un brin
case
'D'
:
{
/// calcul du rayon
getOrthoScreenRay
(
x
,
y
,
rayA
,
rayB
);
PFP
::
VEC3
AB
=
rayB
-
rayA
;
/// recuperation des faces intersectees
d_faces
.
clear
();
d_edges
.
clear
();
d_vertices
.
clear
();
std
::
vector
<
Dart
>
darts
;
Algo
::
Selection
::
dartsRaySelection
<
PFP
>
(
myMap
,
position
,
rayA
,
AB
,
darts
,
SelectorTrue
());
if
(
!
darts
.
empty
())
...
...
@@ -449,47 +482,28 @@ void MyQT::cb_keyPress(int keycode)
Dart
d2
=
myMap
.
phi2
(
darts
[
0
]);
ss
<<
"dart:"
<<
darts
[
0
].
index
<<
" /phi1:"
<<
d1
.
index
<<
" /phi2:"
<<
d2
.
index
;
const
P
FP
::
VEC3
&
P
=
position
[
darts
[
0
]];
const
P
oint3D
&
P
=
position
[
darts
[
0
]];
ss
<<
" /Emb:"
<<
P
;
statusMsg
(
ss
.
str
().
c_str
());
}
break
;
}
// Sélectionne des faces
case
'f'
:
{
/// calcul du rayon
getOrthoScreenRay
(
x
,
y
,
rayA
,
rayB
);
PFP
::
VEC3
AB
=
rayB
-
rayA
;
/// recuperation des faces intersectees
d_faces
.
clear
();
d_edges
.
clear
();
d_vertices
.
clear
();
Algo
::
Selection
::
facesRaySelection
<
PFP
>
(
myMap
,
position
,
SelectorTrue
(),
rayA
,
AB
,
d_faces
);
if
(
!
d_faces
.
empty
())
{
std
::
stringstream
ss
;
ss
<<
"Face "
<<
d_faces
[
0
].
index
/
3
;
statusMsg
(
ss
.
str
().
c_str
());
updateGL
();
}
break
;
}
// Sélectionne des arêtes
case
'a'
:
{
/// calcul du rayon
float
dist
=
getOrthoScreenRay
(
x
,
y
,
rayA
,
rayB
);
PFP
::
VEC3
AB
=
rayB
-
rayA
;
d_faces
.
clear
();
d_edges
.
clear
();
d_vertices
.
clear
();
Algo
::
Selection
::
edgesRaySelection
<
PFP
>
(
myMap
,
position
,
SelectorTrue
(),
rayA
,
AB
,
d_edges
,
dist
);
if
(
!
d_edges
.
empty
())
...
...
@@ -500,22 +514,12 @@ void MyQT::cb_keyPress(int keycode)
if
(
dd
!=
d_edges
[
0
])
ss
<<
" phi2: "
<<
dd
.
index
<<
" phi1: "
<<
myMap
.
phi1
(
dd
).
index
;
statusMsg
(
ss
.
str
().
c_str
());
updateGL
();
}
break
;
}
// Sélectionne des sommets
case
's'
:
{
/// Rayon
float
dist
=
getOrthoScreenRay
(
x
,
y
,
rayA
,
rayB
);
PFP
::
VEC3
AB
=
rayB
-
rayA
;
d_faces
.
clear
();
d_edges
.
clear
();
d_vertices
.
clear
();
Algo
::
Selection
::
verticesRaySelection
<
PFP
>
(
myMap
,
position
,
rayA
,
AB
,
d_vertices
,
dist
,
SelectorTrue
());
if
(
!
d_vertices
.
empty
())
...
...
@@ -523,55 +527,71 @@ void MyQT::cb_keyPress(int keycode)
std
::
stringstream
ss
;
ss
<<
"Sommet: dart: "
<<
d_vertices
[
0
].
index
<<
": "
<<
position
[
d_vertices
[
0
]]
<<
"( id emb:"
<<
myMap
.
getEmbedding
(
VERTEX
,
d_vertices
[
0
])
<<
")"
<<
std
::
endl
;
;
statusMsg
(
ss
.
str
().
c_str
());
updateGL
();
}
break
;
}
case
'r'
:
if
(
!
selected_darts
.
empty
())
{
Reduction
(
selected_darts
[
0
]);
updateGL
();
}
break
;
case
'T'
:
if
(
!
selected_darts
.
empty
())
{
Tourne
(
selected_darts
[
0
]);
updateGL
();
}
break
;
// Opérations utilisant 2 brins
case
'c'
:
if
(
selected_darts
.
size
()
>=
2
)
case
'm'
:
case
'x'
:
if
(
selected_darts
.
size
()
>=
2
)
{
Colle
(
selected_darts
[
0
],
selected_darts
[
1
]);
updateGL
();
switch
(
keycode
)
{
// Colle 2 arêtes
case
'c'
:
myMap
.
Colle
(
selected_darts
[
0
],
selected_darts
[
1
]);
break
;
// Colle 2 arêtes en leur milieu
case
'm'
:
myMap
.
ColleMilieu
(
selected_darts
[
0
],
selected_darts
[
1
]);
break
;
// Coupe une face en 2 avec une nouvelle arête
case
'x'
:
myMap
.
coupeFace
(
selected_darts
[
0
],
selected_darts
[
1
]);
break
;
}
selected_darts
.
clear
();
}
break
;
case
'C'
:
if
(
selected_darts
.
size
()
>=
2
)
// Opérations utilisant un brin
case
'y'
:
case
'z'
:
case
'q'
:
if
(
selected_darts
.
size
()
>=
1
)
{
ColleMilieu
(
selected_darts
[
0
],
selected_darts
[
1
]);
updateGL
();
switch
(
keycode
)
{
// Coupe une arête en 2 avec un nouveau sommet
case
'y'
:
myMap
.
coupeArete
(
selected_darts
[
0
]);
break
;
// Arrondi
case
'z'
:
myMap
.
arrondi
(
selected_darts
[
0
]);
break
;
// Fusion de sommet
case
'q'
:
myMap
.
fusionSommet
(
selected_darts
[
0
]);
break
;
}
selected_darts
.
clear
();
}
break
;
case
'x'
:
if
(
selected_darts
.
size
()
>=
2
)