Moka libraries
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
analytic-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 : Analytic_View.cpp *
26  * Auteur : DEXET Martine *
27  *----------------------------------------------------------------------------*
28  * Ce fichier contient l'implémentation des méthodes de la classe *
29  * Analytic_View. *
30  * *
31  *****************************************************************************/
32 
33 #ifdef _WINDOWS
34 #include <windows.h>
35 #endif
36 
37 #ifdef __APPLE__
38 #include <GLUT/glut.h>
39 #else
40 #include <GL/glut.h>
41 #endif
42 
43 #include "analytic-view.hh"
44 #include "ineq-table-6.hh"
45 #include "ineq-table-6-att.hh"
46 #include "int-att.hh"
47 #include "ineq-use-att.hh"
48 #include "ineq-table-2-att.hh"
49 #include "ineq-table-2.hh"
50 #include "ineq-use.hh"
51 #include "definition.hh"
52 #include "vector3d.hh"
53 #include "point-list.hh"
54 #include "attribute-vertex.hh"
55 
56 using namespace std;
57 using namespace GMap3d;
58 /******************************************************************************
59  * Constructeur *
60  *****************************************************************************/
61 
62 Analytic_View::Analytic_View(CGMap * GM)
63 {
64  G = GM;
65  directInfo = G->getNewDirectInfo();
66 }
67 
68 
69 // Destructeur.
70 Analytic_View::~Analytic_View()
71 {
72  // Libération du champ directInfo.
73  G->freeDirectInfo(directInfo);
74 }
75 
76 
77 /******************************************************************************
78  * Fonction : void Analytic_View::Create_Vertices_Faces() *
79  *----------------------------------------------------------------------------*
80  * Cette fonction crée les listes d'affichage des faces. *
81  * *
82  *****************************************************************************/
83 
84 void Analytic_View::Create_Vertices_Faces()
85 {
86  CAttribute* alpha;
87  Ineq_Table6* t;
88  CVertex* p;
89 
90 
91  // Création d'une marque.
92  int markVertex = G->getNewMark();
93 
94  // Parcours des brins de la G-carte.
95  CDynamicCoverageAll Cgm(G);
96  for (Cgm.reinit(); Cgm.cont(); Cgm++)
97  {
98  CDart* dgm = *Cgm;
99 
100  // Si le brin n'est pas marqué.
101  if (!G->isMarked(dgm, markVertex))
102  {
103  // Liste d'afichage du sommet.
104  Point_List* pList = new Point_List();
105  list<CVertex*> *vL = (list<CVertex*>*)pList->Get_Data();
106 
107  // Liste de points du sommet.
108  list<CVertex*> *l = new list<CVertex*>;
109 
110  // Tableau des 6 inequations et coordonnées du point
111  // associées au sommet.
112  alpha = G->getAttribute(dgm,ORBIT_123,INEQ6_ATTRIBUTE_ID);
113  t = ((Ineq_Table6_Att*)alpha)->Get_Data();
114  alpha = G->getAttribute(dgm,ORBIT_123,VERTEX_ATTRIBUTE_ID);
115  p = (CAttributeVertex*)alpha;
116 
117  // Création de la liste de points du sommet.
118  l->push_front(new CVertex(p->getX()+0.5,
119  p->getY()+0.5,
120  p->getZ()+0.5));
121  l->push_front(new CVertex(p->getX()+0.5,
122  p->getY()+0.5,
123  p->getZ()-0.5));
124  l->push_front(new CVertex(p->getX()+0.5,
125  p->getY()-0.5,
126  p->getZ()-0.5));
127  l->push_front(new CVertex(p->getX()+0.5,
128  p->getY()-0.5,
129  p->getZ()+0.5));
130  l->push_front(new CVertex(p->getX()-0.5,
131  p->getY()+0.5,
132  p->getZ()+0.5));
133  l->push_front(new CVertex(p->getX()-0.5,
134  p->getY()+0.5,
135  p->getZ()-0.5));
136  l->push_front(new CVertex(p->getX()-0.5,
137  p->getY()-0.5,
138  p->getZ()-0.5));
139  l->push_front(new CVertex(p->getX()-0.5,
140  p->getY()-0.5,
141  p->getZ()+0.5));
142 
143  // Ajout de cette liste à la variable directInfo du brin qui
144  // possède les attributs de l'orbite ORBIT_123.
145 
146  G->setDirectInfo(G->getEmbeddingOwner(dgm, ORBIT_123),directInfo,l);
147 
148  // Création de la liste d'affichage du sommet.
149  for (int i = 0 ; i<6 ; i++)
150  {
151  // Recherche des inequations visibles du sommet.
152  Inequation *ineq = t->Get_Ineq(i);
153 
154  // Si l'inéquation est visible.
155  if (ineq->Is_Used())
156  {
157  // Ajout des points verifiant l'inequation à la liste.
158  switch (i)
159  {
160  case 0:
161  vL->push_front(new CVertex(ineq->GetW(),
162  p->getY()+0.5,
163  p->getZ()+0.5));
164  vL->push_front(new CVertex(ineq->GetW(),
165  p->getY()+0.5,
166  p->getZ()-0.5));
167  vL->push_front(new CVertex(ineq->GetW(),
168  p->getY()-0.5,
169  p->getZ()-0.5));
170  vL->push_front(new CVertex(ineq->GetW(),
171  p->getY()-0.5,
172  p->getZ()+0.5));
173  break;
174 
175  case 1:
176  vL->push_front(new CVertex(-ineq->GetW(),
177  p->getY()+0.5,
178  p->getZ()+0.5));
179  vL->push_front(new CVertex(-ineq->GetW(),
180  p->getY()+0.5,
181  p->getZ()-0.5));
182  vL->push_front(new CVertex(-ineq->GetW(),
183  p->getY()-0.5,
184  p->getZ()-0.5));
185  vL->push_front(new CVertex(-ineq->GetW(),
186  p->getY()-0.5,
187  p->getZ()+0.5));
188  break;
189 
190  case 2:
191  vL->push_front(new CVertex(p->getX()+0.5,
192  ineq->GetW(),
193  p->getZ()+0.5));
194  vL->push_front(new CVertex(p->getX()+0.5,
195  ineq->GetW(),
196  p->getZ()-0.5));
197  vL->push_front(new CVertex(p->getX()-0.5,
198  ineq->GetW(),
199  p->getZ()-0.5));
200  vL->push_front(new CVertex(p->getX()-0.5,
201  ineq->GetW(),
202  p->getZ()+0.5));
203  break;
204 
205  case 3:
206  vL->push_front(new CVertex(p->getX()+0.5,
207  -ineq->GetW(),
208  p->getZ()+0.5));
209  vL->push_front(new CVertex(p->getX()+0.5,
210  -ineq->GetW(),
211  p->getZ()-0.5));
212  vL->push_front(new CVertex(p->getX()-0.5,
213  -ineq->GetW(),
214  p->getZ()-0.5));
215  vL->push_front(new CVertex(p->getX()-0.5,
216  -ineq->GetW(),
217  p->getZ()+0.5));
218  break;
219 
220  case 4:
221  vL->push_front(new CVertex(p->getX()+0.5,
222  p->getY()+0.5,
223  ineq->GetW()));
224  vL->push_front(new CVertex(p->getX()+0.5,
225  p->getY()-0.5,
226  ineq->GetW()));
227  vL->push_front(new CVertex(p->getX()-0.5,
228  p->getY()-0.5,
229  ineq->GetW()));
230  vL->push_front(new CVertex(p->getX()-0.5,
231  p->getY()+0.5,
232  ineq->GetW()));
233  break;
234 
235  case 5:
236  vL->push_front(new CVertex(p->getX()+0.5,
237  p->getY()+0.5,
238  -ineq->GetW()));
239  vL->push_front(new CVertex(p->getX()+0.5,
240  p->getY()-0.5,
241  -ineq->GetW()));
242  vL->push_front(new CVertex(p->getX()-0.5,
243  p->getY()-0.5,
244  -ineq->GetW()));
245  vL->push_front(new CVertex(p->getX()-0.5,
246  p->getY()+0.5,
247  -ineq->GetW()));
248  break;
249 
250  default:
251  break;
252  }
253  }
254  }
255 
256  // Ajout de la liste d'affichage au sommet en tant qu'attribut.
257  G->addAttribute(dgm, ORBIT_123, pList);
258 
259  // Parcours et marquage des brins du sommet.
260  CCoverage* DCv = G->getDynamicCoverage(dgm, ORBIT_123);
261  for(DCv->reinit(); DCv->cont(); (*DCv)++)
262  G->setMark(**DCv, markVertex);
263  delete DCv;
264  }
265  }
266 
267  // Demarquage et libération de la marque "markVertex".
268  for (Cgm.reinit(); Cgm.cont(); Cgm++)
269  G->unsetMark(*Cgm, markVertex);
270  G->freeMark(markVertex);
271 
272 }
273 
274 
275 /******************************************************************************
276  * Fonction : void Analytic_View::Create_Edges_Faces() *
277  *----------------------------------------------------------------------------*
278  * Cette fonction crée les listes d'affichage des arêtes de l'objet. *
279  * *
280  *****************************************************************************/
281 
282 void Analytic_View::Create_Edges_Faces()
283 {
284  CAttribute* alpha;
285  Ineq_Table6* t;
286  list<CVertex*> *pl1, *pl2;
287  list<CVertex*>::iterator iter;
288  CVertex *p1, *p2;
289  CVertex* nearest[4];
290 
291  int tmpNb;
292  float length;
293  bool biplanes = false, noEdge;
294 
295 
296  // Création d'une marque.
297  int markEdge = G->getNewMark();
298 
299  // Parcours des brins de la G-carte.
300  CDynamicCoverageAll Cgm(G);
301  for (Cgm.reinit(); Cgm.cont(); Cgm++)
302  {
303  CDart* dgm = *Cgm;
304 
305  // L'arête n'alpha pas encore été traitée.
306  if (!G->isMarked(dgm, markEdge) && !G->isFree0(dgm))
307  {
308  // Liste d'affichage de l'arête.
309  Point_List* pList = new Point_List();
310  list<CVertex*> *l = (list<CVertex*>*)pList->Get_Data();
311 
312  // Coordonnées des 2 sommets.
313  alpha = G->getAttribute(dgm,ORBIT_123,VERTEX_ATTRIBUTE_ID);
314  p1 = (CAttributeVertex*)alpha;
315  alpha = G->getAttribute(G->alpha0(dgm),ORBIT_123,
317  p2 = (CAttributeVertex*)alpha;
318 
319  // Vecteur correspondant à l'arête
320  Vector3D edgeVec(p2->getX()-p1->getX(),
321  p2->getY()-p1->getY(),
322  p2->getZ()-p1->getZ());
323 
324  // Inequations de l'arête.
325  alpha = G->getAttribute(dgm,ORBIT_023,INEQ6_ATTRIBUTE_ID);
326  t = ((Ineq_Table6_Att*)alpha)->Get_Data();
327 
328  // Liste des points des 1er et 2ieme sommets.
329  pl1 = (list<CVertex*>*)G->getDirectInfo(G->getEmbeddingOwner(dgm, ORBIT_123),directInfo);
330  pl2 = (list<CVertex*>*)G->getDirectInfo(G->getEmbeddingOwner(G->alpha0(dgm),ORBIT_123),directInfo);
331 
332  // Création de la liste d'affichage.
333  for (int i=0; i<6; i++)
334  {
335  // Recherche des inequations visibles.
336  Inequation *ineq = t->Get_Ineq(i);
337 
338  if (ineq->Is_Used())
339  {
340  noEdge=false;
341 
342  // Le segment n'est pas sur un (ou deux) plan(s) du repere.
343  if (ineq->Get_Dim()!=1)
344  {
345  tmpNb = 0;
346 
347  // Recherche des points du 1er sommet verifiant
348  // l'inequation.
349  for (iter = pl1->begin() ;
350  iter != pl1->end() && tmpNb < 2 ;
351  iter++)
352 
353  if (ineq->Test_Point_Eq(**iter))
354  {
355  nearest[tmpNb] = *iter;
356  tmpNb++;
357  }
358 
359  // Recherche des points du 2ieme sommet verifiant
360  // l'inequation.
361  for (iter = pl2->begin() ;
362  iter != pl2->end() && tmpNb < 4 ;
363  iter++)
364 
365  if (ineq->Test_Point_Eq(**iter))
366  {
367  nearest[tmpNb] = *iter;
368  tmpNb++;
369  }
370 
371  // Ajout des points à la liste dans l'ordre.
372  // pour permettre l affichage direct.
373  Vector3D v(nearest[2]->getX()-nearest[0]->getX(),
374  nearest[2]->getY()-nearest[0]->getY(),
375  nearest[2]->getZ()-nearest[0]->getZ());
376 
377  l->push_front(nearest[0]);
378  l->push_front(nearest[1]);
379 
380  if (v == edgeVec)
381  {
382  l->push_front(nearest[3]);
383  l->push_front(nearest[2]);
384  }
385  else
386  {
387  l->push_front(nearest[2]);
388  l->push_front(nearest[3]);
389  }
390  }
391 
392  // Le segment est sur un (ou deux) plan(s) du repère.
393  else
394  {
395  if ((*p2-*p1).norm()<1.0)
396  length = 2.0;
397  else
398  length = 2.0*(*p2-*p1).norm();
399 
400  tmpNb = 0;
401 
402  // Recherche du (ou des 2) point(s) le(s) plus
403  //proche(s) pour le 1er sommet verifiant l'inequation
404  for (iter = pl1->begin();
405  iter != pl1->end() && tmpNb<4;
406  iter++)
407  {
408  if(ineq->Test_Point_Eq(**iter))
409  {
410  // Le point est plus proche.
411  if ((*p2-**iter).norm()
412  <length-EPS)
413  {
414  length =
415  (*p2-**iter).norm();
416  if (tmpNb != 0)
417  nearest[tmpNb] = nearest[0];
418 
419  nearest[0] = *iter;
420  biplanes = false;
421 
422  }
423 
424  // Le point est à égale distance.
425  else
426  if(fabs((*p2-**iter).norm()
427  -length)
428  <= EPS)
429  {
430  if (tmpNb != 1)
431  nearest[tmpNb] = nearest[1];
432 
433  nearest[1] = *iter;
434  biplanes = true;
435  }
436 
437  // Le point est plus éloigné.
438  else
439  nearest[tmpNb]=*iter;
440 
441  tmpNb++;
442  }
443  }
444 
445  // Le segment est seulement sur un plan du repère.
446  if (!biplanes)
447  {
448  CVertex* tmp;
449  tmpNb = 0;
450 
451  if ((*p1-*p2).norm()<1.0)
452  length = 2.0;
453  else
454  length = 2.0*(*p1-*p2).norm();
455 
456  // Equation que doit vérifier le 2ieme point
457  // du 1er sommet.
458  Inequation eq;
459 
460  if (i == 0 || i == 1)
461  eq.SetAbcw(0, 0, 1, nearest[0]->getZ());
462 
463  else
464  if (i == 2 || i == 3)
465  eq.SetAbcw(1, 0, 0, nearest[0]->getX());
466 
467  else
468  eq.SetAbcw(0, 1, 0, nearest[0]->getY());
469 
470  // recherche du 2ieme point du 1er sommet
471  // verifiant l'equation calculee.
472  for (int i=2; i<4; i++)
473  {
474  if (eq.Test_Point_Eq (*nearest[i]))
475  {
476  tmp = nearest[1];
477  nearest[1] = nearest[i];
478  nearest[i] = tmp;
479  }
480  }
481 
482  // Recherche des 2 points du 2ieme sommet
483  // verifiant l'inequation.
484  for (iter=pl2->begin();
485  iter!=pl2->end() && tmpNb<4;
486  iter++)
487  {
488  if (ineq->Test_Point_Eq(**iter))
489  {
490  Vector3D v((*iter)->getX()
491  -nearest[1]->getX(),
492  (*iter)->getY()
493  -nearest[1]->getY(),
494  (*iter)->getZ()
495  -nearest[1]->getZ());
496 
497  // Les deux vecteurs sont égaux.
498  if (edgeVec == v)
499  nearest[2] = *iter;
500 
501  // Le point est plus proche.
502  else
503  if((*p1-**iter).norm()
504  <length-EPS){
505  length = (*p1-**iter).norm();
506  nearest[3] = *iter;
507  }
508  tmpNb++;
509  }
510  }
511 
512 
513  // Cas particlier :
514  // Les deux voxels des sommets se chevauchent.
515  if (Vector3D(*nearest[0],
516  *nearest[3]).Scal_Product(edgeVec)
517  <0.0)
518  {
519  Inequation eq2;
520  bool found = false;
521 
522  if (nearest[2]->getX() == nearest[3]->getX())
523  {
524  eq2.SetAbcw(1,0,0,nearest[3]->getX());
525  if (eq2 != *ineq)
526  found = true;
527  }
528  if (nearest[2]->getY() == nearest[3]->getY()
529  && !found)
530  {
531  eq2.SetAbcw(0,1,0,nearest[3]->getY());
532  if (eq2 != *ineq)
533  found = true;
534  }
535 
536  if (nearest[2]->getZ() == nearest[3]->getZ()
537  && !found)
538  {
539  eq2.SetAbcw(0,0,1,nearest[3]->getZ());
540  if (eq2 != *ineq)
541  found = true;
542  }
543  nearest[0] = ineq->Intersec (eq, eq2);
544  nearest[3] = nearest[0];
545  }
546  }
547 
548  // Le segment est sur deux plans.
549  else
550  {
551  tmpNb = 0;
552 
553  // Recherche des points du 2ieme sommet
554  // verifiant l'inequation.
555  for (iter=pl2->begin();
556  iter!=pl2->end() && tmpNb < 4;
557  iter++)
558  {
559  if(ineq->Test_Point_Eq(**iter))
560  {
561  // Calcul des deux vecteurs pour chaque
562  // point testé.
563  Vector3D v1((*iter)->getX()
564  -nearest[1]->getX(),
565  (*iter)->getY()
566  -nearest[1]->getY(),
567  (*iter)->getZ()
568  -nearest[1]->getZ());
569 
570  Vector3D v0((*iter)->getX()
571  -nearest[0]->getX(),
572  (*iter)->getY()
573  -nearest[0]->getY(),
574  (*iter)->getZ()
575  -nearest[0]->getZ());
576 
577  // Le premier vecteur est parallèle
578  // au vecteur de l'arête.
579  if ( v1.Vect_Product(edgeVec) ==
580  Vector3D(0, 0, 0))
581  {
582  if (v1 != edgeVec)
583  nearest[2] = *iter;
584  }
585 
586  // Le deuxieme vecteur est parallèle
587  // au vecteur de l'arete.
588  else
589  if ( v0.Vect_Product(edgeVec) ==
590  Vector3D(0, 0, 0))
591  {
592  if (v0 != edgeVec)
593  nearest[3] = *iter;
594  }
595  tmpNb++;
596  }
597  }
598 
599  if (Vector3D(*nearest[0],
600  *nearest[3]).Scal_Product(edgeVec)
601  +1<EPS)
602  noEdge=true;
603  }
604  if (!noEdge)
605  {
606  // Ajout des 4 points trouves alpha la liste.
607  l->push_front(nearest[0]);
608  l->push_front(nearest[1]);
609  l->push_front(nearest[2]);
610  l->push_front(nearest[3]);
611  }
612  }
613  }
614  }
615 
616  // Ajout de la liste d'affichage à l'arete.
617  G->addAttribute(dgm, ORBIT_023, pList);
618 
619  // Parcours et marquage des brins de l'arête.
620  CCoverage* DCe = G->getDynamicCoverage(dgm, ORBIT_023);
621  for(DCe->reinit(); DCe->cont(); (*DCe)++)
622  G->setMark(**DCe, markEdge);
623  delete DCe;
624  }
625  }
626  // Demarquage et liberation de la marque "markEdge".
627  for (Cgm.reinit(); Cgm.cont(); Cgm++)
628  G->unsetMark(*Cgm, markEdge);
629  G->freeMark(markEdge);
630 
631 }
632 
633 
634 /******************************************************************************
635  * Fonction : void Analytic_View::Create_Faces() *
636  *----------------------------------------------------------------------------*
637  * Cette fonction crée les listes d'affichage des faces de l'objet. *
638  * *
639  *****************************************************************************/
640 
641 void Analytic_View::Create_Faces()
642 {
643  CAttribute* alpha;
644  Ineq_Table2* tf;
645  list<CVertex*> *pl;
646  list<CVertex*>::iterator iter;
647  Ineq_Table6 *te;
648  CVertex* p, *lastPt;
649  Ineq_Use *u;
650  CDart *dgm, *d01;
651  Inequation **faceIneq = NULL, **faceIneq2 = NULL;
652 
653  int nbPoints, realNbPoints;
654  bool testPoint;
655 
656 
657  // Création d'une marque.
658  int markFace = G->getNewMark();
659 
660  // Parcours des brins de la G-carte.
661  CDynamicCoverageAll Cgm(G);
662  for (Cgm.reinit(); Cgm.cont(); Cgm++)
663  {
664  dgm = *Cgm;
665 
666  // La face n'alpha pas encore ete traitée.
667  if (!G->isMarked(dgm, markFace) &&
668  G->getEmbeddingOwner(dgm, ORBIT_013))
669  {
670  // Liste d'affichage de la face.
671  Point_List* pList = new Point_List();
672  list<CVertex*> *l = (list<CVertex*>*)pList->Get_Data();
673 
674  // Tableau des 2 inequations de la face.
675  alpha = G->getAttribute(dgm,ORBIT_013,INEQ2_ATTRIBUTE_ID);
676  tf = ((Ineq_Table2_Att*)alpha)->Get_Data();
677 
678  // Nombre de sommets de la face.
679  alpha = G->getAttribute(dgm,ORBIT_013,INT_ATTRIBUTE_ID);
680  nbPoints = *(((Int_Att*)alpha)->Get_Data());
681 
682  // Pour chaque inéquation de la face..
683  for (int i=0 ; i<2 ; i++)
684  {
685  Inequation *ineq = tf->Get_Ineq(i);
686 
687  // La face est de dimension 1 ( deux des composantes alpha, b ou c
688  // de l'inéquation de la face sont nulles).
689  if (ineq->Get_Dim() == 1)
690  {
691  if (i == 0)
692  {
693  int k = 0;
694 
695  // Tableau contenant les inéquations non visibles.
696  faceIneq = new Inequation*[nbPoints];
697 
698  // Parcours les brins de la face.
699  CCoverage* DC01 = G->getDynamicCoverage(dgm, ORBIT_01);
700  for (DC01->reinit();
701  DC01->cont();
702  (*DC01)++)
703  {
704  d01 = **DC01;
705 
706  // Le brin n'alpha pas encore été traité.
707  if (!G->isMarked(d01, markFace))
708  {
709  // Récupération des inéquation de l'arête et du
710  // tableau de type Ineq_Use.
711  alpha = G->getAttribute(d01,ORBIT_023,
713  te = ((Ineq_Table6_Att*)alpha)->Get_Data();
714  alpha = G->getAttribute(d01,ORBIT_0,
716  u = ((Ineq_Use_Att*)alpha)->Get_Data();
717 
718  // Recupération des inéquations des arêtes qui
719  // ne sont pas visibles.
720  for (int j=0; j<6; j++)
721  if (!u->Get_Use(j) &&
722  te->Get_Ineq(j)->Get_Dim()!=0)
723  faceIneq[k++] = te->Get_Ineq(j);
724 
725  G->setMark(d01, markFace);
726  G->setMark(G->alpha0(d01), markFace);
727  }
728  }
729  delete DC01;
730  }
731 
732  lastPt = NULL;
733 
734  // Nombre de points de la facette.
735  realNbPoints = 0;
736 
737  // Recherche des points de la facette.
738  for (int j=0 ; j<nbPoints ; j++)
739  {
740  testPoint = false;
741 
742  for (int k=j+1 ; k<nbPoints+1 && !testPoint; k++)
743  {
744  // Si les deux bords des demi-espaces définis par
745  // les inéquations ne sont pas parallèles.
746  if(Vector3D(faceIneq[j]->GetA(),
747  faceIneq[j]->GetB(),
748  faceIneq[j]->GetC())
749  .Vect_Product(Vector3D(faceIneq[k%nbPoints]
750  ->GetA(),
751  faceIneq[k%nbPoints]
752  ->GetB(),
753  faceIneq[k%nbPoints]
754  ->GetC()))
755  != Vector3D(0,0,0))
756  {
757  testPoint = true;
758 
759  // Calcul du point d'intersection.
760  p = ineq->Intersec(*faceIneq[j],
761  *faceIneq[k%nbPoints]);
762 
763  // Je teste si le point vérifie le reste des
764  // des inéquations du tableau.
765  for (int m=0 ; m<nbPoints && testPoint ; m++)
766  {
767  if (m != j && m != k%nbPoints)
768  if (faceIneq[m]->Test_Point(*p) &&
769  !faceIneq[m]->Test_Point_Eq(*p))
770  {
771  testPoint = false;
772  delete p;
773  }
774  }
775  }
776 
777  // Si un point correct est trouvé.
778  if (testPoint)
779  {
780  // Si ce point est différent du précédent.
781  if (lastPt == NULL ||
782  (lastPt != NULL && *lastPt != *p))
783  {
784  // Ajout du point à la liste.
785  l->push_front(p);
786  lastPt = p;
787  realNbPoints++;
788  }
789  else
790  delete p;
791  }
792  }
793  }
794 
795  if (i == 1)
796  delete [] faceIneq;
797  }
798 
799  // La face est de dimension 2.
800  else
801  if (ineq->Get_Dim() == 2)
802  {
803  int k = 0;
804 
805  if (i == 0)
806  {
807  // Tableau contenant les inéquations non visibles des
808  // arêtes.
809  faceIneq2 = new Inequation*[nbPoints*2];
810 
811  // Parcours des brins de la face.
812  CCoverage* DC01 = G->getDynamicCoverage(dgm, ORBIT_01);
813  for (DC01->reinit();
814  DC01->cont();
815  (*DC01)++)
816  {
817  d01 = **DC01;
818 
819  // Le brin n'alpha pas encore été traité.
820  if (!G->isMarked(d01, markFace))
821  {
822 
823 
824 
825  // Récupération des inéquations de l'arête et
826  // du tableau de type Ineq_Use.
827  alpha = G->getAttribute(d01,ORBIT_023,
829  te = ((Ineq_Table6_Att*)alpha)->Get_Data();
830  alpha = G->getAttribute(d01,ORBIT_0,
832  u = ((Ineq_Use_Att*)alpha)->Get_Data();
833  // Récupération les inéquations des arêtes qui
834  // ne sont pas visibles.
835  for (int j=0; j<6; j++)
836  {
837  if (!u->Get_Use(j) &&
838  te->Get_Ineq(j)->Get_Dim()!=0)
839  {
840  faceIneq2[k++] = te->Get_Ineq(j);
841  }
842  }
843  G->setMark(d01, markFace);
844  G->setMark(G->alpha0(d01), markFace);
845  }
846  }
847 
848  // Parcours et démarquage des brins de la face.
849  for (DC01->reinit();
850  DC01->cont();
851  (*DC01)++)
852  {
853  G->unsetMark(**DC01, markFace);
854  }
855 
856 
857  delete DC01;
858 
859  }
860 
861 
862 
863  // Tableau contenant les inéquations utilisées pour une
864  // facette.
865  faceIneq = new Inequation*[nbPoints];
866 
867  k = 0;
868 
869  // Parcours des brins de la face.
870  CCoverage* DC01 = G->getDynamicCoverage(dgm, ORBIT_01);
871  for (DC01->reinit();
872  DC01->cont();
873  (*DC01)++)
874  {
875  d01 = **DC01;
876 
877  // Le sommet n'alpha pas encore été traité.
878  if (!G->isMarked(d01, markFace))
879  {
880  // Récupération de la liste de points du sommet.
881  pl = (list<CVertex*>*)G->getDirectInfo(G->getEmbeddingOwner
882  (d01,ORBIT_123),directInfo);
883 
884  // Recherche des équations des inéquations non
885  // visibles des arêtes qui sont vérifiées par les
886  // points vérifiant l'équation de la face.
887  for (iter=pl->begin();
888  iter!=pl->end();
889  iter++) {
890  if(ineq->Test_Point_Eq(**iter))
891  {
892  for (int j=2*k; j<2*k+2; j++)
893  {
894  if (faceIneq2[j]
895  ->Test_Point_Eq(**iter))
896  // Stockage de l'inéquation dans le
897  // tableau
898  faceIneq[k] = faceIneq2[j];
899  }
900  }
901  }
902  k++;
903 
904  G->setMark(d01, markFace);
905  G->setMark(G->alpha1(d01), markFace);
906  }
907  }
908 
909 
910  if (i==0)
911  {
912  // Parcours et démarquage des brins de la face.
913  for (DC01->reinit();
914  DC01->cont();
915  (*DC01)++)
916  G->unsetMark(**DC01, markFace);
917  }
918  delete DC01;
919 
920  lastPt = NULL;
921 
922  // Nombre de sommets de la facette.
923  realNbPoints = 0;
924 
925  for (int j=0 ; j<nbPoints ; j++)
926  {
927  testPoint = false;
928 
929  // Pour chaque inéquation du tableau.
930  for (k=j+1 ; k<nbPoints+1 && !testPoint; k++)
931  {
932  // Si les deux inéquations ne sont pas parallèles.
933  if(Vector3D(faceIneq[j]->GetA(),
934  faceIneq[j]->GetB(),
935  faceIneq[j]->GetC())
936  .Vect_Product(Vector3D(faceIneq[k%nbPoints]
937  ->GetA(),
938  faceIneq[k%nbPoints]
939  ->GetB(),
940  faceIneq[k%nbPoints]
941  ->GetC()))
942  != Vector3D(0,0,0))
943  {
944  testPoint = true;
945 
946  // Calcul du point d'intersection.
947  p = ineq->Intersec(*faceIneq[j],
948  *faceIneq[k%nbPoints]);
949 
950  // Je teste si le point vérifie le reste des
951  // inéquations du tableau.
952  for (int m=0 ; m<nbPoints && testPoint ; m++)
953  {
954  if (m != j && m != k%nbPoints)
955  if (faceIneq[m]->Test_Point(*p) &&
956  !faceIneq[m]->Test_Point_Eq(*p))
957  {
958  testPoint = false;
959  delete p;
960  }
961  }
962  }
963 
964  // Si un point correct est trouvé.
965  if (testPoint)
966  {
967  // Si ce point est différent du précédent.
968  if (lastPt == NULL ||
969  (lastPt != NULL && *lastPt != *p))
970  {
971  // Ajout du point à la liste.
972  l->push_front(p);
973  lastPt = p;
974  realNbPoints++;
975  }
976  else
977  delete p;
978  }
979  }
980  }
981 
982  delete [] faceIneq;
983 
984  if (i==1)
985  delete [] faceIneq2;
986  }
987 
988 
989  // La face est de dimension 3.
990  else
991  {
992 
993  // Parcours des brins de la face.
994  CCoverage* DC01 = G->getDynamicCoverage(dgm, ORBIT_01);
995  for (DC01->reinit();
996  DC01->cont();
997  (*DC01)++)
998  {
999  d01 = **DC01;
1000 
1001  // Le sommet n'alpha pas encore ete traité.
1002  if (!G->isMarked(d01, markFace))
1003  {
1004  // Récupération de la liste de points du sommet.
1005  pl = (list<CVertex*>*)G->getDirectInfo(G->getEmbeddingOwner
1006  (d01, ORBIT_123),directInfo);
1007 
1008  // Recherche du point du sommet verifiant
1009  // l'équation de inéquation courante.
1010  for (iter=pl->begin();
1011  iter!=pl->end();
1012  iter++)
1013 
1014  // Ajout du point à la liste.
1015  if(ineq->Test_Point_Eq(**iter))
1016  l->push_front(*iter);
1017 
1018 
1019  G->setMark(d01, markFace);
1020  G->setMark(G->alpha1(d01), markFace);
1021  }
1022  }
1023 
1024  if (i==0)
1025  {
1026  // Parcours et démarquage des brins de la face.
1027  for (DC01->reinit();
1028  DC01->cont();
1029  (*DC01)++)
1030  G->unsetMark(**DC01, markFace);
1031  }
1032  delete DC01;
1033 
1034  // Affectation du nombre de points de la facette.
1035  realNbPoints = nbPoints;
1036  }
1037  }
1038 
1039  // Ajout de la liste à la face.
1040  if(!G->getAttribute(dgm, ORBIT_013, PT_LIST_ATTRIBUTE_ID))
1041  G->addAttribute(dgm, ORBIT_013, pList);
1042 
1043 
1044  // Stockage du nombre de sommets de la facette à la place du nombre
1045  // de sommets de la face.
1046  alpha = G->getAttribute(dgm, ORBIT_013, INT_ATTRIBUTE_ID);
1047  *(((Int_Att*)alpha)->Get_Data()) = realNbPoints;
1048  }
1049  else
1050  G->setMark(dgm, markFace);
1051  }
1052 
1053  // Demarquage et liberation de la marque "markEdge".
1054  for (Cgm.reinit(); Cgm.cont(); Cgm++)
1055  G->unsetMark(*Cgm, markFace);
1056  G->freeMark(markFace);
1057 
1058 }
1059 
1060 
1061 /******************************************************************************
1062  * Fonction : void Analytic_View::Draw_List() *
1063  *----------------------------------------------------------------------------*
1064  * Cette fonction permet d'afficher les polygones dont les points sont *
1065  * contenus dans une liste en calculant au préalable la normale à leur face. *
1066  * *
1067  *****************************************************************************/
1068 
1069 void Analytic_View::Draw_List(list<CVertex*> *l, int nbPoints) const
1070 {
1071  if (nbPoints >= 3)
1072  {
1073  Vector3D normal;
1074  CVertex ** tab = new CVertex*[nbPoints];
1075 
1076  int count = 0;
1077 
1078  // Parcours de la liste de points.
1079  list<CVertex*>::iterator iter;
1080  for (iter=l->begin();
1081  iter!=l->end();
1082  iter++)
1083  {
1084  // Stockage des points dans un tableau temporaire.
1085  tab[count] = *iter;
1086  count++;
1087 
1088  if (count == nbPoints)
1089  {
1090  // Calcul de la normale à la face
1091  Vector3D v1(*tab[0], *tab[1]);
1092  Vector3D v2(*tab[1], *tab[2]);
1093  normal = v1.Vect_Product(v2);
1094 
1095  if (normal.norm()>EPS)
1096  normal.Normalize();
1097 
1098  // Affichage du polygone
1099  glBegin(GL_POLYGON);
1100  glNormal3f(normal.getX(), normal.getY(), normal.getZ());
1101  for (int i=0; i<nbPoints; i++)
1102  glVertex3f(tab[i]->getX(), tab[i]->getY(), tab[i]->getZ());
1103  glEnd();
1104 
1105  count = 0;
1106  }
1107  }
1108 
1109  delete [] tab;
1110  }
1111 }
1112 
1113 
1114 /******************************************************************************
1115  * Fonction : void Analytic_View::Vertices_Draw() *
1116  *----------------------------------------------------------------------------*
1117  * Cette fonction affiche les facettes des sommets. *
1118  * *
1119  *****************************************************************************/
1120 
1121 void Analytic_View::Vertices_Draw()
1122 {
1123  int markVertex = G->getNewMark();
1124 
1125  // Activation de l'éclairage
1126  glEnable(GL_LIGHTING);
1127  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
1128  glShadeModel(GL_SMOOTH);
1129 
1130  // Création d'un parcours des brins de la G-carte.
1131  CDynamicCoverageAll C(G);
1132 
1133  // Parcours des sommets.
1134  for (C.reinit(); C.cont(); C++)
1135  {
1136  CDart* d = *C;
1137 
1138  // Si le brin n'est pas marqué.
1139  if (!G->isMarked(d, markVertex))
1140  {
1141  // Récupération de la liste d'affichage du sommet.
1142  CAttribute * alpha = G->getAttribute(d,ORBIT_123, PT_LIST_ATTRIBUTE_ID);
1143 
1144  // Affichage des facettes.
1145  Draw_List(((Point_List*)alpha)->Get_Data(), 4);
1146 
1147  // Marquage des brins de l'orbite ORBIT_123.
1148  CCoverage* DCv = G->getDynamicCoverage(d, ORBIT_123);
1149  for(DCv->reinit(); DCv->cont(); (*DCv)++)
1150  G->setMark(**DCv, markVertex);
1151  delete DCv;
1152  }
1153  }
1154 
1155  // Parcours et démarquage des brins de la G-carte.
1156  for (C.reinit(); C.cont(); C++)
1157  G->unsetMark(*C, markVertex);
1158  G->freeMark(markVertex);
1159 
1160  // Désactivation de l'éclairage
1161  glDisable(GL_LIGHTING);
1162  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
1163  glShadeModel(GL_FLAT);
1164 }
1165 
1166 
1167 
1168 /******************************************************************************
1169  * Fonction : void Analytic_View::Edges_Draw() *
1170  *----------------------------------------------------------------------------*
1171  * Cette fonction affiche les facettes des arêtes. *
1172  * *
1173  *****************************************************************************/
1174 
1175 void Analytic_View::Edges_Draw()
1176 {
1177  // Création d'une marque
1178  int markEdge = G->getNewMark();
1179 
1180  // Création d'un parcours des brins de la G-carte.
1181  CDynamicCoverageAll C(G);
1182 
1183  // Activation de l'éclairage
1184  glEnable(GL_LIGHTING);
1185  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
1186  glShadeModel(GL_SMOOTH);
1187 
1188  // Parcours des arêtes.
1189  for (C.reinit(); C.cont(); C++)
1190  {
1191  CDart* d = *C;
1192 
1193  //Si le brin n'est pas marqué.
1194  if (!G->isMarked(d, markEdge) && !G->isFree0(d))
1195  {
1196  // Récupération de la liste d'affichage de l'arête.
1197  CAttribute* alpha = G->getAttribute(d, ORBIT_023,PT_LIST_ATTRIBUTE_ID);
1198 
1199  // Affichage des facettes.
1200  Draw_List(((Point_List*)alpha)->Get_Data(), 4);
1201 
1202  // Parcours et marquage des brins de l'arête.
1203  CCoverage* DCe = G->getDynamicCoverage(d, ORBIT_023);
1204  for(DCe->reinit(); DCe->cont(); (*DCe)++)
1205  G->setMark(**DCe, markEdge);
1206  delete DCe;
1207  }
1208  }
1209 
1210  // Parcours et démarquage des brins de la G-carte.
1211  for (C.reinit(); C.cont(); C++)
1212  G->unsetMark(*C, markEdge);
1213  G->freeMark(markEdge);
1214 
1215 
1216  // Désactivation de l'éclairage
1217  glDisable(GL_LIGHTING);
1218  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
1219  glShadeModel(GL_FLAT);
1220 }
1221 
1222 
1223 /******************************************************************************
1224  * Fonction : void Analytic_View::Faces_Draw() *
1225  *----------------------------------------------------------------------------*
1226  * Cette fonction affiche les facettes des faces. *
1227  * *
1228  *****************************************************************************/
1229 
1230 void Analytic_View::Faces_Draw()
1231 {
1232  CAttribute *alpha;
1233 
1234  int nbPoints;
1235 
1236  // Création d'une marque.
1237  int markFace = G->getNewMark();
1238 
1239  // Création d'un parcours des brins de la G-carte.
1240  CDynamicCoverageAll C(G);
1241 
1242  // Activation de l'éclairage
1243  glEnable(GL_LIGHTING);
1244  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
1245  glShadeModel(GL_SMOOTH);
1246 
1247  // Parcours des faces.
1248  for (C.reinit(); C.cont(); C++)
1249  {
1250  CDart* d = *C;
1251 
1252  // Si le brin n'est pas marqué.
1253  if(!G->isMarked(d, markFace) && G->getEmbeddingOwner(d, ORBIT_013))
1254  {
1255  // Récupération du nombre de sommets de la face.
1256  alpha = G->getAttribute(d, ORBIT_013, INT_ATTRIBUTE_ID);
1257  nbPoints = *(((Int_Att*)alpha)->Get_Data());
1258 
1259  // Récupération de la liste d'affichage de la face.
1260  alpha = G->getAttribute(d, ORBIT_013, PT_LIST_ATTRIBUTE_ID);
1261 
1262  // Affichage des facettes.
1263  Draw_List(((Point_List*)alpha)->Get_Data(), nbPoints);
1264 
1265  // Marquage des brins de l'orbite ORBIT_013.
1266  CCoverage* DCf = G->getDynamicCoverage(d, ORBIT_013);
1267  for(DCf->reinit(); DCf->cont(); (*DCf)++)
1268  G->setMark(**DCf, markFace);
1269  delete DCf;
1270  }
1271  }
1272 
1273  // Parcours et démarquage des brins de la G-carte.
1274  for (C.reinit(); C.cont(); C++)
1275  G->unsetMark(*C, markFace);
1276  G->freeMark(markFace);
1277 
1278 
1279  // Désactivation de l'éclairage
1280  glDisable(GL_LIGHTING);
1281  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
1282  glShadeModel(GL_FLAT);
1283 }