Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
CGoGN
CGoGN
Commits
92875e5f
Commit
92875e5f
authored
Nov 21, 2011
by
untereiner
Browse files
Options
Browse Files
Download
Plain Diff
Merge cgogn:~cgogn/CGoGN
parents
528fa5d8
3526329c
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
4777 additions
and
267 deletions
+4777
-267
Apps/Tuto/tp_master.cpp
Apps/Tuto/tp_master.cpp
+271
-267
bin/lapin.trian
bin/lapin.trian
+4504
-0
src/Utils/qtSimple.cpp
src/Utils/qtSimple.cpp
+2
-0
No files found.
Apps/Tuto/tp_master.cpp
View file @
92875e5f
...
...
@@ -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
)
{
Decoupage
(
selected_darts
[
0
],
selected_darts
[
1
]);