Moka libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
voxel-view.cc
Go to the documentation of this file.
1 /*
2  * lib-spamod : Visualisation des objets en discret.
3  * Copyright (C) 2004, Moka Team, Université de Poitiers, Laboratoire SIC
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * Copyright (C) 2009, Guillaume Damiand, CNRS, LIRIS,
6  * guillaume.damiand@liris.cnrs.fr, http://liris.cnrs.fr/
7  *
8  * This file is part of lib-spamod
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 /******************************************************************************
25  * Fichier : Voxel_View.cpp *
26  * Auteur : DEXET Martine *
27  *----------------------------------------------------------------------------*
28  * Ce fichier contient l'implémentation des méthodes de la classe Voxel_View.*
29  * *
30  *****************************************************************************/
31 
32 #ifdef _WINDOWS
33 #include <windows.h>
34 #endif
35 
36 #ifdef __APPLE__
37 #include <GLUT/glut.h>
38 #else
39 #include <GL/glut.h>
40 #endif
41 
42 #include "voxel-view.hh"
43 #include "ineq-op.hh"
44 #include "definition.hh"
45 #include "matrix-att.hh"
46 #include "voxel-list.hh"
47 #include "ineq-table-6.hh"
48 #include "ineq-table-2.hh"
49 #include "ineq-table-2-att.hh"
50 #include "ineq-table-6-att.hh"
51 #include "ineq-use-att.hh"
52 #include "ineq-use.hh"
53 
54 using namespace std;
55 using namespace GMap3d;
56 
57 /******************************************************************************
58  * Constructeur *
59  *****************************************************************************/
60 
61 Voxel_View::Voxel_View(CGMap * GM)
62 {
63  G = GM;
64 }
65 
66 
67 /******************************************************************************
68  * Fonction : void VoxelView::Calculate_Int_Bounding_Box( *
69  * float gmapBoundingBox[6], *
70  * int matrixBoundingBox[6]) *
71  *----------------------------------------------------------------------------*
72  * Cette fonction récupère le tableau des bornes de la boite englobante de *
73  * l'objet, arrondit les bornes non entières supérieures à l'entier supérieur *
74  * et arrondit les bornes non entières inférieures à l'entier inférieur. *
75  * *
76  *****************************************************************************/
77 
78 void Voxel_View::Calculate_Int_Bounding_Box(float gmapBoundingBox[6],
79  int matrixBoundingBox[6])
80 {
81  float up, down;
82 
83  // Pour chaque borne de la boite englobante.
84  for (int i=0 ; i<5 ; i+=2)
85  {
86 
87  // Calcul de l'arrondit entier des bornes supérieures.
88  // X, Y, et Z maximums
89  up = ceilf(gmapBoundingBox[i]);
90  down = floorf(gmapBoundingBox[i]);
91 
92  if (fabs(up - gmapBoundingBox[i])<EPS)
93  matrixBoundingBox[i] = (int)up;
94 
95  else
96  matrixBoundingBox[i] = (int)down;
97 
98  // Calcul de l'arrondit entier des bornes inférieures.
99  // X, Y et Z minimums
100  up = ceilf(-gmapBoundingBox[i+1]);
101  down = floorf(-gmapBoundingBox[i+1]);
102 
103  if (fabs(down + gmapBoundingBox[i+1])<EPS)
104  matrixBoundingBox[i+1] = (int)down;
105 
106  else
107  matrixBoundingBox[i+1] = (int)up;
108  }
109 }
110 
111 
112 /******************************************************************************
113  * Fonction : void VoxelView::Create_Matrix() *
114  *----------------------------------------------------------------------------*
115  * Cette fonction recherche les points entiers appartenant à la *
116  * supercouverture de l'objet et met à jour la matrice principale *
117  * *
118  *****************************************************************************/
119 
120 void Voxel_View::Create_Matrix()
121 {
122  CAttribute * alpha;
123  Matrix_Att * matrix;
124  Matrix * mat, * tempMat;
125  CDart * d01, * dO, * d;
126  Ineq_Table2 * tf;
127  Ineq_Table6 * te;
128  Ineq_Use * ue;
129 
130  float gmapBoundingBox[6];
131  int matrixBoundingBox[6];
132 
133  // Création d'une marque.
134  int markVoxel = G->getNewMark();
135 
136  // Parcours des brins de la G-carte.
137  CDynamicCoverageAll Cgm(G);
138 
139  for (Cgm.reinit(); Cgm.cont(); Cgm++)
140  {
141  d = *Cgm;
142 
143  // Si le brin n'est pas marqué.
144  if (!G->isMarked(d, markVoxel))
145  {
146  // Calcul de la boite englobante de l'objet afin de définir la
147  // taille de la matrice.
148  Calculate_Bounding_Box(G, d, ORBIT_0123, gmapBoundingBox);
149 
150  // Calcul des bornes entières de la boite englobante de l'objet.
151  Calculate_Int_Bounding_Box(gmapBoundingBox, matrixBoundingBox);
152 
153  // Attribut contenant la matrice.
154  matrix = new Matrix_Att(matrixBoundingBox, NO_COLOR);
155  mat = (Matrix*)matrix->Get_Data();
156 
157  // Parcours des brins de la G-carte.
158  CCoverage* DC = G->getDynamicCoverage(d, ORBIT_0123);
159 
160  // Recherche des voxels appartenant aux faces.
161  for (DC->reinit(); DC->cont(); (*DC)++)
162  {
163  dO = **DC;
164 
165  // Si le brin n'est pas marqué.
166  if (!G->isMarked(dO, markVoxel))
167  {
168  // Le brin appartient à une face.
169  if (G->getAttribute(dO,ORBIT_013, INT_ATTRIBUTE_ID))
170  {
171  // Calcul de la boîte englobante de la face.
172  Calculate_Bounding_Box(G, dO, ORBIT_01,
173  gmapBoundingBox);
174 
175  // Calcul des bornes entières de la boite englobante
176  // de la face.
177  Calculate_Int_Bounding_Box(gmapBoundingBox,
178  matrixBoundingBox);
179 
180  // Matrice temporaire utilisée pour la face traitée.
181  tempMat = new Matrix(matrixBoundingBox, FACE_COLOR);
182 
183  // Inéquations de la face.
184  alpha = G->getAttribute(dO, ORBIT_013,
186  tf = ((Ineq_Table2_Att*)alpha)->Get_Data();
187 
188  // Recherche des point entiers verifiant les inéquations
189  // de la face.
190  for (int t=0; t<2; t++)
191 
192  for (int i = matrixBoundingBox[1];
193  i <= matrixBoundingBox[0]; i++)
194  for (int j = matrixBoundingBox[3];
195  j <= matrixBoundingBox[2]; j++)
196  for (int k = matrixBoundingBox[5];
197  k <= matrixBoundingBox[4]; k++)
198  {
199  if (!tf->Get_Ineq(t)
200  ->Test_Point(CVertex(i,j,k)))
201  tempMat->Set_Color(i, j, k, NO_COLOR);
202  }
203 
204  // Parcourt des brins de la face.
205  CCoverage* DCf = G->getDynamicCoverage(dO, ORBIT_01);
206  for (DCf->reinit();
207  DCf->cont();
208  (*DCf)++)
209  {
210  d01 = **DCf;
211 
212  // Si le brin n'est pas marqué.
213  if (!G->isMarked(d01, markVoxel))
214  {
215  // Inéquations de l'arête.
216  alpha = G->getAttribute(d01, ORBIT_023,
218  te = ((Ineq_Table6_Att*)alpha)->Get_Data();
219 
220  // Visibilité des inéquations de l'arête par
221  // rapport à la face.
222  alpha = G->getAttribute(d01, ORBIT_0,
224  ue = ((Ineq_Use_Att*)alpha)->Get_Data();
225 
226  // Recherche des centres des voxels traversés
227  //par l'arête.
228  for (int t=0; t<6; t++)
229 
230  if(ue->Get_Use(t))
231  {
232  for (int i = matrixBoundingBox[1];
233  i <= matrixBoundingBox[0]; i++)
234  for (int j = matrixBoundingBox[3];
235  j <= matrixBoundingBox[2]; j++)
236  for (int k = matrixBoundingBox[5];
237  k <= matrixBoundingBox[4]; k++)
238  {
239  if (!te->Get_Ineq(t)
240  ->Test_Point(CVertex(i,j,k)))
241  tempMat->Set_Color(i, j, k,
242  NO_COLOR);
243  }
244  }
245  G->setMark(d01, markVoxel);
246  G->setMark(G->alpha0(d01), markVoxel);
247  }
248  }
249  delete DCf;
250 
251 
252  // Liste de voxels de la face.
253  Voxel_List* vList = new Voxel_List();
254  list<Voxel*> *l = (list<Voxel*>*)vList->Get_Data();
255 
256  // Parcours de la matrice pour créer la liste de voxels
257  // de la face.
258  for (int i = matrixBoundingBox[1];
259  i <= matrixBoundingBox[0]; i++)
260  for (int j = matrixBoundingBox[3];
261  j <= matrixBoundingBox[2]; j++)
262  for (int k = matrixBoundingBox[5];
263  k <= matrixBoundingBox[4]; k++)
264  {
265  if (tempMat->Get_Color(i, j, k) == FACE_COLOR)
266  {
267  l->push_front(new Voxel(i, j, k));
268  mat->Set_Color(i, j, k, FACE_COLOR);
269  }
270  }
271  if(!G->getAttribute(dO,ORBIT_013,PT_LIST_ATTRIBUTE_ID))
272  G->addAttribute(dO, ORBIT_013, vList);
273 
274  delete tempMat;
275  }
276  else
277  G->setMark(dO, markVoxel);
278  }
279  }
280 
281  // Demarquage des brins de la G-carte.
282  for (DC->reinit(); DC->cont(); (*DC)++)
283  G->unsetMark(**DC, markVoxel);
284 
285  // Recherche des point entiers correspondant aux aretes.
286  for (DC->reinit(); DC->cont(); (*DC)++)
287  {
288  dO = **DC;
289  if (!G->isMarked(dO, markVoxel))
290  {
291  if (!G->isFree0(dO))
292  {
293  // Calcul de la boite englobante de l'arête.
294  Calculate_Bounding_Box(G, dO, ORBIT_0,
295  gmapBoundingBox);
296 
297  // Calcul des bornes entières de la boite englobante.
298  Calculate_Int_Bounding_Box(gmapBoundingBox,
299  matrixBoundingBox);
300 
301  // Matrice temporaire pour l'arête traitee.
302  tempMat = new Matrix(matrixBoundingBox, EDGE_COLOR);
303 
304  // Inéquations de l'arête.
305  alpha = G->getAttribute(dO, ORBIT_023,
307  te = ((Ineq_Table6_Att*)alpha)->Get_Data();
308 
309  // Pour chaque inéquation.
310  for (int t=0; t<6; t++)
311 
312  // Mise à jour de la matrice.
313  for (int i=matrixBoundingBox[1];
314  i<=matrixBoundingBox[0]; i++)
315 
316  for (int j=matrixBoundingBox[3];
317  j<=matrixBoundingBox[2]; j++)
318 
319  for (int k=matrixBoundingBox[5];
320  k<=matrixBoundingBox[4]; k++)
321  {
322  if (!te->Get_Ineq(t)
323  ->Test_Point(CVertex(i,j,k)))
324  tempMat->Set_Color(i, j, k, NO_COLOR);
325  }
326 
327  // Marquage des brins de l arete.
328  CCoverage* DCe = G->getDynamicCoverage(dO, ORBIT_023);
329  for (DCe->reinit();
330  DCe->cont();
331  (*DCe)++)
332  G->setMark(**DCe, markVoxel);
333  delete DCe;
334 
335  // Liste de voxels de l'arete.
336  Voxel_List* vList = new Voxel_List();
337  list<Voxel*> *l = (list<Voxel*>*)vList->Get_Data();
338 
339 
340  // Parcours de la matrice pour créer la liste de voxels
341  // de l'arete.
342  for (int i=matrixBoundingBox[1];
343  i<=matrixBoundingBox[0]; i++)
344 
345  for (int j=matrixBoundingBox[3];
346  j<=matrixBoundingBox[2]; j++)
347 
348  for (int k=matrixBoundingBox[5];
349  k<=matrixBoundingBox[4]; k++)
350  {
351  if (tempMat->Get_Color(i, j, k) == EDGE_COLOR)
352  {
353  l->push_front(new Voxel(i, j, k));
354  mat->Set_Color(i, j, k, EDGE_COLOR);
355  }
356  }
357  G->addAttribute(dO, ORBIT_023, vList);
358  delete tempMat;
359  }
360 
361  // Le brin est seul.
362  else
363  G->setMark(dO, markVoxel);
364  }
365  }
366  // Demarquage des brins de la G-carte.
367  for (DC->reinit(); DC->cont(); (*DC)++)
368  G->unsetMark(**DC, markVoxel);
369 
370 
371  // Recherche des voxels correspondant aux sommets.
372  for (DC->reinit(); DC->cont(); (*DC)++)
373  {
374  dO = **DC;
375 
376  // Si le brin n'est pas marqué.
377  if (!G->isMarked(dO, markVoxel))
378  {
379  // Inéquations du sommet.
380  alpha = G->getAttribute(dO, ORBIT_123, INEQ6_ATTRIBUTE_ID);
381  te = ((Ineq_Table6_Att*)alpha)->Get_Data();
382 
383  // Boite engllobante du sommet.
384  gmapBoundingBox[0]=te->Get_Ineq(0)->GetW();
385  gmapBoundingBox[1]=te->Get_Ineq(1)->GetW();
386  gmapBoundingBox[2]=te->Get_Ineq(2)->GetW();
387  gmapBoundingBox[3]=te->Get_Ineq(3)->GetW();
388  gmapBoundingBox[4]=te->Get_Ineq(4)->GetW();
389  gmapBoundingBox[5]=te->Get_Ineq(5)->GetW();
390 
391  // Calcul des bornes entières de la boite englobante.
392  Calculate_Int_Bounding_Box(gmapBoundingBox,
393  matrixBoundingBox);
394 
395  // Matrice temporaire pour le sommet traité.
396  tempMat = new Matrix(matrixBoundingBox, VERTEX_COLOR);
397 
398  // Pour chaque inéquation.
399  for (int t=0; t<6; t++)
400 
401  // Mise à jour de la matrice.
402  for (int i=matrixBoundingBox[1];
403  i<=matrixBoundingBox[0]; i++)
404 
405  for (int j=matrixBoundingBox[3];
406  j<=matrixBoundingBox[2]; j++)
407 
408  for (int k=matrixBoundingBox[5];
409  k<=matrixBoundingBox[4]; k++)
410  {
411  if (!te->Get_Ineq(t)->Test_Point(CVertex(i,j,k)))
412  tempMat->Set_Color(i, j, k, NO_COLOR);
413  }
414 
415  // Marquage des brins du sommet.
416  CCoverage* DCe = G->getDynamicCoverage(dO, ORBIT_123);
417  for(DCe->reinit();
418  DCe->cont();
419  (*DCe)++)
420  G->setMark(**DCe, markVoxel);
421  delete DCe;
422 
423  // Liste de voxels du sommet.
424  Voxel_List* vList = new Voxel_List();
425  list<Voxel*> *l = (list<Voxel*>*)vList->Get_Data();
426 
427  // Parcours de la matrice pour créer la liste de voxels
428  // du sommet.
429  for (int i=matrixBoundingBox[1];
430  i<=matrixBoundingBox[0]; i++)
431 
432  for (int j=matrixBoundingBox[3];
433  j<=matrixBoundingBox[2]; j++)
434 
435  for (int k=matrixBoundingBox[5];
436  k<=matrixBoundingBox[4]; k++)
437  {
438  if (tempMat->Get_Color(i, j, k) == VERTEX_COLOR)
439  {
440  l->push_front(new Voxel(i, j, k));
441  mat->Set_Color(i, j, k, VERTEX_COLOR);
442  }
443  }
444 
445  G->addAttribute(dO, ORBIT_123, vList);
446  delete tempMat;
447  }
448  }
449 
450  G->addAttribute(d, ORBIT_0123, matrix);
451  //Demarquage et libération de la marque.
452  for (DC->reinit(); DC->cont(); (*DC)++)
453  G->unsetMark(**DC, markVoxel);
454 
455  for (DC->reinit(); DC->cont(); (*DC)++)
456  G->setMark(**DC, markVoxel);
457  delete DC;
458  }
459  }
460  for (Cgm.reinit(); Cgm.cont(); Cgm++)
461  G->unsetMark(*Cgm, markVoxel);
462 
463  G->freeMark(markVoxel);
464 }
465 
466 
467 /******************************************************************************
468  * Fonction : void VoxelView::Draw_Vertices(unsigned int cube) *
469  *----------------------------------------------------------------------------*
470  * Cette fonction affiche les voxels des sommets de l'objet. *
471  * *
472  *****************************************************************************/
473 
474 void Voxel_View::Draw_Vertices()
475 {
476  CDart * d;
477  int markVoxel = G->getNewMark();
478 
479  // Activation de l'éclairage.
480  glEnable(GL_LIGHTING);
481 
482  CDynamicCoverageAll Cgm(G);
483  for (Cgm.reinit(); Cgm.cont(); Cgm++)
484  {
485  d = *Cgm;
486 
487  // Si le brin n'est pas marqué.
488  if (!G->isMarked(d, markVoxel))
489  {
490  // Matrice principale.
491  CAttribute *alpha = G->getAttribute(d, ORBIT_0123, MATRIX_ATTRIBUTE_ID);
492  Matrix * mat = ((Matrix_Att*)alpha)->Get_Data();
493 
494  // Parcours de la matrice et affichage des voxels.
495  for (int i=mat->Get_X_Min() ; i<=mat->Get_X_Max() ; i++)
496 
497  for (int j=mat->Get_Y_Min() ; j<=mat->Get_Y_Max() ; j++)
498 
499  for (int k=mat->Get_Z_Min() ; k<=mat->Get_Z_Max() ; k++)
500 
501  if (mat->Get_Color(i,j,k) == VERTEX_COLOR)
502  {
503  glPushMatrix();
504  glTranslatef(i,j,k);
505  glutSolidCube(0.9);
506  glPopMatrix();
507  }
508 
509 
510  CCoverage* DC = G->getDynamicCoverage(d, ORBIT_0123);
511  for (DC->reinit(); DC->cont(); (*DC)++)
512  G->setMark(**DC, markVoxel);
513  delete DC;
514  }
515  }
516  for (Cgm.reinit(); Cgm.cont(); Cgm++)
517  G->unsetMark(*Cgm, markVoxel);
518 
519  G->freeMark(markVoxel);
520 
521  // Désactivation de l'éclairage.
522  glDisable(GL_LIGHTING);
523 }
524 
525 
526 /******************************************************************************
527  * Fonction : void VoxelView::Draw_Edges(unsigned int cube) *
528  *----------------------------------------------------------------------------*
529  * Cette fonction affiche les voxels des arêtes de l'objet. *
530  * *
531  *****************************************************************************/
532 
533 void Voxel_View::Draw_Edges()
534 {
535  CDart * d;
536  int markVoxel = G->getNewMark();
537 
538  // Activation de l'éclairage.
539  glEnable(GL_LIGHTING);
540 
541  CDynamicCoverageAll Cgm(G);
542  for (Cgm.reinit(); Cgm.cont(); Cgm++)
543  {
544  d = *Cgm;
545 
546  // Si le brin n'est pas marqué.
547  if (!G->isMarked(d, markVoxel))
548  {
549  // Matrice principale.
550  CAttribute *alpha = G->getAttribute(d, ORBIT_0123, MATRIX_ATTRIBUTE_ID);
551  Matrix * mat = ((Matrix_Att*)alpha)->Get_Data();
552 
553  // Parcours de la matrice et affichage des voxels.
554  for (int i=mat->Get_X_Min() ; i<=mat->Get_X_Max() ; i++)
555 
556  for (int j=mat->Get_Y_Min() ; j<=mat->Get_Y_Max() ; j++)
557 
558  for (int k=mat->Get_Z_Min() ; k<=mat->Get_Z_Max() ; k++)
559 
560  if (mat->Get_Color(i,j,k) == EDGE_COLOR)
561  {
562  glPushMatrix();
563  glTranslatef(i,j,k);
564  glutSolidCube(0.9);
565  glPopMatrix();
566  }
567  CCoverage* DC = G->getDynamicCoverage(d, ORBIT_0123);
568  for (DC->reinit(); DC->cont(); (*DC)++)
569  G->setMark(**DC, markVoxel);
570  delete DC;
571  }
572  }
573  for (Cgm.reinit(); Cgm.cont(); Cgm++)
574  G->unsetMark(*Cgm, markVoxel);
575 
576  G->freeMark(markVoxel);
577 
578  // Désactivation de l'éclairage.
579  glDisable(GL_LIGHTING);
580 }
581 
582 
583 /******************************************************************************
584  * Fonction : void VoxelView::Draw_Faces(unsigned int cube) *
585  *----------------------------------------------------------------------------*
586  * Cette fonction affiche les voxels des faces de l'objet. *
587  * *
588  *****************************************************************************/
589 
590 void Voxel_View::Draw_Faces()
591 {
592  CDart * d;
593  int markVoxel = G->getNewMark();
594 
595  // Activation de l(éclairage.
596  glEnable(GL_LIGHTING);
597 
598  CDynamicCoverageAll Cgm(G);
599  for (Cgm.reinit(); Cgm.cont(); Cgm++)
600  {
601  d = *Cgm;
602 
603  // Si le brin n'est pas marqué.
604  if (!G->isMarked(d, markVoxel))
605  {
606 
607  // Matrice principale.
608  CAttribute *alpha = G->getAttribute(d, ORBIT_0123, MATRIX_ATTRIBUTE_ID);
609  Matrix * mat = ((Matrix_Att*)alpha)->Get_Data();
610 
611  // Parcours de la matrice et affichage des voxels.
612  for (int i=mat->Get_X_Min() ; i<=mat->Get_X_Max() ; i++)
613 
614  for (int j=mat->Get_Y_Min() ; j<=mat->Get_Y_Max() ; j++)
615 
616  for (int k=mat->Get_Z_Min() ; k<=mat->Get_Z_Max() ; k++)
617 
618  if (mat->Get_Color(i,j,k) == FACE_COLOR)
619  {
620  glPushMatrix();
621  glTranslatef(i,j,k);
622  glutSolidCube(0.9);
623  glPopMatrix();
624  }
625  CCoverage* DC = G->getDynamicCoverage(d, ORBIT_0123);
626  for (DC->reinit(); DC->cont(); (*DC)++)
627  G->setMark(**DC, markVoxel);
628  delete DC;
629  }
630  }
631  for (Cgm.reinit(); Cgm.cont(); Cgm++)
632  G->unsetMark(*Cgm, markVoxel);
633 
634  G->freeMark(markVoxel);
635 
636  // Désactivation de l'éclairage.
637  glDisable(GL_LIGHTING);
638 }