Commit 3526329c authored by David Cazier's avatar David Cazier

Mise a jour de tp_master

parent c867b436
...@@ -22,10 +22,6 @@ ...@@ -22,10 +22,6 @@
* * * *
*******************************************************************************/ *******************************************************************************/
#include <iostream>
#include <time.h>
#include <algorithm>
#include "tp_master.h" #include "tp_master.h"
#include "Topology/generic/parameters.h" #include "Topology/generic/parameters.h"
...@@ -48,167 +44,224 @@ ...@@ -48,167 +44,224 @@
#include "Utils/drawer.h" #include "Utils/drawer.h"
/// pour simplifier l'ecriture du code // pour simplifier l'ecriture du code
using namespace CGoGN; 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 struct PFP: public PFP_STANDARD
{ {
// definition of the map // definition of the map
typedef EmbeddedMap2 MAP; typedef Map2TP MAP;
}; };
// fonction qui renvoit vrai (pour sélectioner tous les brins)
SelectorTrue allDarts;
/// definition de la carte en global, plus facile // typedef pour le plongement des sommets
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 PFP::VEC3 Point3D; typedef PFP::VEC3 Point3D;
/// pile des brins selectionnes (6 max) // Variables pour la gestion des plongements
std::vector<Dart> selected_darts; // 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 ? /// phi1(d), phi2(d) : les parcours topologiques
/// phi<21>(d) equivalent a phi2(phi1(d)), phi<121212> equivalent a ....
/// ///
/// Creer un face: newOrientedFace(nb_cotes); renvoit un Dart /// Creer un face: newOrientedFace(nb_cotes); renvoit un Dart
/// ///
/// Creer un plongement de sommet :
/// Point3D P = Point3D(0.0f,0.0f,0.0f);
/// Fonction Carre: construit un carre et renvoit un brin
/// ///
/// 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() class Map2TP : public Map2
{
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)
{ {
} 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 public:
/// Attention on ne connait pas le nombre de cotes de face !! // Fonction Carre: construit un carre et renvoit un brin
/// Indice: 2 passes: calculer le centre, puis bouger les sommets Dart Carre()
/// appel clavier touche 'r' pout le carre {
/// appel clavier touche 'R' pout le triangle Point3D P[4];
void Reduction(Dart e) P[0] = Point3D(0.0f,0.0f,0.0f);
{ P[1] = Point3D(1.0f,0.0f,0.0f);
P[2] = Point3D(1.0f,1.0f,0.0f);
P[3] = Point3D(0.0f,1.0f,0.0f);
return NIL;
}
} // Fonction Triangle: construit un triangle et renvoit un brin
Dart Triangle()
{
Point3D P[3];
P[0] = Point3D(0.0f,1.1f,0.0f);
P[1] = Point3D(1.0f,1.1f,0.0f);
P[2] = Point3D(0.5f,2.0f,0.0f);
return NIL;
}
/// faire touner une face !!! // Construit un polygone de taille "size"
/// chaque sommet avance vers le suivant Dart Polygone(Point3D* P, unsigned size)
/// appel clavier touche 'T' pout le carre {
/// appel clavier touche 'U' pout le triangle 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.0f,0.0f,0.0f);
P[1] = Point3D(3.0f,0.0f,0.0f);
P[2] = Point3D(3.5f,1.0f,0.0f);
P[3] = Point3D(3.0f,1.8f,0.0f);
P[4] = Point3D(2.0f,1.8f,0.0f);
P[5] = Point3D(1.5f,1.0f,0.0f);
Dart hexa = Polygone(P,6);
Point3D Q[3];
Q[0] = Point3D(2.0f,2.0f,0.0f);
Q[1] = Point3D(3.0f,2.0f,0.0f);
Q[2] = Point3D(2.5f,3.0f,0.0f);
Dart triangle = Polygone(Q,3);
Point3D R[4];
R[0] = Point3D(4.0f,0.0f,0.0f);
R[1] = Point3D(5.0f,0.0f,0.0f);
R[2] = Point3D(5.0f,1.0f,0.0f);
R[3] = Point3D(4.0f,1.0f,0.0f);
Dart carre = Polygone(R,4);
Point3D S[3];
S[0] = Point3D(4.0f,1.2f,0.0f);
S[1] = Point3D(5.0f,1.2f,0.0f);
S[2] = Point3D(4.5f,2.2f,0.0f);
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() // Touche y
{ void coupeArete(Dart d) {
// d_carre = Carre(); Point3D p = position[d];
// d_tri = Triangle(); Point3D q = position[phi1(d)];
// d_maison = Maison(); Point3D milieu = (p + q + Point3D(0.2f,0.2f,0.0f) /* 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;
}
/// Coupe une face carre en 2 en utilisant cutEdge et splitFace // Touche p
/// splitFace(d1,d2): le suivant (phi1) de d1 devient celui de d2 void triangule() {
/// et inversement: faire un dessin }
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 rayA;
PFP::VEC3 rayB; PFP::VEC3 rayB;
std::vector<PFP::VEC3> inters; std::vector<PFP::VEC3> inters;
...@@ -216,8 +269,6 @@ std::vector<Dart> d_faces; ...@@ -216,8 +269,6 @@ std::vector<Dart> d_faces;
std::vector<Dart> d_edges; std::vector<Dart> d_edges;
std::vector<Dart> d_vertices; std::vector<Dart> d_vertices;
void MyQT::drawSelected() void MyQT::drawSelected()
{ {
...@@ -314,7 +365,6 @@ void MyQT::drawSelected() ...@@ -314,7 +365,6 @@ void MyQT::drawSelected()
} }
void MyQT::cb_initGL() void MyQT::cb_initGL()
{ {
// choose to use GL version 2 // choose to use GL version 2
...@@ -344,11 +394,20 @@ void MyQT::cb_initGL() ...@@ -344,11 +394,20 @@ void MyQT::cb_initGL()
registerShader(m_shader2); 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.9f, 0.9f);
{
drawSelected(); drawSelected();
if (renderTopo) if (renderTopo)
...@@ -381,65 +440,39 @@ void MyQT::cb_redraw() ...@@ -381,65 +440,39 @@ void MyQT::cb_redraw()
void MyQT::cb_keyPress(int keycode) void MyQT::cb_keyPress(int keycode)
{ {
typedef Dart Dart; // coordonnées du clic et calcul du rayon dans l'espace 3D
int x,y; int x,y;
glMousePosition(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) switch(keycode)
{ {
// Bascule affichage topologie - normal
case 't': case 't':
renderTopo = !renderTopo; renderTopo = !renderTopo;
if (renderTopo)
statusMsg("Render Topology");
else
statusMsg("");
updateGL();
break; break;
// Oublie les brins sélectionnés
case '0': case '0':
selected_darts.clear(); selected_darts.clear();
statusMsg("Cleanning selected darts");
updateGL();
break; break;
// Sélectionne un brin
case 'd': 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()); 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; break;
}
// Affiche les informations sur un brin
case 'D': 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()); Algo::Selection::dartsRaySelection<PFP>(myMap, position, rayA, AB, darts, SelectorTrue());
if (!darts.empty()) if (!darts.empty())
...@@ -449,47 +482,28 @@ void MyQT::cb_keyPress(int keycode) ...@@ -449,47 +482,28 @@ void MyQT::cb_keyPress(int keycode)
Dart d2 = myMap.phi2(darts[0]); Dart d2 = myMap.phi2(darts[0]);
ss << "dart:" << darts[0].index<<" /phi1:"<< d1.index<<" /phi2:"<< d2.index; ss << "dart:" << darts[0].index<<" /phi1:"<< d1.index<<" /phi2:"<< d2.index;
const PFP::VEC3& P = position[darts[0]]; const Point3D& P = position[darts[0]];
ss << " /Emb:" << P; ss << " /Emb:" << P;
statusMsg(ss.str().c_str()); statusMsg(ss.str().c_str());
} }
break; break;
}
// Sélectionne des faces
case 'f': case 'f':
{
/// calcul du rayon
getOrthoScreenRay(x,y,rayA,rayB);
PFP::VEC3 AB = rayB-rayA;
/// recuperation des faces intersectees
d_faces.clear(); d_faces.clear();
d_edges.clear();
d_vertices.clear();
Algo::Selection:: facesRaySelection<PFP>(myMap, position, SelectorTrue(), rayA, AB, d_faces); Algo::Selection:: facesRaySelection<PFP>(myMap, position, SelectorTrue(), rayA, AB, d_faces);
if (!d_faces.empty()) if (!d_faces.empty())
{ {
std::stringstream ss; std::stringstream ss;
ss << "Face " << d_faces[0].index/3; ss << "Face " << d_faces[0].index/3;
statusMsg(ss.str().c_str()); statusMsg(ss.str().c_str());
updateGL();
} }
break; break;
}
// Sélectionne des arêtes
case 'a': case 'a':
{
/// calcul du rayon
float dist = getOrthoScreenRay(x,y,rayA,rayB);
PFP::VEC3 AB = rayB-rayA;
d_faces.clear();
d_edges.clear(); d_edges.clear();
d_vertices.clear();
Algo::Selection::edgesRaySelection<PFP>(myMap, position, SelectorTrue(), rayA, AB, d_edges,dist); Algo::Selection::edgesRaySelection<PFP>(myMap, position, SelectorTrue(), rayA, AB, d_edges,dist);
if (!d_edges.empty()) if (!d_edges.empty())
...@@ -500,22 +514,12 @@ void MyQT::cb_keyPress(int keycode) ...@@ -500,22 +514,12 @@ void MyQT::cb_keyPress(int keycode)
if (dd != d_edges[0]) if (dd != d_edges[0])
ss << " phi2: " << dd.index<<" phi1: "<< myMap.phi1(dd).index; ss << " phi2: " << dd.index<<" phi1: "<< myMap.phi1(dd).index;
statusMsg(ss.str().c_str()); statusMsg(ss.str().c_str());
updateGL();
} }
break; break;
}
// Sélectionne des sommets
case 's': case 's':
{
/// Rayon
float dist = getOrthoScreenRay(x,y,rayA,rayB);
PFP::VEC3 AB = rayB-rayA;
d_faces.clear();
d_edges.clear();
d_vertices.clear(); d_vertices.clear();
Algo::Selection::verticesRaySelection<PFP>(myMap, position,rayA, AB, d_vertices,dist,SelectorTrue()); Algo::Selection::verticesRaySelection<PFP>(myMap, position,rayA, AB, d_vertices,dist,SelectorTrue());
if (!d_vertices.empty()) if (!d_vertices.empty())
...@@ -523,55 +527,71 @@ void MyQT::cb_keyPress(int keycode) ...@@ -523,55 +527,71 @@ void MyQT::cb_keyPress(int keycode)
std::stringstream ss; std::stringstream ss;
ss << "Sommet: dart: " << d_vertices[0].index << ": " << position[d_vertices[0]]<< "( id emb:"<< myMap.getEmbedding(VERTEX,d_vertices[0])<<")"<< std::endl; ; 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()); 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; break;
// Opérations utilisant 2 brins
case 'c': case 'c':
case 'm':
if (selected_darts.size()>=2) case 'x':
if (selected_darts.size() >= 2)
{ {
Colle(selected_darts[0], selected_darts[1]); switch (keycode) {
updateGL(); // 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;