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

Mise a jour de tp_master

parent c867b436
......@@ -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 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
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.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 !!!
/// 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.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()
{
// 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.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
/// splitFace(d1,d2): le suivant (phi1) de d1 devient celui de d2
/// et inversement: faire un dessin
// Touche 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.9f, 0.9f);
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 PFP::VEC3& P = position[darts[0]];
const Point3D& 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]);
updateGL();
}
// Opérations globales
// Triangulation
case 'p':
myMap.triangule();
selected_darts.clear();
break;
// Simplification
case 'k':
myMap.simplifie();
selected_darts.clear();
break;
}
// Mise à jour de l'affichage
updateGL();
}
int main(int argc, char **argv)
......@@ -580,48 +600,32 @@ int main(int argc, char **argv)
QApplication app(argc, argv);
MyQT sqt;
if (argc == 2)
{
if (argc == 2) {
std::vector<std::string> attrNames ;
Algo::Import::importMesh<PFP>(myMap, argv[1], attrNames) ;
position = myMap.getAttribute<PFP::VEC3>(VERTEX, attrNames[0]) ;
position = myMap.getAttribute<Point3D>(VERTEX, attrNames[0]) ;
normal = myMap.addAttribute<PFP::VEC3>(VERTEX, "normal");
Algo::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
}
else
{
position = myMap.addAttribute<PFP::VEC3>(VERTEX, "position");
else {
position = myMap.addAttribute<Point3D>(VERTEX, "position");
normal = myMap.addAttribute<PFP::VEC3>(VERTEX, "normal");
createMap();
myMap.createMap();
Algo::Geometry::computeNormalVertices<PFP>(myMap, position, normal) ;
}
if (myMap.getNbDarts()==0)
if (myMap.getNbDarts()==0) {
CGoGNout << "Aucun brin dans la carte. Sortie ..." << CGoGNendl;
exit(0);
}
// caclul de la bounding box de la scene a afficher
Geom::BoundingBox<PFP::VEC3> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position);
float lWidthObj = std::max<PFP::REAL>(std::max<PFP::REAL>(bb.size(0), bb.size(1)), bb.size(2));
Geom::Vec3f lPosObj = (bb.min() + bb.max()) / PFP::REAL(2);
// envoit info BB a l'interface
// Parametre de la fenetre en fonction de la taille du maillage à afficher
Geom::BoundingBox<Point3D> bb = Algo::Geometry::computeBoundingBox<PFP>(myMap, position);
float lWidthObj = std::max(std::max(bb.size(0), bb.size(1)), bb.size(2));
Point3D lPosObj = (bb.min() + bb.max()) / 2;
sqt.setParamObject(lWidthObj,lPosObj.data());
// show 1 pour optenir le contexte GL
sqt.show();
// update du VBO position (contexte GL necessaire)
sqt.m_positionVBO->updateData(position);
sqt.m_normalVBO->updateData(normal);
// update des primitives du renderer
SelectorTrue allDarts;
sqt.m_render->initPrimitives<PFP>(myMap, allDarts, Algo::Render::GL2::TRIANGLES);
sqt.m_render->initPrimitives<PFP>(myMap, allDarts, Algo::Render::GL2::LINES);
sqt.m_render_topo->updateData<PFP>(myMap, position, 0.9f, 0.9f);
// show final pour premier redraw
// show pour optenir le contexte GL
sqt.show();
// et on attend la fin.
......
......@@ -105,6 +105,8 @@ SimpleQT::SimpleQT() :
m_dockConsole->hide();
m_transfo_matrix = glm::mat4(1.0f);
resize(1200,800);
}
SimpleQT::SimpleQT(const SimpleQT& sqt):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment