topology.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. /*************************************/
  2. /* Auteur : Rémi Synave */
  3. /* Date de création : 01/03/07 */
  4. /* Date de modification : 15/03/15 */
  5. /* Version : 0.4 */
  6. /*************************************/
  7. /***************************************************************************/
  8. /* This file is part of a2ri. */
  9. /* */
  10. /* a2ri is free software: you can redistribute it and/or modify it */
  11. /* under the terms of the GNU Lesser General Public License as published */
  12. /* by the Free Software Foundation, either version 3 of the License, or */
  13. /* (at your option) any later version. */
  14. /* */
  15. /* a2ri 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 */
  21. /* License along with a2ri. */
  22. /* If not, see <http://www.gnu.org/licenses/>. */
  23. /***************************************************************************/
  24. #include "topology.h"
  25. /********** INTERMEDIATE TYPES AND FUNCTIONS **********/
  26. /* Les fonctions intermédiaires sont préfixées de IF */
  27. /* et les types intermédiaires de IT */
  28. typedef struct
  29. {
  30. int *list;
  31. int nbelt;
  32. } ITlistecouple;
  33. void
  34. IFstar_byedge (
  35. const vf_model * const m,
  36. int ** list,
  37. int * size,
  38. int depth,
  39. const hashtable * const table)
  40. {
  41. int sizetemp = *size;
  42. vf_edge *edgetemp;
  43. if (depth == 0)
  44. return;
  45. for (int i = 0; i < sizetemp; i++)
  46. {
  47. int ve1 = m->fa[(*list)[i]].ve1;
  48. int ve2 = m->fa[(*list)[i]].ve2;
  49. int ve3 = m->fa[(*list)[i]].ve3;
  50. //1ere arete
  51. edgetemp = hashtable_look_for (table, ve1, ve2);
  52. if (edgetemp->nbsharedfaces == 2)
  53. {
  54. if (edgetemp->sharedfaces[0] == (*list)[i])
  55. list_int_add (list, size, edgetemp->sharedfaces[1],
  56. WITHOUT_REDUNDANCE);
  57. else
  58. list_int_add (list, size, edgetemp->sharedfaces[0],
  59. WITHOUT_REDUNDANCE);
  60. }
  61. //2eme arete
  62. edgetemp = hashtable_look_for (table, ve1, ve3);
  63. if (edgetemp->nbsharedfaces == 2)
  64. {
  65. if (edgetemp->sharedfaces[0] == (*list)[i])
  66. list_int_add (list, size, edgetemp->sharedfaces[1],
  67. WITHOUT_REDUNDANCE);
  68. else
  69. list_int_add (list, size, edgetemp->sharedfaces[0],
  70. WITHOUT_REDUNDANCE);
  71. }
  72. //3eme arete
  73. edgetemp = hashtable_look_for (table, ve2, ve3);
  74. if (edgetemp->nbsharedfaces == 2)
  75. {
  76. if (edgetemp->sharedfaces[0] == (*list)[i])
  77. list_int_add (list, size, edgetemp->sharedfaces[1],
  78. WITHOUT_REDUNDANCE);
  79. else
  80. list_int_add (list, size, edgetemp->sharedfaces[0],
  81. WITHOUT_REDUNDANCE);
  82. }
  83. }
  84. IFstar_byedge (m, list, size, depth - 1, table);
  85. }
  86. void
  87. IFstar_byvertex (
  88. const vf_model * const m,
  89. int **list,
  90. int *size,
  91. int depth,
  92. const hashtable * const table)
  93. {
  94. int sizetemp = *size;
  95. vf_edge *edgetemp;
  96. int ve[3];
  97. if (depth == 0)
  98. return;
  99. for (int i = 0; i < sizetemp; i++)
  100. {
  101. ve[0] = m->fa[(*list)[i]].ve1;
  102. ve[1] = m->fa[(*list)[i]].ve2;
  103. ve[2] = m->fa[(*list)[i]].ve3;
  104. for (int j = 0; j < 3; j++)
  105. {
  106. for (int k = 0; k < m->ve[ve[j]].nbincidentvertices; k++)
  107. {
  108. edgetemp =
  109. hashtable_look_for (table, ve[j],
  110. m->ve[ve[j]].incidentvertices[k]);
  111. for (int l = 0; l < edgetemp->nbsharedfaces; l++)
  112. if (edgetemp->sharedfaces[l] != (*list)[i])
  113. list_int_add (list, size, edgetemp->sharedfaces[l],
  114. WITHOUT_REDUNDANCE);
  115. }
  116. }
  117. }
  118. IFstar_byvertex (m, list, size, depth - 1, table);
  119. }
  120. //on cherche les aretes qui ne partagent qu'une seule face et on ajoute leur sommet dans une liste
  121. //résultat : la liste des sommets appartenant au bord du maillage
  122. void
  123. IFlook_for_border (
  124. int key,
  125. vf_edge * value,
  126. void *user_data)
  127. {
  128. ITlistecouple *list = user_data;
  129. if (value->nbsharedfaces == 1)
  130. {
  131. list_int_add (&(list->list), &(list->nbelt), value->ve1,
  132. WITH_REDUNDANCE);
  133. list_int_add (&(list->list), &(list->nbelt), value->ve2,
  134. WITH_REDUNDANCE);
  135. }
  136. }
  137. //on cherche à retrouver un cycle dans la liste des sommets appartenant au bord du maillage
  138. void
  139. IFcycle (
  140. ITlistecouple * list,
  141. ITlistecouple * cycle)
  142. {
  143. int trouve = 1;
  144. int next = (*list).list[1];
  145. //on ajoute le premier et le second sommet
  146. list_int_add (&(cycle->list), &(cycle->nbelt), (*list).list[0],
  147. WITH_REDUNDANCE);
  148. list_int_add (&(cycle->list), &(cycle->nbelt), (*list).list[1],
  149. WITH_REDUNDANCE);
  150. while (next != (*list).list[0] && trouve)
  151. {
  152. trouve = 0;
  153. //dans le reste de la liste, on cherche le couple dont le premier element correspond au dernier element ajouté
  154. for (int i = 0; i < (*list).nbelt / 2; i++)
  155. {
  156. if ((*list).list[i * 2] == cycle->list[(cycle->nbelt) - 1])
  157. {
  158. //on a correspondance entre le premier element du couple et le dernier element ajouté
  159. if ((*list).list[i * 2 + 1] != (*list).list[0])
  160. {
  161. //l'element trouvé ne correpond pas au premier element
  162. //on ajoute donc le sommet suivant
  163. list_int_add (&(cycle->list), &(cycle->nbelt),
  164. (*list).list[i * 2 + 1], WITH_REDUNDANCE);
  165. next = (*list).list[i * 2 + 1];
  166. list_int_remove (&((*list).list), &((*list).nbelt),
  167. i * 2 + 1);
  168. list_int_remove (&((*list).list), &((*list).nbelt), i * 2);
  169. }
  170. else
  171. {
  172. //on a correpondance entre l'element à ajouter et le premier élément donc nous avons trouvé un cycle
  173. next = (*list).list[0];
  174. list_int_add (&(cycle->list), &(cycle->nbelt),
  175. -1, WITH_REDUNDANCE);
  176. //on termine l'algorithme en mettant next à la valeur du premier element
  177. list_int_remove (&((*list).list), &((*list).nbelt),
  178. i * 2 + 1);
  179. list_int_remove (&((*list).list), &((*list).nbelt), i * 2);
  180. }
  181. trouve = 1;
  182. }
  183. }
  184. }
  185. list_int_remove (&((*list).list), &((*list).nbelt), 1);
  186. list_int_remove (&((*list).list), &((*list).nbelt), 0);
  187. }
  188. void
  189. IFvf_complete_partie_connexe (
  190. const vf_model * const m,
  191. const hashtable * const table,
  192. int *list,
  193. int numface,
  194. int numpartie,
  195. int *nbaffect,
  196. int *nbrecurs)
  197. {
  198. int p1,
  199. p2;
  200. printf("nbrecurs : %d\n",*nbrecurs);
  201. *nbrecurs=*nbrecurs+1;
  202. if (list[numface] != -1)
  203. return;
  204. //la première face est affectée du numéro de partie
  205. list[numface] = numpartie;
  206. *nbaffect = (*nbaffect) + 1;
  207. //pour la premiere arete de la face,
  208. p1 = m->fa[numface].ve1;
  209. p2 = m->fa[numface].ve2;
  210. //printf("blop3.5 - %d %d\n",p1,p2);
  211. vf_edge *edgetemp = hashtable_look_for (table, p1, p2);
  212. //printf("blop4\n");
  213. //on regarde si elle partage deux faces
  214. if (edgetemp->nbsharedfaces == 2)
  215. {
  216. //dans ce cas, on relance la fonction avec le meme modele, les memes aretes, la meme list de parties, le numero de la face partagée, le meme numéro de parties et le meme nombre de faces affecté
  217. if (edgetemp->sharedfaces[0] == numface)
  218. IFvf_complete_partie_connexe (m, table, list,
  219. edgetemp->sharedfaces[1], numpartie,
  220. nbaffect,nbrecurs);
  221. else
  222. IFvf_complete_partie_connexe (m, table, list,
  223. edgetemp->sharedfaces[0], numpartie,
  224. nbaffect,nbrecurs);
  225. }
  226. //printf("blop5\n");
  227. //on recommence l'opération précédente avec la seconde et la troisième arete de la face
  228. p1 = m->fa[numface].ve2;
  229. p2 = m->fa[numface].ve3;
  230. //printf("blop5.5 - %d %d\n",p1,p2);
  231. edgetemp = hashtable_look_for (table, p1, p2);
  232. //printf("blop6\n");
  233. if (edgetemp->nbsharedfaces == 2)
  234. {
  235. if (edgetemp->sharedfaces[0] == numface)
  236. IFvf_complete_partie_connexe (m, table, list,
  237. edgetemp->sharedfaces[1], numpartie,
  238. nbaffect,nbrecurs);
  239. else
  240. IFvf_complete_partie_connexe (m, table, list,
  241. edgetemp->sharedfaces[0], numpartie,
  242. nbaffect,nbrecurs);
  243. }
  244. //printf("blop7\n");
  245. p1 = m->fa[numface].ve3;
  246. p2 = m->fa[numface].ve1;
  247. //printf("blop7.5 - %d %d\n",p1,p2);
  248. edgetemp = hashtable_look_for (table, p1, p2);
  249. //printf("blop8\n");
  250. if (edgetemp->nbsharedfaces == 2)
  251. {
  252. if (edgetemp->sharedfaces[0] == numface)
  253. IFvf_complete_partie_connexe (m, table, list,
  254. edgetemp->sharedfaces[1], numpartie,
  255. nbaffect,nbrecurs);
  256. else
  257. IFvf_complete_partie_connexe (m, table, list,
  258. edgetemp->sharedfaces[0], numpartie,
  259. nbaffect,nbrecurs);
  260. }
  261. }
  262. void
  263. IFvef_complete_partie_connexe (
  264. const vef_model * const m,
  265. int *list,
  266. int numface,
  267. int numpartie,
  268. int *nbaffect)
  269. {
  270. int ed1 = m->fa[numface].ed1,
  271. ed2 = m->fa[numface].ed2,
  272. ed3 = m->fa[numface].ed3;
  273. char *temp = NULL;
  274. if (list[numface] != -1)
  275. return;
  276. temp = (char *) malloc (20 * sizeof (char));
  277. a2ri_erreur_critique_si (temp == NULL,
  278. "erreur allocation memoire pour temp\nIFvef_complete_partie_connexe");
  279. //la première face est affecté du numéro de partie
  280. list[numface] = numpartie;
  281. *nbaffect = (*nbaffect) + 1;
  282. //pour la premiere arete de la face,
  283. //on regarde si elle partage deux faces
  284. if (m->ed[ed1].nbsharedfaces == 2)
  285. {
  286. //dans ce cas, on relance la fonction avec le meme modele, les memes aretes, la meme list de parties, le numero de la face partagée, le meme numéro de parties et le meme nombre de faces affecté
  287. if (m->ed[ed1].sharedfaces[0] == numface)
  288. IFvef_complete_partie_connexe (m, list, m->ed[ed1].sharedfaces[1],
  289. numpartie, nbaffect);
  290. else
  291. IFvef_complete_partie_connexe (m, list, m->ed[ed1].sharedfaces[0],
  292. numpartie, nbaffect);
  293. }
  294. //on recommence l'opération précédente avec la seconde et la troisième arete de la face
  295. if (m->ed[ed2].nbsharedfaces == 2)
  296. {
  297. if (m->ed[ed2].sharedfaces[0] == numface)
  298. IFvef_complete_partie_connexe (m, list, m->ed[ed2].sharedfaces[1],
  299. numpartie, nbaffect);
  300. else
  301. IFvef_complete_partie_connexe (m, list, m->ed[ed2].sharedfaces[0],
  302. numpartie, nbaffect);
  303. }
  304. if (m->ed[ed3].nbsharedfaces == 2)
  305. {
  306. if (m->ed[ed3].sharedfaces[0] == numface)
  307. IFvef_complete_partie_connexe (m, list, m->ed[ed3].sharedfaces[1],
  308. numpartie, nbaffect);
  309. else
  310. IFvef_complete_partie_connexe (m, list, m->ed[ed3].sharedfaces[0],
  311. numpartie, nbaffect);
  312. }
  313. free (temp);
  314. }
  315. /********** MAIN FUNCTIONS **********/
  316. /**
  317. Recherche du voisinage pour une liste de faces et à une profondeur donnée
  318. @param type BYVERTEX ou BYEDGE <BR> BYVERTEX : recherche du voisinage par sommet <BR> BYEDGE : recherche du voisinage par arete.
  319. @param m le modèle
  320. @param faces tableau contenant les numéros des faces de d\303\251part
  321. @param nbfaces taille du tableau
  322. @param list pointeur sur le tableau des faces contenu dans le voisinage
  323. @param size pointeur sur le nombre de faces dans le voisinage
  324. @param depth profondeur du voisinage
  325. @return aucun
  326. */
  327. void
  328. a2ri_vf_star (
  329. int type,
  330. const vf_model * const m,
  331. const int * const faces,
  332. int nbfaces,
  333. int **list,
  334. int *size,
  335. int depth)
  336. {
  337. int *listclone = NULL;
  338. hashtable *table = a2ri_vf_construction_edge_table (m, NULL, 0);
  339. list_int_clone (faces, nbfaces, &listclone);
  340. *size = nbfaces;
  341. if (type == BYEDGE)
  342. {
  343. IFstar_byedge (m, &listclone, size, depth, table);
  344. *list = listclone;
  345. }
  346. else
  347. {
  348. IFstar_byvertex (m, &listclone, size, depth, table);
  349. *list = listclone;
  350. }
  351. hashtable_free (table);
  352. free (table);
  353. }
  354. /**
  355. Calcul du nombre de trous/nombre de limites dans le modèle
  356. @param m le modèle
  357. @return nombre de trous/limites
  358. */
  359. int
  360. a2ri_vf_nb_hole (
  361. const vf_model * const m)
  362. {
  363. int nbtrou = 0;
  364. ITlistecouple lescouples,
  365. lescycles;
  366. lescouples.list = NULL;
  367. lescouples.nbelt = 0;
  368. lescycles.list = NULL;
  369. lescycles.nbelt = 0;
  370. hashtable *table = a2ri_vf_construction_edge_table (m, NULL, 0);
  371. hashtable_foreach (table, IFlook_for_border, &lescouples);
  372. //si on ne trouve aucun sommet sur le bord du maillage
  373. if (lescouples.nbelt == 0)
  374. {
  375. hashtable_free (table);
  376. free (table);
  377. free (lescouples.list);
  378. free (lescycles.list);
  379. //il n'y a pas de trou
  380. return nbtrou;
  381. }
  382. #ifdef _DEBUG
  383. printf("--> lescouples\n");
  384. list_int_display(lescouples.list,lescouples.nbelt);
  385. #endif
  386. //sinon tant qu'on a des elements dans la liste, on cherche un nouveau cycle
  387. while (lescouples.nbelt != 0)
  388. {
  389. IFcycle (&lescouples, &lescycles);
  390. //le nombre de cycle correspond au nombre de trou
  391. nbtrou++;
  392. }
  393. #ifdef _DEBUG
  394. printf("--> lescycles\n");
  395. list_int_display(lescycles.list,lescycles.nbelt);
  396. #endif
  397. hashtable_free (table);
  398. free (table);
  399. free (lescouples.list);
  400. free (lescycles.list);
  401. return nbtrou;
  402. }
  403. /**
  404. Calcul du nombre de trous/nombre de limites dans le modèle
  405. @param m le modèle
  406. @return nombre de trous/limites
  407. */
  408. int
  409. a2ri_vef_nb_hole (
  410. const vef_model * const m)
  411. {
  412. int nbtrou = 0;
  413. ITlistecouple lescouples,
  414. lescycles;
  415. lescouples.list = NULL;
  416. lescouples.nbelt = 0;
  417. lescycles.list = NULL;
  418. lescycles.nbelt = 0;
  419. for (int i = 0; i < m->nbedge; i++)
  420. if (m->ed[i].nbsharedfaces == 1)
  421. {
  422. list_int_add (&(lescouples.list), &(lescouples.nbelt), m->ed[i].ve1,
  423. WITH_REDUNDANCE);
  424. list_int_add (&(lescouples.list), &(lescouples.nbelt), m->ed[i].ve2,
  425. WITH_REDUNDANCE);
  426. }
  427. //si on ne trouve aucun sommet sur le bord du maillage
  428. if (lescouples.nbelt == 0)
  429. //il n'y a pas de trou
  430. return nbtrou;
  431. //sinon tant qu'on a des elements dans la liste, on cherche un nouveau cycle
  432. while (lescouples.nbelt != 0)
  433. {
  434. IFcycle (&lescouples, &lescycles);
  435. //le nombre de cycle correspond au nombre de trou
  436. nbtrou++;
  437. }
  438. free (lescouples.list);
  439. free (lescycles.list);
  440. return nbtrou;
  441. }
  442. /**
  443. Calcul du nombre de parties connexes contenu dans le modèle
  444. @param m le modèle
  445. @param list tableau d'entier représentant les faces du modèle et contenant le numéro de la partie à laquelle la face appartient.
  446. @return nombre de parties connexes
  447. */
  448. int
  449. a2ri_vf_nb_connected_part (
  450. const vf_model * const m,
  451. int **list)
  452. {
  453. int nbpart = 0,
  454. nbaffect = 0,
  455. nbrecurs=0,
  456. j;
  457. int *parties = NULL;
  458. parties = (int *) malloc (m->nbface * sizeof (int));
  459. a2ri_erreur_critique_si (parties == NULL,
  460. "erreur allocation memoire pour parties\na2ri_vf_nb_connected_part");
  461. //parties sera le tableau qui donnera le numero de la parties à laquelle apparient la face du meme index
  462. // les parties sont initialisées à -1
  463. for (int i = 0; i < m->nbface; i++)
  464. parties[i] = -1;
  465. hashtable *table = a2ri_vf_construction_edge_table (m, NULL, 0);
  466. //tant que toutes les faces n'ont pas trouvées de numéro de parties, on continu
  467. while (nbaffect != m->nbface)
  468. {
  469. nbrecurs=0;
  470. j = 0;
  471. //on cherche la première face n'ayant pas de numéro de parties donc ne faisant parties d'aucun groupe
  472. while (parties[j] != -1)
  473. j++;
  474. //on appelle la fonction avec le modèle, les aretes, le tableau des parties, le numéro de la première face, le numéro de la nouvelle partie et enfin le nombre de face deja affecté d'un numéro de parties
  475. IFvf_complete_partie_connexe (m, table, parties, j, nbpart,
  476. &nbaffect,&nbrecurs);
  477. //nous avons trouvé une nouvelle partie
  478. nbpart++;
  479. }
  480. *list = parties;
  481. hashtable_free (table);
  482. free (table);
  483. return nbpart;
  484. }
  485. /**
  486. Calcul du nombre de parties connexes contenu dans le modèle
  487. @param m le modèle
  488. @param list tableau d'entier représentant les faces du modèle et contenant le numéro de la partie à laquelle la face appartient.
  489. @return nombre de parties connexes
  490. */
  491. int
  492. a2ri_vef_nb_connected_part (
  493. const vef_model * const m,
  494. int **list)
  495. {
  496. int nbpart = 0,
  497. nbaffect = 0,
  498. j;
  499. int *parties = NULL;
  500. parties = (int *) malloc (m->nbface * sizeof (int));
  501. a2ri_erreur_critique_si (parties == NULL,
  502. "erreur allocation memoire pour parties\na2ri_vef_nb_connected_part");
  503. //parties sera le tableau qui donnera le numero de la parties à laquelle apparient la face du meme index
  504. // les parties sont initialisées à -1
  505. for (int i = 0; i < m->nbface; i++)
  506. parties[i] = -1;
  507. //tant que toutes les faces n'ont pas trouvées de numéro de parties, on continu
  508. while (nbaffect != m->nbface)
  509. {
  510. j = 0;
  511. //on cherche la première face n'ayant pas de numéro de parties donc ne faisant parties d'aucun groupe
  512. while (parties[j] != -1)
  513. j++;
  514. //on appelle la fonction avec le modèle, les aretes, le tableau des parties, le numéro de la première face, le numéro de la nouvelle partie et enfin le nombre de face deja affecté d'un numéro de parties
  515. IFvef_complete_partie_connexe (m, parties, j, nbpart, &nbaffect);
  516. //nous avons trouvé une nouvelle partie
  517. nbpart++;
  518. }
  519. *list = parties;
  520. return nbpart;
  521. }
  522. /**
  523. Cherche un trou/cycle dans le maillage contenant les deux sommets
  524. @param m le modele
  525. @param ve1 premier sommet qui doit etre contenu dans le cycle
  526. @param ve2 second sommet qui doit etre contenu dans le cycle
  527. @param list liste des sommets formant le cycle
  528. @param size taille de la liste
  529. **/
  530. void
  531. a2ri_vf_search_hole_contains (
  532. const vf_model * const m,
  533. int ve1,
  534. int ve2,
  535. int ** list,
  536. int * size)
  537. {
  538. ITlistecouple lescouples,
  539. lescycles;
  540. lescouples.list = NULL;
  541. lescouples.nbelt = 0;
  542. lescycles.list = NULL;
  543. lescycles.nbelt = 0;
  544. hashtable *table = a2ri_vf_construction_edge_table (m, NULL, 0);
  545. hashtable_foreach (table, IFlook_for_border, &lescouples);
  546. //si on ne trouve aucun sommet sur le bord du maillage
  547. if (lescouples.nbelt == 0)
  548. {
  549. hashtable_free (table);
  550. free (table);
  551. free (lescouples.list);
  552. free (lescycles.list);
  553. //il n'y a pas de trou
  554. *list = NULL;
  555. *size = 0;
  556. return;
  557. }
  558. //sinon tant qu'on a des elements dans la liste, on cherche un nouveau cycle
  559. while (lescouples.nbelt != 0)
  560. {
  561. IFcycle (&lescouples, &lescycles);
  562. //le nombre de cycle correspond au nombre de trou
  563. if (list_int_contains (lescycles.list, lescycles.nbelt, ve1) != -1 &&
  564. list_int_contains (lescycles.list, lescycles.nbelt, ve2) != -1)
  565. {
  566. *list = lescycles.list;
  567. *size = lescycles.nbelt;
  568. free (lescouples.list);
  569. hashtable_free (table);
  570. free (table);
  571. return;
  572. }
  573. free (lescycles.list);
  574. lescycles.list = NULL;
  575. lescycles.nbelt = 0;
  576. }
  577. hashtable_free (table);
  578. free (table);
  579. free (lescouples.list);
  580. free (lescycles.list);
  581. *list = NULL;
  582. *size = 0;
  583. return;
  584. }