opengl.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. #include "opengl.h"
  2. vf_model *model;
  3. double longdiag3d,longdiag2d,largeur,hauteur,ratiomodel;
  4. hashtable *table;
  5. int recharge,width,height;
  6. GLdouble *vertices;
  7. GLint *indices_face,*indices_arete;
  8. int size_vertices,size_indices_face,size_indices_arete;
  9. vector3d *normal;
  10. double radius;
  11. char* nomfic;
  12. /*VARIABLE POUR LE BPA*/
  13. bpa_edge *e;
  14. int sigma_k,sigma_i,sigma_j,*listused=NULL,sizeused=0;
  15. bpa_fronts *fronts=NULL;
  16. point3d centre;
  17. point3d pmin,pmax;
  18. int nbpartX,nbpartY,nbpartZ;
  19. space_partition *sp;
  20. void
  21. init (int argc, char **argv)
  22. {
  23. double vpx,vpy,vpz;
  24. GLfloat mat[]= {COUL_LUMIERE, 1.0f};
  25. GLfloat ambientlight[]={COUL_LUMIERE_AMBIENT,1.0f};
  26. GLfloat diffuselight[]={COUL_LUMIERE_DIFFUSE,1.0f};
  27. GLfloat specularlight[]={COUL_LUMIERE_SPECULAR,1.0f};
  28. GLfloat position[4];
  29. glutInit (&argc, argv);
  30. glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  31. glutInitWindowSize (WIDTH*2, HEIGHT*2);
  32. width=WIDTH;
  33. height=HEIGHT;
  34. glutInitWindowPosition (800, 25);
  35. glutCreateWindow ("titre_de_la_fenetre");
  36. glClearColor (255.0, 255.0, 255.0, 0.0);
  37. glEnable(GL_DEPTH_TEST);
  38. glCullFace(GL_BACK);
  39. glEnable(GL_CULL_FACE);
  40. /*glEnable(GL_LIGHTING);
  41. glEnable(GL_LIGHT0);*/
  42. glShadeModel(GL_SMOOTH);
  43. vpx=model->xmin;
  44. vpy=model->ymin;
  45. if(model->zmax!=0)
  46. vpz=model->zmax*1.5+zoom;
  47. else
  48. vpz=70;
  49. position[0]=vpx;position[1]=vpy;position[2]=vpz;position[3]=1.0;
  50. if(model->zmax<0)
  51. position[2]*=-1.0;
  52. glLightfv(GL_LIGHT0, GL_AMBIENT, ambientlight);
  53. glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuselight);
  54. glLightfv(GL_LIGHT0, GL_SPECULAR, specularlight);
  55. glLightfv(GL_LIGHT0, GL_POSITION, position);
  56. glMaterialfv (GL_FRONT, GL_AMBIENT, mat);
  57. glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
  58. glMaterialfv (GL_FRONT, GL_SPECULAR, mat);
  59. glViewport (0, 0, (GLsizei)WIDTH, (GLsizei)HEIGHT);
  60. }
  61. void
  62. camera_positionner_tourner()
  63. {
  64. glScalef(zoom,zoom,1.0);
  65. glTranslatef(tx,ty,0);
  66. glTranslatef((model->xmin+model->xmax)/2.0,
  67. (model->ymin+model->ymax)/2.0,
  68. (model->zmin+model->zmax)/2.0);
  69. glRotatef(angle,0.0,1.0,0.0);
  70. glRotatef(angle2,1.0,0.0,0.0);
  71. glTranslatef(-(model->xmin+model->xmax)/2.0,
  72. -(model->ymin+model->ymax)/2.0,
  73. -(model->zmin+model->zmax)/2.0);
  74. }
  75. void
  76. liste_arete(int key, vf_edge *value, void* user_data)
  77. {
  78. user_data=NULL;
  79. key=0;
  80. list_int_add(&indices_arete,&size_indices_arete,value->ve1,WITH_REDUNDANCE);
  81. list_int_add(&indices_arete,&size_indices_arete,value->ve2,WITH_REDUNDANCE);
  82. }
  83. void
  84. display_triangle()
  85. {
  86. glPolygonMode(GL_FRONT, GL_FILL);
  87. if(recharge)
  88. {
  89. // on ne rechage le tableau de sommets, d'arete et de faces
  90. // qu'au premier affichage ou si les sommets/artetes ou faces
  91. // ont été modifiés. ne pas oublier de mettre la variable recharge
  92. // à 1 à l'endroit où les modifications sont faites...
  93. //
  94. // on peut meme faire mieux ! si on ne fait que de la translation
  95. // de sommets, on peut répercuter les modifications directement
  96. // dans le tableau concerné sans tout recharger.
  97. //
  98. // par contre si on supprimer un sommet ou une face, la il faut tout recharger !
  99. free(vertices);
  100. free(indices_face);
  101. free(indices_arete);
  102. vertices=NULL;
  103. indices_face=NULL;
  104. indices_arete=NULL;
  105. size_vertices=0;
  106. size_indices_face=0;
  107. size_indices_arete=0;
  108. vertices=(double*)malloc(3*model->nbvertex*sizeof(double));
  109. for(int i=0;i<model->nbvertex;i++)
  110. {
  111. /*list_double_add(&vertices,&size_vertices,model->ve[i].x,WITH_REDUNDANCE);
  112. list_double_add(&vertices,&size_vertices,model->ve[i].y,WITH_REDUNDANCE);
  113. list_double_add(&vertices,&size_vertices,model->ve[i].z,WITH_REDUNDANCE);*/
  114. vertices[i*3]=model->ve[i].x;
  115. vertices[i*3+1]=model->ve[i].y;
  116. vertices[i*3+2]=model->ve[i].z;
  117. }
  118. indices_face=(int*)malloc(3*model->nbface*sizeof(int));
  119. for(int i=0;i<model->nbface;i++)
  120. {
  121. /*list_int_add(&indices_face,&size_indices_face,model->fa[i].ve1,WITH_REDUNDANCE);
  122. list_int_add(&indices_face,&size_indices_face,model->fa[i].ve2,WITH_REDUNDANCE);
  123. list_int_add(&indices_face,&size_indices_face,model->fa[i].ve3,WITH_REDUNDANCE);*/
  124. indices_face[i*3]=model->fa[i].ve1;
  125. indices_face[i*3+1]=model->fa[i].ve2;
  126. indices_face[i*3+2]=model->fa[i].ve3;
  127. }
  128. size_indices_face=model->nbface*3;
  129. hashtable_free(table);
  130. free(table);
  131. table=NULL;
  132. table=a2ri_vf_construction_edge_table(model,NULL,0);
  133. hashtable_foreach(table,liste_arete,NULL);
  134. recharge=0;
  135. }
  136. //affichage des polygones
  137. glColor4f(COUL_TRIANGLE, 1.0f);
  138. glEnable(GL_POLYGON_OFFSET_FILL);
  139. glPolygonOffset(1.0, 1.0);
  140. glEnableClientState(GL_VERTEX_ARRAY);
  141. glVertexPointer(3, GL_DOUBLE, 0, vertices);
  142. glDrawElements(GL_TRIANGLES, size_indices_face , GL_UNSIGNED_INT, indices_face);
  143. glDisableClientState(GL_VERTEX_ARRAY);
  144. glDisable(GL_POLYGON_OFFSET_FILL);
  145. //affichage des aretes
  146. glColor4f(COUL_ARETE, 1.0f);
  147. glPolygonMode(GL_FRONT, GL_LINE);
  148. glLineWidth(0.5);
  149. glEnableClientState(GL_VERTEX_ARRAY);
  150. glVertexPointer(3, GL_DOUBLE, 0, vertices);
  151. glDrawElements(GL_LINES, size_indices_arete , GL_UNSIGNED_INT, indices_arete);
  152. glDisableClientState(GL_VERTEX_ARRAY);
  153. //affichage des sommets
  154. glColor4f(COUL_POINT, 1.0f);
  155. glPointSize(4.0);
  156. glBegin(GL_POINTS);
  157. for(int i=0;i<model->nbvertex;i++)
  158. glVertex3f(model->ve[i].x,model->ve[i].y,model->ve[i].z);
  159. glEnd();
  160. /*glColor4f(0.0,0.0,1.0, 1.0f);
  161. glLineWidth(1);
  162. glBegin(GL_LINES);
  163. for(int i=0;i<model->nbvertex;i++)
  164. {
  165. glVertex3f(model->ve[i].x,model->ve[i].y,model->ve[i].z);
  166. glVertex3f(model->ve[i].x+normal[i].dx,model->ve[i].y+normal[i].dy,model->ve[i].z+normal[i].dz);
  167. }
  168. glEnd();*/
  169. glColor4f(0.0,1.0,0.0, 1.0f);
  170. if(e!=NULL)
  171. {
  172. glTranslatef(e->cijo.x,e->cijo.y,e->cijo.z);
  173. glutSolidSphere(radius,10,10);
  174. glTranslatef(-e->cijo.x,-e->cijo.y,-e->cijo.z);
  175. }
  176. glFlush();
  177. }
  178. void mouse(int button, int state, int x, int y)
  179. {
  180. if(button==GLUT_WHEEL_MOUSE_UP)
  181. {
  182. zoom*=1.1;
  183. glutPostRedisplay();
  184. return;
  185. }
  186. if(button==GLUT_WHEEL_MOUSE_DOWN)
  187. {
  188. zoom/=1.1;
  189. glutPostRedisplay();
  190. return ;
  191. }
  192. if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
  193. {
  194. rotation=1;
  195. initx=x;
  196. inity=y;
  197. }
  198. if(button==GLUT_LEFT_BUTTON && state==GLUT_UP)
  199. rotation=0;
  200. if(button==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)
  201. {
  202. translation=1;
  203. initx=x;
  204. inity=y;
  205. }
  206. if(button==GLUT_RIGHT_BUTTON && state==GLUT_UP)
  207. translation=0;
  208. }
  209. void motion(int x, int y)
  210. {
  211. if(rotation)
  212. {
  213. angle+=(x-initx)*0.5;
  214. angle2+=(y-inity)*0.5;
  215. initx=x;
  216. inity=y;
  217. glutPostRedisplay();
  218. }
  219. if(translation)
  220. {
  221. tx+=(x-initx)*0.001*longdiag2d/zoom;
  222. ty-=(y-inity)*0.001*longdiag2d/zoom;
  223. initx=x;
  224. inity=y;
  225. glutPostRedisplay();
  226. }
  227. }
  228. void display()
  229. {
  230. glClearColor(255.0,255.0,255.0,0.0);
  231. glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
  232. glMatrixMode(GL_MODELVIEW);
  233. glLoadIdentity();
  234. camera_positionner_tourner();
  235. display_triangle();
  236. glutSwapBuffers();
  237. }
  238. void reshape(int w, int h)
  239. {
  240. ratiomodel=largeur/hauteur;
  241. ratioecran=(w*1.0)/(h*1.0);
  242. width=w;
  243. height=h;
  244. glViewport(0, 0, w, h);
  245. glMatrixMode(GL_PROJECTION);
  246. glLoadIdentity();
  247. if(ratioecran>ratiomodel)
  248. glOrtho(model->xmin-(((ratioecran*hauteur)-largeur)/2.0)-(longdiag2d/20.0),model->xmax+(((ratioecran*hauteur)-largeur)/2.0)+(longdiag2d/20.0),
  249. model->ymin-(longdiag2d/20.0),model->ymax+(longdiag2d/20.0),
  250. model->zmin-longdiag3d,model->zmax+longdiag3d);
  251. else
  252. glOrtho(model->xmin-(longdiag2d/20.0),model->xmax+(longdiag2d/20.0),
  253. model->ymin-(((largeur/ratioecran)-hauteur)/2.0)-(longdiag2d/20.0),model->ymax+(((largeur/ratioecran)-hauteur)/2.0)+(longdiag2d/20.0),
  254. model->zmin-longdiag3d,model->zmax+longdiag3d);
  255. glMatrixMode(GL_MODELVIEW);
  256. glLoadIdentity();
  257. camera_positionner_tourner();
  258. glutPostRedisplay();
  259. }
  260. void
  261. exitFunc ()
  262. {
  263. hashtable_free(table);
  264. free(table);
  265. a2ri_vf_free(model);
  266. exit(EXIT_SUCCESS);
  267. }
  268. void a2ri_bpa_step()
  269. {
  270. e=a2ri_bpa_get_active_edge_in_fronts(fronts);
  271. if(e!=NULL)
  272. {
  273. a2ri_bpa_ball_pivot(model,sp,normal,radius,e,listused,sizeused,fronts,&sigma_k,&centre);
  274. if(sigma_k!=-1)
  275. {
  276. list_int_add(&listused,&sizeused,sigma_k,WITH_REDUNDANCE);
  277. //printf("Ajout triangle %d : %d %d %d par pivot\n",model->nbface,e->sigma_i,sigma_k,e->sigma_j);
  278. a2ri_vf_add_face(model,e->sigma_i,sigma_k,e->sigma_j);
  279. sigma_i=e->sigma_i;sigma_j=e->sigma_j;
  280. //a2ri_bpa_display_fronts(fronts);
  281. a2ri_bpa_join(&e,sigma_k,centre);
  282. //a2ri_bpa_display_fronts(fronts);
  283. a2ri_bpa_regularization(&fronts,sigma_i,sigma_j,sigma_k);
  284. //a2ri_bpa_display_fronts(fronts);
  285. e=(bpa_edge*)malloc(sizeof(bpa_edge));
  286. e->sigma_i=sigma_i;e->sigma_j=sigma_j;e->cijo=centre;
  287. }
  288. else
  289. {
  290. e->state=BOUNDARY;
  291. //printf("arete frontiere %d %d\n",e->sigma_i,e->sigma_j);
  292. }
  293. //a2ri_bpa_display_fronts(fronts);
  294. }
  295. else
  296. {
  297. if(a2ri_bpa_find_seed_triangle(model,sp,normal,radius,listused,sizeused,&sigma_i,&sigma_j,&sigma_k,&centre,0))
  298. {
  299. e=(bpa_edge*)malloc(sizeof(bpa_edge));
  300. e->sigma_i=sigma_i;e->sigma_j=sigma_j;e->cijo=centre;
  301. //printf("Ajout triangle %d : %d %d %d par seed triangle\n",model->nbface,sigma_i,sigma_j,sigma_k);
  302. a2ri_vf_add_face(model,sigma_i,sigma_j,sigma_k);
  303. a2ri_bpa_free_fronts(&fronts);
  304. fronts=NULL;
  305. a2ri_bpa_new_front(&fronts,sigma_i,sigma_j,sigma_k,centre);
  306. //a2ri_bpa_display_fronts(fronts);
  307. list_int_add(&listused,&sizeused,sigma_i,WITH_REDUNDANCE);
  308. list_int_add(&listused,&sizeused,sigma_j,WITH_REDUNDANCE);
  309. list_int_add(&listused,&sizeused,sigma_k,WITH_REDUNDANCE);
  310. }
  311. else
  312. {
  313. printf("plus de nouveau triangle trouve...\n");
  314. return;
  315. }
  316. }
  317. //a2ri_bpa_display_fronts(fronts);
  318. //printf("\n\n");
  319. recharge=1;
  320. return;
  321. }
  322. void keyboard(unsigned char key, int x, int y)
  323. {
  324. FILE *screenshot;
  325. unsigned short *pixels=NULL;
  326. char nom_fichier[100];
  327. double min,max,moyenne,sd;
  328. bpa_fronts *temp1;
  329. int *temp2, temp3;
  330. x=0;
  331. y=0;
  332. switch (key)
  333. {
  334. //touche entrée
  335. case 13:
  336. pixels=(unsigned short*)malloc(width*height*3*sizeof(unsigned short));
  337. glReadPixels(0,0,width,height,GL_RGB,GL_UNSIGNED_SHORT,pixels);
  338. printf("entrer le nom du fichier (sans extension) : ");
  339. a2ri_erreur_critique_si(!scanf("%s",nom_fichier),"erreur nom fichier\n");
  340. sprintf(nom_fichier,"%s.ppm",nom_fichier);
  341. screenshot=fopen(nom_fichier,"w");
  342. fprintf(screenshot,"P3\n %d %d\n65535\n",width,height);
  343. for(int j=height-1;j>=0;j--)
  344. for(int i=0;i<width;i++)
  345. fprintf(screenshot,"%d %d %d ",pixels[(j*width+i)*3],pixels[(j*width+i)*3+1],pixels[(j*width+i)*3+2]);
  346. fclose(screenshot);
  347. break;
  348. //touche TAB
  349. case 't':
  350. case'T':
  351. a2ri_vf_bpa(model,normal,radius);
  352. a2ri_vf_save_file(nomfic,model);
  353. recharge=1;
  354. break;
  355. case 9:
  356. a2ri_bpa_step();
  357. break;
  358. case 'r':
  359. glutPostRedisplay();
  360. break;
  361. case 'f':
  362. a2ri_bpa_display_fronts(fronts);
  363. break;
  364. case 'p':
  365. a2ri_bpa_average_radius_suggestion(model,&min,&max,&moyenne,&sd);
  366. printf("rayon propose :\nmin : %lf - max : %lf - moyenne : %lf - ecart-type : %lf\n",min,max,moyenne,sd);
  367. radius=moyenne;
  368. printf("Le rayon de la boule a ete modifiee. rayon = %lf\n",radius);
  369. break;
  370. case 'h':
  371. a2ri_bpa_initialisation(model,&temp1,&temp2,&temp3);
  372. break;
  373. case 's':
  374. case 'S':
  375. a2ri_vf_save_file(nomfic,model);
  376. break;
  377. //touche echap
  378. case 27:
  379. case 'q':
  380. case 'Q':
  381. exitFunc();
  382. break;
  383. }
  384. glutPostRedisplay();
  385. }
  386. int go(int argc, char** argv, vf_model * b, double my_radius, char* ficsave)
  387. {
  388. point3d ptmin,ptmax,infgauche,supgauche,infdroit;
  389. printf("radius : %lf\n",my_radius);
  390. //a2ri_bpa_initialisation(&b);
  391. recharge=1;
  392. vertices=NULL;
  393. indices_face=NULL;
  394. indices_arete=NULL;
  395. size_vertices=0;
  396. size_indices_face=0;
  397. size_indices_arete=0;
  398. /*vector3d trans;
  399. vector3d_init(&trans,0.5,0.5,0.5);*/
  400. model=b;
  401. radius=my_radius;
  402. nomfic=ficsave;
  403. table=a2ri_vf_construction_edge_table(model,NULL,0);
  404. if(model->nbface!=0)
  405. {
  406. /*Calcul des normales aux sommets*/
  407. normal=(vector3d*)malloc(model->nbvertex*sizeof(vector3d));
  408. for(int i=0;i<model->nbvertex;i++)
  409. {
  410. normal[i]=a2ri_vf_normal_vertex_with_hashtable(model,i,table);
  411. vector3d_normalize(&normal[i]);
  412. }
  413. /*Suppression des faces*/
  414. free(model->fa);
  415. model->nbface=0;
  416. model->fa=NULL;
  417. }
  418. //a2ri_vf_center(model);
  419. tx=0;ty=0;zoom=1;
  420. /*longdiag3d*/
  421. ptmin.x=model->xmin;
  422. ptmin.y=model->ymin;
  423. ptmin.z=model->zmin;
  424. ptmax.x=model->xmax;
  425. ptmax.y=model->ymax;
  426. ptmax.z=model->zmax;
  427. longdiag3d=point3d_length(&ptmin,&ptmax);
  428. /*INITIALISATION DE L'ALGORITHME*/
  429. /*CREATION DE LA SPACE PARTITION POUR OPTIMISATION DES RECHERCHES*/
  430. sp=(space_partition*)malloc(sizeof(space_partition));
  431. a2ri_erreur_critique_si(sp==NULL,
  432. "Erreur allocation memoire pour sp\na2ri_bpa_find_seed_triangle\n");
  433. nbpartX=(int)((model->xmax-model->xmin)/(2*radius));
  434. if(nbpartX==0)
  435. nbpartX++;
  436. nbpartY=(int)((model->ymax-model->ymin)/(2*radius));
  437. if(nbpartY==0)
  438. nbpartY++;
  439. nbpartZ=(int)((model->zmax-model->zmin)/(2*radius));
  440. if(nbpartZ==0)
  441. nbpartZ++;
  442. space_partition_new(sp,&ptmin,&ptmax,nbpartX,nbpartY,nbpartZ);
  443. a2ri_vf_space_partition(model,sp);
  444. //space_partition_display(sp);
  445. /*largeur, hauteur, longdiag2d*/
  446. point3d_init(&infgauche,model->xmin,model->ymin,0);
  447. point3d_init(&supgauche,model->xmin,model->ymax,0);
  448. point3d_init(&infdroit,model->xmax,model->ymin,0);
  449. largeur=point3d_length(&infgauche,&infdroit);
  450. hauteur=point3d_length(&infgauche,&supgauche);
  451. longdiag2d=point3d_length(&supgauche,&infdroit);
  452. init(argc,argv);
  453. glutReshapeFunc (reshape);
  454. glutDisplayFunc(display);
  455. glutMouseFunc (mouse);
  456. glutMotionFunc(motion);
  457. glutKeyboardFunc (keyboard);
  458. glutMainLoop();
  459. return 0;
  460. }