triangulation.c 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705
  1. /*************************************/
  2. /* Auteur : Rémi Synave */
  3. /* Date de création : 15/05/08 */
  4. /* Date de modification : 15/03/15 */
  5. /* Version : 0.4 */
  6. /*************************************/
  7. /*************************************/
  8. /* Auteur : Romain Leguay */
  9. /* Nguyen Haiduong */
  10. /* Solange Houeto */
  11. /* Marianne Fichoux */
  12. /* Date de modification : 08/06/09 */
  13. /* Version : 0.2 */
  14. /*************************************/
  15. /***************************************************************************/
  16. /* This file is part of a2ri. */
  17. /* */
  18. /* a2ri is free software: you can redistribute it and/or modify it */
  19. /* under the terms of the GNU Lesser General Public License as published */
  20. /* by the Free Software Foundation, either version 3 of the License, or */
  21. /* (at your option) any later version. */
  22. /* */
  23. /* a2ri is distributed in the hope that it will be useful, */
  24. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  25. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  26. /* GNU Lesser General Public License for more details. */
  27. /* */
  28. /* You should have received a copy of the GNU Lesser General Public */
  29. /* License along with a2ri. */
  30. /* If not, see <http://www.gnu.org/licenses/>. */
  31. /***************************************************************************/
  32. #include "triangulation.h"
  33. /********** INTERMEDIATE TYPES AND FUNCTIONS **********/
  34. /* Les fonctions intermédiaires sont préfixées de IF */
  35. /* et les types intermédiaires de IT */
  36. typedef struct
  37. {
  38. point3d *liste_centre1,
  39. *liste_centre2;
  40. double *liste_rayon1,
  41. *liste_rayon2;
  42. double sensibility;
  43. int nbtest1deb,
  44. nbtest1fin,
  45. nbtest2;
  46. int **asupprimer,
  47. *nbelt;
  48. } ITnettoyage_thread_argument;
  49. typedef struct
  50. {
  51. int *list;
  52. int nbelt;
  53. } IT_bpa_liste;
  54. void *
  55. IFthread_process_nettoyage (
  56. void *argu)
  57. {
  58. ITnettoyage_thread_argument *arg =
  59. (ITnettoyage_thread_argument *) argu;
  60. *(arg->asupprimer) = NULL;
  61. *(arg->nbelt) = 0;
  62. for (int i = arg->nbtest1deb; i <= arg->nbtest1fin; i++)
  63. {
  64. if (!intersection_bounding_ball_with_bounding_ball_list
  65. (&(arg->liste_centre1[i]), arg->liste_rayon1[i], arg->liste_centre2,
  66. arg->liste_rayon2, arg->nbtest2, arg->sensibility))
  67. list_int_add (arg->asupprimer, arg->nbelt, i, WITH_REDUNDANCE);
  68. }
  69. pthread_exit (0);
  70. }
  71. //on cherche les aretes qui ne partagent qu'une seule face et on ajoute leur sommet dans une liste
  72. //résultat : la liste des sommets appartenant au bord du maillage
  73. void
  74. IF_bpa_look_for_border (
  75. int key,
  76. vf_edge * value,
  77. void *user_data)
  78. {
  79. IT_bpa_liste *list = user_data;
  80. if (value->nbsharedfaces == 1)
  81. {
  82. list_int_add (&(list->list), &(list->nbelt), value->ve1,
  83. WITH_REDUNDANCE);
  84. list_int_add (&(list->list), &(list->nbelt), value->ve2,
  85. WITH_REDUNDANCE);
  86. }
  87. }
  88. //on cherche à retrouver un cycle dans la liste des sommets appartenant au bord du maillage
  89. void
  90. IF_bpa_cycle (
  91. IT_bpa_liste * list,
  92. IT_bpa_liste * cycle)
  93. {
  94. int trouve = 1;
  95. int next = (*list).list[1];
  96. //on ajoute le premier et le second sommet
  97. list_int_add (&(cycle->list), &(cycle->nbelt), (*list).list[0],
  98. WITH_REDUNDANCE);
  99. list_int_add (&(cycle->list), &(cycle->nbelt), (*list).list[1],
  100. WITH_REDUNDANCE);
  101. while (next != (*list).list[0] && trouve)
  102. {
  103. trouve = 0;
  104. //dans le reste de la liste, on cherche le couple dont le premier element correspond au dernier element ajouté
  105. for (int i = 0; i < (*list).nbelt / 2; i++)
  106. {
  107. if ((*list).list[i * 2] == cycle->list[(cycle->nbelt) - 1])
  108. {
  109. //on a correspondance entre le premier element du couple et le dernier element ajouté
  110. if ((*list).list[i * 2 + 1] != (*list).list[0])
  111. {
  112. //l'element trouvé ne correpond pas au premier element
  113. //on ajoute donc le sommet suivant
  114. list_int_add (&(cycle->list), &(cycle->nbelt),
  115. (*list).list[i * 2 + 1], WITH_REDUNDANCE);
  116. next = (*list).list[i * 2 + 1];
  117. list_int_remove (&((*list).list), &((*list).nbelt),
  118. i * 2 + 1);
  119. list_int_remove (&((*list).list), &((*list).nbelt), i * 2);
  120. }
  121. else
  122. {
  123. //on a correpondance entre l'element à ajouter et le premier élément donc nous avons trouvé un cycle
  124. next = (*list).list[0];
  125. list_int_add (&(cycle->list), &(cycle->nbelt),
  126. -1, WITH_REDUNDANCE);
  127. //on termine l'algorithme en mettant next à la valeur du premier element
  128. list_int_remove (&((*list).list), &((*list).nbelt),
  129. i * 2 + 1);
  130. list_int_remove (&((*list).list), &((*list).nbelt), i * 2);
  131. }
  132. trouve = 1;
  133. }
  134. }
  135. }
  136. list_int_remove (&((*list).list), &((*list).nbelt), 1);
  137. list_int_remove (&((*list).list), &((*list).nbelt), 0);
  138. }
  139. //recherche de cycle dans les arêtes du bord du modèle
  140. int IF_bpa_vf_hole (vf_model * m, IT_bpa_liste *lescycles)
  141. {
  142. int nbtrou = 0;
  143. IT_bpa_liste lescouples;
  144. lescouples.list = NULL;
  145. lescouples.nbelt = 0;
  146. lescycles->list = NULL;
  147. lescycles->nbelt = 0;
  148. hashtable *table = a2ri_vf_construction_edge_table (m, NULL, 0);
  149. hashtable_foreach (table, IF_bpa_look_for_border, &lescouples);
  150. //si on ne trouve aucun sommet sur le bord du maillage
  151. if (lescouples.nbelt == 0)
  152. {
  153. hashtable_free (table);
  154. free (table);
  155. free (lescouples.list);
  156. //il n'y a pas de trou
  157. return nbtrou;
  158. }
  159. //sinon tant qu'on a des elements dans la liste, on cherche un nouveau cycle
  160. while (lescouples.nbelt != 0)
  161. {
  162. IF_bpa_cycle (&lescouples, lescycles);
  163. //le nombre de cycle correspond au nombre de trou
  164. nbtrou++;
  165. }
  166. hashtable_free (table);
  167. free (table);
  168. free (lescouples.list);
  169. return nbtrou;
  170. }
  171. /********** MAIN FUNCTIONS **********/
  172. /**
  173. Nettoyage par suppression des faces dans la zone de recouvrement
  174. @param base,m 2 vf_model
  175. @return aucun
  176. **/
  177. void
  178. nettoyage_delete_face (
  179. vf_model * base,
  180. vf_model * m,
  181. double sensibility)
  182. {
  183. hashtable *table = NULL;
  184. int recouvrement = 1;
  185. int tour = -1;
  186. int *candidat_m = NULL,
  187. size_candidat_m = 0,
  188. *candidat_base = NULL,
  189. size_candidat_base = 0;
  190. double *listrayonmodelm = NULL,
  191. *listrayonbase = NULL;
  192. point3d *listcentrebase = NULL,
  193. *listcentremodelm = NULL;
  194. a2ri_time deptotal,
  195. fintotal,
  196. depinter,
  197. fininter,
  198. depMAJ,
  199. finMAJ,
  200. depBB,
  201. finBB;
  202. double totalinter = 0,
  203. totalMAJ = 0;
  204. deptotal = a2ri_get_time ();
  205. pthread_t th[A2RI_NB_THREAD];
  206. ITnettoyage_thread_argument argument[A2RI_NB_THREAD];
  207. void *ret[A2RI_NB_THREAD];
  208. int *liste_a_supprimer[A2RI_NB_THREAD],
  209. size_liste_a_supprimer[A2RI_NB_THREAD];
  210. for (int i = 0; i < A2RI_NB_THREAD; i++)
  211. {
  212. liste_a_supprimer[i] = NULL;
  213. size_liste_a_supprimer[i] = 0;
  214. }
  215. //on va demander les bounding ball de toutes les faces des deux modèles
  216. candidat_m = (int *) malloc (m->nbface * sizeof (int));
  217. a2ri_erreur_critique_si (candidat_m == NULL,
  218. "erreur allocation memoire pour candidat_m\nnettoyage_delete_face");
  219. candidat_base = (int *) malloc (base->nbface * sizeof (int));
  220. a2ri_erreur_critique_si (candidat_base == NULL,
  221. "erreur allocation memoire pour candidat_base\nnettoyage_delete_face");
  222. for (int i = 0; i < m->nbface; i++)
  223. candidat_m[i] = i;
  224. size_candidat_m = m->nbface;
  225. for (int i = 0; i < base->nbface; i++)
  226. candidat_base[i] = i;
  227. size_candidat_base = base->nbface;
  228. //récupère toutes les bounding sphere de toutes les faces des modeles base et m
  229. depBB = a2ri_get_time ();
  230. a2ri_vf_bounding_ball_minimale (base,
  231. candidat_base,
  232. size_candidat_base,
  233. &listcentrebase,
  234. &listrayonbase);
  235. a2ri_vf_bounding_ball_minimale (m,
  236. candidat_m,
  237. size_candidat_m,
  238. &listcentremodelm,
  239. &listrayonmodelm);
  240. finBB = a2ri_get_time ();
  241. while (recouvrement)
  242. {
  243. tour++;
  244. for (int i = 0; i < A2RI_NB_THREAD; i++)
  245. {
  246. free (liste_a_supprimer[i]);
  247. liste_a_supprimer[i] = NULL;
  248. size_liste_a_supprimer[i] = 0;
  249. }
  250. /*mettre le numero des faces dans la zone de recouvrement de
  251. 2 vf_model dans 2 listes */
  252. if (tour == 0)
  253. {
  254. depinter = a2ri_get_time ();
  255. for (int i = 0; i < A2RI_NB_THREAD - 1; i++)
  256. {
  257. argument[i].liste_centre2 = listcentrebase;
  258. argument[i].liste_rayon2 = listrayonbase;
  259. argument[i].nbtest2 = size_candidat_base;
  260. argument[i].nbtest1deb = (size_candidat_m / A2RI_NB_THREAD) * i;
  261. argument[i].nbtest1fin =
  262. (size_candidat_m / A2RI_NB_THREAD) * (i + 1) - 1;
  263. argument[i].liste_centre1 = listcentremodelm;
  264. argument[i].liste_rayon1 = listrayonmodelm;
  265. argument[i].sensibility = sensibility;
  266. argument[i].asupprimer = &liste_a_supprimer[i];
  267. argument[i].nbelt = &size_liste_a_supprimer[i];
  268. }
  269. argument[A2RI_NB_THREAD - 1].liste_centre2 = listcentrebase;
  270. argument[A2RI_NB_THREAD - 1].liste_rayon2 = listrayonbase;
  271. argument[A2RI_NB_THREAD - 1].nbtest2 = size_candidat_base;
  272. argument[A2RI_NB_THREAD - 1].nbtest1deb =
  273. (size_candidat_m / A2RI_NB_THREAD) * (A2RI_NB_THREAD - 1);
  274. argument[A2RI_NB_THREAD - 1].nbtest1fin = size_candidat_m - 1;
  275. argument[A2RI_NB_THREAD - 1].liste_centre1 = listcentremodelm;
  276. argument[A2RI_NB_THREAD - 1].liste_rayon1 = listrayonmodelm;
  277. argument[A2RI_NB_THREAD - 1].sensibility = sensibility;
  278. argument[A2RI_NB_THREAD - 1].asupprimer =
  279. &liste_a_supprimer[A2RI_NB_THREAD - 1];
  280. argument[A2RI_NB_THREAD - 1].nbelt =
  281. &size_liste_a_supprimer[A2RI_NB_THREAD - 1];
  282. for (int i = 0; i < A2RI_NB_THREAD; i++)
  283. {
  284. if (pthread_create
  285. (th + i, NULL, IFthread_process_nettoyage, argument + i) < 0)
  286. exit (1);
  287. }
  288. for (int i = 0; i < A2RI_NB_THREAD; i++)
  289. (void) pthread_join (th[i], &ret[i]);
  290. for (int i = A2RI_NB_THREAD - 1; i >= 0; i--)
  291. {
  292. for (int j = size_liste_a_supprimer[i] - 1; j >= 0; j--)
  293. {
  294. list_int_remove (&candidat_m, &size_candidat_m,
  295. liste_a_supprimer[i][j]);
  296. size_candidat_m++;
  297. list_double_remove (&listrayonmodelm, &size_candidat_m,
  298. liste_a_supprimer[i][j]);
  299. size_candidat_m++;
  300. list_point3d_remove (&listcentremodelm, &size_candidat_m,
  301. liste_a_supprimer[i][j]);
  302. }
  303. free (liste_a_supprimer[i]);
  304. liste_a_supprimer[i] = NULL;
  305. size_liste_a_supprimer[i] = 0;
  306. }
  307. for (int i = 0; i < A2RI_NB_THREAD - 1; i++)
  308. {
  309. argument[i].liste_centre2 = listcentremodelm;
  310. argument[i].liste_rayon2 = listrayonmodelm;
  311. argument[i].nbtest2 = size_candidat_m;
  312. argument[i].nbtest1deb =
  313. (size_candidat_base / A2RI_NB_THREAD) * i;
  314. argument[i].nbtest1fin =
  315. (size_candidat_base / A2RI_NB_THREAD) * (i + 1) - 1;
  316. argument[i].liste_centre1 = listcentrebase;
  317. argument[i].liste_rayon1 = listrayonbase;
  318. argument[i].sensibility = sensibility;
  319. argument[i].asupprimer = &liste_a_supprimer[i];
  320. argument[i].nbelt = &size_liste_a_supprimer[i];
  321. }
  322. argument[A2RI_NB_THREAD - 1].liste_centre2 = listcentremodelm;
  323. argument[A2RI_NB_THREAD - 1].liste_rayon2 = listrayonmodelm;
  324. argument[A2RI_NB_THREAD - 1].nbtest2 = size_candidat_m;
  325. argument[A2RI_NB_THREAD - 1].nbtest1deb =
  326. (size_candidat_base / A2RI_NB_THREAD) * (A2RI_NB_THREAD - 1);
  327. argument[A2RI_NB_THREAD - 1].nbtest1fin = size_candidat_base - 1;
  328. argument[A2RI_NB_THREAD - 1].liste_centre1 = listcentrebase;
  329. argument[A2RI_NB_THREAD - 1].liste_rayon1 = listrayonbase;
  330. argument[A2RI_NB_THREAD - 1].sensibility = sensibility;
  331. argument[A2RI_NB_THREAD - 1].asupprimer =
  332. &liste_a_supprimer[A2RI_NB_THREAD - 1];
  333. argument[A2RI_NB_THREAD - 1].nbelt =
  334. &size_liste_a_supprimer[A2RI_NB_THREAD - 1];
  335. for (int i = 0; i < A2RI_NB_THREAD; i++)
  336. {
  337. if (pthread_create
  338. (th + i, NULL, IFthread_process_nettoyage, argument + i) < 0)
  339. exit (1);
  340. }
  341. for (int i = 0; i < A2RI_NB_THREAD; i++)
  342. (void) pthread_join (th[i], &ret[i]);
  343. for (int i = A2RI_NB_THREAD - 1; i >= 0; i--)
  344. {
  345. for (int j = size_liste_a_supprimer[i] - 1; j >= 0; j--)
  346. {
  347. list_int_remove (&candidat_base, &size_candidat_base,
  348. liste_a_supprimer[i][j]);
  349. size_candidat_base++;
  350. list_double_remove (&listrayonbase, &size_candidat_base,
  351. liste_a_supprimer[i][j]);
  352. size_candidat_base++;
  353. list_point3d_remove (&listcentrebase, &size_candidat_base,
  354. liste_a_supprimer[i][j]);
  355. }
  356. free (liste_a_supprimer[i]);
  357. liste_a_supprimer[i] = NULL;
  358. size_liste_a_supprimer[i] = 0;
  359. }
  360. fininter = a2ri_get_time ();
  361. totalinter += a2ri_time_interval_to_double (depinter, fininter);
  362. }
  363. else
  364. {
  365. if (tour % 2 == 0)
  366. {
  367. depinter = a2ri_get_time ();
  368. for (int i = 0; i < A2RI_NB_THREAD - 1; i++)
  369. {
  370. argument[i].liste_centre2 = listcentrebase;
  371. argument[i].liste_rayon2 = listrayonbase;
  372. argument[i].nbtest2 = size_candidat_base;
  373. argument[i].nbtest1deb =
  374. (size_candidat_m / A2RI_NB_THREAD) * i;
  375. argument[i].nbtest1fin =
  376. (size_candidat_m / A2RI_NB_THREAD) * (i + 1) - 1;
  377. argument[i].liste_centre1 = listcentremodelm;
  378. argument[i].liste_rayon1 = listrayonmodelm;
  379. argument[i].sensibility = sensibility;
  380. argument[i].asupprimer = &liste_a_supprimer[i];
  381. argument[i].nbelt = &size_liste_a_supprimer[i];
  382. }
  383. argument[A2RI_NB_THREAD - 1].liste_centre2 = listcentrebase;
  384. argument[A2RI_NB_THREAD - 1].liste_rayon2 = listrayonbase;
  385. argument[A2RI_NB_THREAD - 1].nbtest2 = size_candidat_base;
  386. argument[A2RI_NB_THREAD - 1].nbtest1deb =
  387. (size_candidat_m / A2RI_NB_THREAD) * (A2RI_NB_THREAD - 1);
  388. argument[A2RI_NB_THREAD - 1].nbtest1fin = size_candidat_m - 1;
  389. argument[A2RI_NB_THREAD - 1].liste_centre1 = listcentremodelm;
  390. argument[A2RI_NB_THREAD - 1].liste_rayon1 = listrayonmodelm;
  391. argument[A2RI_NB_THREAD - 1].sensibility = sensibility;
  392. argument[A2RI_NB_THREAD - 1].asupprimer =
  393. &liste_a_supprimer[A2RI_NB_THREAD - 1];
  394. argument[A2RI_NB_THREAD - 1].nbelt =
  395. &size_liste_a_supprimer[A2RI_NB_THREAD - 1];
  396. for (int i = 0; i < A2RI_NB_THREAD; i++)
  397. {
  398. if (pthread_create
  399. (th + i, NULL, IFthread_process_nettoyage,
  400. argument + i) < 0)
  401. exit (1);
  402. }
  403. for (int i = 0; i < A2RI_NB_THREAD; i++)
  404. (void) pthread_join (th[i], &ret[i]);
  405. for (int i = A2RI_NB_THREAD - 1; i >= 0; i--)
  406. {
  407. for (int j = size_liste_a_supprimer[i] - 1; j >= 0; j--)
  408. {
  409. list_int_remove (&candidat_m, &size_candidat_m,
  410. liste_a_supprimer[i][j]);
  411. size_candidat_m++;
  412. list_double_remove (&listrayonmodelm, &size_candidat_m,
  413. liste_a_supprimer[i][j]);
  414. size_candidat_m++;
  415. list_point3d_remove (&listcentremodelm,
  416. &size_candidat_m,
  417. liste_a_supprimer[i][j]);
  418. }
  419. free (liste_a_supprimer[i]);
  420. liste_a_supprimer[i] = NULL;
  421. size_liste_a_supprimer[i] = 0;
  422. }
  423. fininter = a2ri_get_time ();
  424. totalinter += a2ri_time_interval_to_double (depinter, fininter);
  425. }
  426. if (tour % 2 == 1)
  427. {
  428. depinter = a2ri_get_time ();
  429. for (int i = 0; i < A2RI_NB_THREAD - 1; i++)
  430. {
  431. argument[i].liste_centre2 = listcentremodelm;
  432. argument[i].liste_rayon2 = listrayonmodelm;
  433. argument[i].nbtest2 = size_candidat_m;
  434. argument[i].nbtest1deb =
  435. (size_candidat_base / A2RI_NB_THREAD) * i;
  436. argument[i].nbtest1fin =
  437. (size_candidat_base / A2RI_NB_THREAD) * (i + 1) - 1;
  438. argument[i].liste_centre1 = listcentrebase;
  439. argument[i].liste_rayon1 = listrayonbase;
  440. argument[i].sensibility = sensibility;
  441. argument[i].asupprimer = &liste_a_supprimer[i];
  442. argument[i].nbelt = &size_liste_a_supprimer[i];
  443. }
  444. argument[A2RI_NB_THREAD - 1].liste_centre2 = listcentremodelm;
  445. argument[A2RI_NB_THREAD - 1].liste_rayon2 = listrayonmodelm;
  446. argument[A2RI_NB_THREAD - 1].nbtest2 = size_candidat_m;
  447. argument[A2RI_NB_THREAD - 1].nbtest1deb =
  448. (size_candidat_base / A2RI_NB_THREAD) * (A2RI_NB_THREAD - 1);
  449. argument[A2RI_NB_THREAD - 1].nbtest1fin =
  450. size_candidat_base - 1;
  451. argument[A2RI_NB_THREAD - 1].liste_centre1 = listcentrebase;
  452. argument[A2RI_NB_THREAD - 1].liste_rayon1 = listrayonbase;
  453. argument[A2RI_NB_THREAD - 1].sensibility = sensibility;
  454. argument[A2RI_NB_THREAD - 1].asupprimer =
  455. &liste_a_supprimer[A2RI_NB_THREAD - 1];
  456. argument[A2RI_NB_THREAD - 1].nbelt =
  457. &size_liste_a_supprimer[A2RI_NB_THREAD - 1];
  458. for (int i = 0; i < A2RI_NB_THREAD; i++)
  459. {
  460. if (pthread_create
  461. (th + i, NULL, IFthread_process_nettoyage,
  462. argument + i) < 0)
  463. exit (1);
  464. }
  465. for (int i = 0; i < A2RI_NB_THREAD; i++)
  466. (void) pthread_join (th[i], &ret[i]);
  467. for (int i = A2RI_NB_THREAD - 1; i >= 0; i--)
  468. {
  469. for (int j = size_liste_a_supprimer[i] - 1; j >= 0; j--)
  470. {
  471. list_int_remove (&candidat_base, &size_candidat_base,
  472. liste_a_supprimer[i][j]);
  473. size_candidat_base++;
  474. list_double_remove (&listrayonbase, &size_candidat_base,
  475. liste_a_supprimer[i][j]);
  476. size_candidat_base++;
  477. list_point3d_remove (&listcentrebase,
  478. &size_candidat_base,
  479. liste_a_supprimer[i][j]);
  480. }
  481. free (liste_a_supprimer[i]);
  482. liste_a_supprimer[i] = NULL;
  483. size_liste_a_supprimer[i] = 0;
  484. }
  485. fininter = a2ri_get_time ();
  486. totalinter += a2ri_time_interval_to_double (depinter, fininter);
  487. }
  488. }
  489. if ((size_candidat_m == 0) || (size_candidat_base == 0))
  490. recouvrement = 0;
  491. else
  492. {
  493. if (tour % 2 == 0)
  494. {
  495. //supprimer les faces se trouvant sur les bords du maillage
  496. //pour m
  497. depMAJ = a2ri_get_time ();
  498. table = a2ri_vf_construction_edge_table (m, NULL, 0);
  499. for (int i = 0; i < size_candidat_m; i++)
  500. {
  501. vf_edge *edgetemp1 =
  502. hashtable_look_for (table, m->fa[candidat_m[i]].ve1,
  503. m->fa[candidat_m[i]].ve2);
  504. vf_edge *edgetemp2 =
  505. hashtable_look_for (table, m->fa[candidat_m[i]].ve1,
  506. m->fa[candidat_m[i]].ve3);
  507. vf_edge *edgetemp3 =
  508. hashtable_look_for (table, m->fa[candidat_m[i]].ve2,
  509. m->fa[candidat_m[i]].ve3);
  510. if (edgetemp1->nbsharedfaces == 1
  511. || edgetemp2->nbsharedfaces == 1
  512. || edgetemp3->nbsharedfaces == 1)
  513. list_int_add (&liste_a_supprimer[0],
  514. &size_liste_a_supprimer[0], candidat_m[i],
  515. WITH_REDUNDANCE);
  516. }
  517. a2ri_vf_remove_list_of_face (m, liste_a_supprimer[0],
  518. size_liste_a_supprimer[0]);
  519. for (int i = 0; i < size_liste_a_supprimer[0]; i++)
  520. {
  521. int index;
  522. list_int_remove (&candidat_m, &size_candidat_m, index =
  523. list_int_contains (candidat_m,
  524. size_candidat_m,
  525. liste_a_supprimer[0]
  526. [i]));
  527. for (int j = index; j < size_candidat_m; j++)
  528. candidat_m[j] = candidat_m[j] - 1;
  529. size_candidat_m++;
  530. list_double_remove (&listrayonmodelm, &size_candidat_m,
  531. index);
  532. size_candidat_m++;
  533. list_point3d_remove (&listcentremodelm, &size_candidat_m,
  534. index);
  535. }
  536. if (size_liste_a_supprimer[0] == 0)
  537. recouvrement = 0;
  538. else
  539. recouvrement = 1;
  540. free (liste_a_supprimer[0]);
  541. liste_a_supprimer[0] = NULL;
  542. size_liste_a_supprimer[0] = 0;
  543. hashtable_free (table);
  544. table = NULL;
  545. finMAJ = a2ri_get_time ();
  546. totalMAJ += a2ri_time_interval_to_double (depMAJ, finMAJ);
  547. }
  548. if (tour % 2 == 1)
  549. {
  550. //pour base
  551. depMAJ = a2ri_get_time ();
  552. table = a2ri_vf_construction_edge_table (base, NULL, 0);
  553. for (int i = 0; i < size_candidat_base; i++)
  554. {
  555. vf_edge *edgetemp1 =
  556. hashtable_look_for (table, base->fa[candidat_base[i]].ve1,
  557. base->fa[candidat_base[i]].ve2);
  558. vf_edge *edgetemp2 =
  559. hashtable_look_for (table, base->fa[candidat_base[i]].ve1,
  560. base->fa[candidat_base[i]].ve3);
  561. vf_edge *edgetemp3 =
  562. hashtable_look_for (table, base->fa[candidat_base[i]].ve2,
  563. base->fa[candidat_base[i]].ve3);
  564. if (edgetemp1->nbsharedfaces == 1
  565. || edgetemp2->nbsharedfaces == 1
  566. || edgetemp3->nbsharedfaces == 1)
  567. list_int_add (&liste_a_supprimer[0],
  568. &size_liste_a_supprimer[0],
  569. candidat_base[i], WITH_REDUNDANCE);
  570. }
  571. a2ri_vf_remove_list_of_face (base, liste_a_supprimer[0],
  572. size_liste_a_supprimer[0]);
  573. for (int i = 0; i < size_liste_a_supprimer[0]; i++)
  574. {
  575. int index;
  576. list_int_remove (&candidat_base, &size_candidat_base,
  577. index =
  578. list_int_contains (candidat_base,
  579. size_candidat_base,
  580. liste_a_supprimer[0]
  581. [i]));
  582. for (int j = index; j < size_candidat_base; j++)
  583. candidat_base[j] = candidat_base[j] - 1;
  584. size_candidat_base++;
  585. list_double_remove (&listrayonbase, &size_candidat_base,
  586. index);
  587. size_candidat_base++;
  588. list_point3d_remove (&listcentrebase, &size_candidat_base,
  589. index);
  590. }
  591. if (size_liste_a_supprimer[0] == 0 && !recouvrement)
  592. recouvrement = 0;
  593. else
  594. recouvrement = 1;
  595. free (liste_a_supprimer[0]);
  596. liste_a_supprimer[0] = NULL;
  597. size_liste_a_supprimer[0] = 0;
  598. hashtable_free (table);
  599. table = NULL;
  600. finMAJ = a2ri_get_time ();
  601. totalMAJ += a2ri_time_interval_to_double (depMAJ, finMAJ);
  602. }
  603. }
  604. }
  605. tour++;
  606. fintotal = a2ri_get_time ();
  607. a2ri_display_interval_time ("temps TOTAL nettoyage : ", deptotal, fintotal);
  608. printf ("\ttemps calcul BB : %lf -> %lf %c\n",
  609. a2ri_time_interval_to_double (depBB, finBB),
  610. a2ri_time_interval_to_double (depBB,
  611. finBB) /
  612. a2ri_time_interval_to_double (deptotal, fintotal) * 100, 37);
  613. printf ("\ttemps calcul intersection : %lf -> %lf %c\n", totalinter,
  614. totalinter / a2ri_time_interval_to_double (deptotal,
  615. fintotal) * 100, 37);
  616. printf ("\ttemps MAJ : %lf -> %lf %c\n", totalMAJ,
  617. totalMAJ / a2ri_time_interval_to_double (deptotal, fintotal) * 100,
  618. 37);
  619. }
  620. /**
  621. Création d'un vf_model avec une triangulation de delaunay
  622. @param list liste de point
  623. @param nbpoint nombre de points
  624. @return aucun
  625. */
  626. vf_model *
  627. a2ri_vf_delaunay_triangulation (
  628. const point3d * const list,
  629. int nbpoint)
  630. {
  631. /*TODO*/
  632. vf_model *m = (vf_model *) malloc (sizeof (vf_model));
  633. a2ri_erreur_critique_si (m == NULL,
  634. "erreur allocation memoire pour m\na2ri_vf_delaunay_triangulation");
  635. a2ri_vf_init (m);
  636. return m;
  637. }
  638. /**
  639. Création d'un vef_model avec une triangulation de delaunay
  640. @param list liste de point
  641. @param nbpoint nombre de points
  642. @return aucun
  643. */
  644. vef_model *
  645. a2ri_vef_delaunay_triangulation (
  646. const point3d * const list,
  647. int nbpoint)
  648. {
  649. /*TODO*/
  650. vef_model *m = (vef_model *) malloc (sizeof (vef_model));
  651. a2ri_erreur_critique_si (m == NULL,
  652. "erreur allocation memoire pour m\na2ri_vef_delaunay_triangulation");
  653. a2ri_vef_init (m);
  654. return m;
  655. }
  656. /*********************/
  657. /*algorithme BPA 2010*/
  658. /*********************/
  659. void a2ri_bpa_insert_edge(bpa_edge *front, bpa_edge e)
  660. {
  661. bpa_edge *newedge=(bpa_edge*)malloc(sizeof(bpa_edge));
  662. a2ri_erreur_critique_si (newedge == NULL,
  663. "erreur allocation memoire pour newedge\na2ri_bpa_insert_edge");
  664. newedge->sigma_i=e.sigma_i;
  665. newedge->sigma_j=e.sigma_j;
  666. newedge->sigma_o=e.sigma_o;
  667. newedge->cijo=e.cijo;
  668. newedge->state=e.state;
  669. newedge->prev=front->prev;
  670. newedge->next=front;
  671. newedge->front=front->prev->front;
  672. front->prev->next=newedge;
  673. front->prev=newedge;
  674. front->front->front=newedge;
  675. }
  676. void a2ri_bpa_delete_edge(bpa_edge **front)
  677. {
  678. a2ri_erreur_critique_si ((*front)->prev == NULL,
  679. "Erreur algorithmique. Arete impossible a supprimer car non boucle 1.\na2ri_bpa_delete_edge");
  680. a2ri_erreur_critique_si ((*front)->next == NULL,
  681. "Erreur algorithmique. Arete impossible a supprimer car non boucle 2.\na2ri_bpa_delete_edge");
  682. (*front)->front->front=(*front)->prev;
  683. (*front)->prev->next=(*front)->next;
  684. (*front)->next->prev=(*front)->prev;
  685. free((*front));
  686. }
  687. void a2ri_bpa_free_front(bpa_edge **front)
  688. {
  689. bpa_edge *courant=*front,*suivant=NULL;
  690. if((*front)==NULL)
  691. return;
  692. if(courant->prev!=NULL)
  693. courant->prev->next=NULL;
  694. suivant=courant->next;
  695. while(courant!=NULL)
  696. {
  697. a2ri_erreur_critique_si (courant->state == ACTIVE,
  698. "Erreur algorithmique. Arete active impossible a liberer.\na2ri_bpa_free_front");
  699. free(courant);
  700. courant=suivant;
  701. if(suivant!=NULL)
  702. suivant=suivant->next;
  703. }
  704. }
  705. void a2ri_bpa_free_fronts(bpa_fronts **fronts)
  706. {
  707. bpa_fronts *courant=*fronts,*suivant=NULL;
  708. if((*fronts)==NULL)
  709. return;
  710. suivant=courant->next;
  711. while(courant!=NULL)
  712. {
  713. a2ri_bpa_free_front(&(courant->front));
  714. courant->front=NULL;
  715. free(courant);
  716. courant=suivant;
  717. if(suivant!=NULL)
  718. suivant=suivant->next;
  719. }
  720. }
  721. void a2ri_bpa_new_front(bpa_fronts **fronts, int sigma_i, int sigma_j, int sigma_k, point3d centre)
  722. {
  723. bpa_edge *parc;
  724. (*fronts)=(bpa_fronts*)malloc(sizeof(bpa_fronts));
  725. a2ri_erreur_critique_si (*fronts == NULL,
  726. "erreur allocation memoire pour fronts\na2ri_bpa_new_front");
  727. (*fronts)->next=NULL;
  728. (*fronts)->front=(bpa_edge*)malloc(sizeof(bpa_edge));
  729. a2ri_erreur_critique_si ((*fronts)->front == NULL,
  730. "erreur allocation memoire pour *fronts->front - 1ere arete\na2ri_bpa_insert_edge");
  731. parc=(*fronts)->front;
  732. /*premiere arete du front*/
  733. parc->sigma_i=sigma_i;parc->sigma_j=sigma_j;parc->sigma_o=sigma_k;parc->cijo=centre;parc->state=ACTIVE;parc->front=(*fronts);
  734. parc->next=(bpa_edge*)malloc(sizeof(bpa_edge));
  735. a2ri_erreur_critique_si (parc->next == NULL,
  736. "erreur allocation memoire pour parc->next - 2eme arete\na2ri_bpa_new_front");
  737. parc->next->prev=parc;
  738. parc=parc->next;
  739. /*seconde arete du front*/
  740. parc->sigma_i=sigma_j;parc->sigma_j=sigma_k;parc->sigma_o=sigma_i;parc->cijo=centre;parc->state=ACTIVE;parc->front=(*fronts);
  741. parc->next=(bpa_edge*)malloc(sizeof(bpa_edge));
  742. a2ri_erreur_critique_si (parc->next == NULL,
  743. "erreur allocation memoire pour parc->next - 3eme arete\na2ri_bpa_new_front");
  744. parc->next->prev=parc;
  745. parc=parc->next;
  746. /*troisieme arete du front*/
  747. parc->sigma_i=sigma_k;parc->sigma_j=sigma_i;parc->sigma_o=sigma_j;parc->cijo=centre;parc->state=ACTIVE;parc->front=(*fronts);
  748. parc->next=(*fronts)->front;
  749. parc->next->prev=parc;
  750. }
  751. bpa_edge* a2ri_bpa_get_active_edge_in_front(bpa_edge *front)
  752. {
  753. //printf("recherche d'arete active dans un front\n");
  754. int tour=0;
  755. while(tour<2)
  756. {
  757. if(front==front->front->front)
  758. tour++;
  759. if(front->state==ACTIVE)
  760. return front;
  761. else
  762. front=front->next;
  763. }
  764. return NULL;
  765. }
  766. bpa_edge* a2ri_bpa_get_active_edge_in_fronts(bpa_fronts *fronts)
  767. {
  768. bpa_edge *temp;
  769. //printf("recherche d'arete active dans les fronts\n");
  770. while(fronts!=NULL)
  771. if((temp=a2ri_bpa_get_active_edge_in_front(fronts->front))!=NULL)
  772. return temp;
  773. else
  774. fronts=fronts->next;
  775. return NULL;
  776. }
  777. char a2ri_bpa_front_contains_point_in_front(bpa_edge *front, int sigma_k)
  778. {
  779. int tour=0;
  780. while(tour<2)
  781. {
  782. if(front==front->front->front)
  783. tour++;
  784. if(front->sigma_i==sigma_k || front->sigma_j==sigma_k)
  785. return 1;
  786. else
  787. front=front->next;
  788. }
  789. return 0;
  790. }
  791. char a2ri_bpa_front_contains_point_in_fronts(bpa_fronts *fronts, int sigma_k)
  792. {
  793. while(fronts!=NULL)
  794. if(a2ri_bpa_front_contains_point_in_front(fronts->front,sigma_k))
  795. return 1;
  796. else
  797. fronts=fronts->next;
  798. return 0;
  799. }
  800. bpa_edge* a2ri_bpa_front_contains_edge_in_front(bpa_edge *front, bpa_edge e)
  801. {
  802. int tour=0;
  803. while(tour<2)
  804. {
  805. if(front==front->front->front)
  806. tour++;
  807. if(front->sigma_i==e.sigma_i && front->sigma_j==e.sigma_j)
  808. return front;
  809. else
  810. front=front->next;
  811. }
  812. return NULL;
  813. }
  814. bpa_edge* a2ri_bpa_front_contains_edge_in_fronts(bpa_fronts *fronts, bpa_edge e)
  815. {
  816. bpa_edge *temp;
  817. while(fronts!=NULL)
  818. {
  819. temp=a2ri_bpa_front_contains_edge_in_front(fronts->front,e);
  820. if(temp!=NULL)
  821. return temp;
  822. else
  823. fronts=fronts->next;
  824. }
  825. return NULL;
  826. }
  827. void a2ri_bpa_display_front(bpa_edge *front)
  828. {
  829. int tour=0;
  830. while(tour==0 || front!=front->front->front)
  831. {
  832. tour=1;
  833. //printf("\tarete : (%d %d) - point oppose : %d - centre : (%lf %lf %lf) - etat : ",front->sigma_i,front->sigma_j,front->sigma_o,front->cijo.x,front->cijo.y,front->cijo.z);
  834. printf("\tarete : (%4d %4d) - point oppose : %4d - ",front->sigma_i,front->sigma_j,front->sigma_o);
  835. if(front->state==ACTIVE)
  836. printf("ACTIVE\n");
  837. if(front->state==BOUNDARY)
  838. printf("BOUNDARY\n");
  839. //printf("\tfront : %p - front->front : %p - front->front->front : %p\n",front,front->front,front->front->front);
  840. front=front->next;
  841. }
  842. }
  843. void a2ri_bpa_display_fronts(bpa_fronts *fronts)
  844. {
  845. int index=0;
  846. while(fronts!=NULL)
  847. {
  848. printf("front %d :\n",index++);
  849. a2ri_bpa_display_front(fronts->front);
  850. fronts=fronts->next;
  851. }
  852. }
  853. int a2ri_bpa_front_distance(bpa_edge *front, int index)
  854. {
  855. if(!a2ri_bpa_front_contains_point_in_front(front, index))
  856. return -1;
  857. int tour=0,taille=-1,distance=0,trouve=0;
  858. while(tour<2)
  859. {
  860. taille++;
  861. if(front==front->front->front)
  862. tour++;
  863. if(front->sigma_i==index || front->sigma_j==index)
  864. trouve=1;
  865. if(!trouve)
  866. distance++;
  867. front=front->next;
  868. }
  869. if((distance*1.0)>=(taille/2.0))
  870. distance=taille-distance-1;
  871. return distance;
  872. }
  873. void a2ri_bpa_join(bpa_edge **e, int sigma_k, point3d centre)
  874. {
  875. bpa_edge temp;
  876. temp.prev=NULL;
  877. temp.next=NULL;
  878. temp.sigma_i=(*e)->sigma_i;
  879. temp.sigma_j=sigma_k;
  880. temp.sigma_o=(*e)->sigma_j;
  881. temp.cijo=centre;
  882. temp.state=ACTIVE;
  883. a2ri_bpa_insert_edge(*e,temp);
  884. temp.sigma_i=sigma_k;
  885. temp.sigma_j=(*e)->sigma_j;
  886. temp.sigma_o=(*e)->sigma_i;
  887. a2ri_bpa_insert_edge(*e,temp);
  888. a2ri_bpa_delete_edge(e);
  889. }
  890. void a2ri_bpa_glue(bpa_fronts **fronts, bpa_edge *ed1, bpa_edge *ed2)
  891. {
  892. bpa_edge *temp;
  893. bpa_fronts *parc=*fronts,*todelete;
  894. //printf("GLUE - arete %d %d - arete %d %d\n",ed1->sigma_i,ed1->sigma_j,ed2->sigma_i,ed2->sigma_j);
  895. //a2ri_bpa_display_fronts(*fronts);
  896. if(ed1->next==ed2 || ed1->prev==ed2)
  897. {
  898. /*SONT ADJACENTS*/
  899. if(ed1->next==ed2 && ed1->prev==ed2)
  900. {
  901. /*FORMENT UNE BOUCLE A EUX DEUX*/
  902. /*SURPPRIMER LE FRONT*/
  903. //printf("deux aretes adjacentes qui forment une boucle ");
  904. if(ed1->front==*fronts)
  905. {
  906. //printf("cas 1\n");
  907. /*L'ARETE APPARTIENT AU PREMIER FRONT*/
  908. *fronts=(*fronts)->next;
  909. parc->front->state=BOUNDARY;
  910. parc->front->next->state=BOUNDARY;
  911. a2ri_bpa_free_front(&(parc->front));
  912. parc->front=NULL;
  913. free(parc);
  914. }
  915. else
  916. {
  917. /*ON RECHERCHE LE FRONT POUR LE SUPPRIMER*/
  918. //printf("cas 2\n");
  919. while(parc->next!=ed1->front)
  920. parc=parc->next;
  921. todelete=parc->next;
  922. parc->next=todelete->next;
  923. todelete->front->state=BOUNDARY;
  924. todelete->front->next->state=BOUNDARY;
  925. a2ri_bpa_free_front(&(todelete->front));
  926. todelete->front=NULL;
  927. free(todelete);
  928. }
  929. }
  930. else
  931. {
  932. //printf("deux aretes adjacentes\n");
  933. /*NE FORMENT PAS UNE BOUCLE A EUX DEUX*/
  934. a2ri_bpa_delete_edge(&ed1);
  935. a2ri_bpa_delete_edge(&ed2);
  936. }
  937. }
  938. else
  939. {
  940. /*NE SONT PAS ADJACENTS*/
  941. if(ed1->front==ed2->front)
  942. {
  943. //printf("deux arete non adjacentes appartenant au meme front\n");
  944. //a2ri_bpa_display_fronts(*fronts);
  945. /*APPARTIENNENT AU MEME FRONT*/
  946. /*SPLIT DU FRONT EN DEUX*/
  947. ed1->front->front=ed1->prev;
  948. ed2->next->prev=ed1->prev;
  949. ed1->prev->next=ed2->next;
  950. ed1->next->prev=ed2->prev;
  951. ed2->prev->next=ed1->next;
  952. while(parc->next!=NULL)
  953. parc=parc->next;
  954. parc->next=(bpa_fronts*)malloc(sizeof(bpa_fronts));
  955. parc=parc->next;
  956. parc->next=NULL;
  957. parc->front=ed2->prev;
  958. temp=parc->front->next;
  959. parc->front->front=parc;
  960. while(temp!=parc->front)
  961. {
  962. temp->front=parc;
  963. temp=temp->next;
  964. }
  965. //printf("\n\n");
  966. //a2ri_bpa_display_fronts(*fronts);
  967. }
  968. else
  969. {
  970. //a2ri_bpa_display_fronts(*fronts);
  971. //printf("deux aretes non adjacentes qui n'appartiennent pas au meme front\n");
  972. /*N'APPARTIENNENT PAS AU MEME FRONT*/
  973. /*FUSION DES DEUX FRONTS*/
  974. if(ed1->front!=*fronts)
  975. todelete=ed1->front;
  976. else
  977. todelete=ed2->front;
  978. ed1->front->front=ed1->prev;
  979. ed2->front->front=ed2->prev;
  980. while(parc->next!=todelete)
  981. parc=parc->next;
  982. parc->next=todelete->next;
  983. ed1->prev->next=ed2->next;
  984. ed2->next->prev=ed1->prev;
  985. ed1->next->prev=ed2->prev;
  986. ed2->prev->next=ed1->next;
  987. if(todelete==ed1->front)
  988. {
  989. temp=ed2->front->front;
  990. temp->front=ed2->front;
  991. temp=temp->next;
  992. while(temp!=ed2->front->front)
  993. {
  994. temp->front=ed2->front;
  995. temp=temp->next;
  996. }
  997. }
  998. else
  999. {
  1000. temp=ed1->front->front;
  1001. temp->front=ed1->front;
  1002. temp=temp->next;
  1003. while(temp!=ed1->front->front)
  1004. {
  1005. temp->front=ed1->front;
  1006. temp=temp->next;
  1007. }
  1008. }
  1009. free(todelete);
  1010. }
  1011. free(ed1);
  1012. free(ed2);
  1013. }
  1014. return;
  1015. }
  1016. void a2ri_bpa_regularization(bpa_fronts **fronts, int sigma_i, int sigma_j, int sigma_k)
  1017. {
  1018. bpa_edge *ed1,*ed2,temp;
  1019. /*IK KI*/
  1020. temp.sigma_i=sigma_i;
  1021. temp.sigma_j=sigma_k;
  1022. //printf("arete recherche : %d %d\n",temp.sigma_i,temp.sigma_j);
  1023. //a2ri_bpa_display_fronts(*fronts);
  1024. ed1=a2ri_bpa_front_contains_edge_in_fronts(*fronts,temp);
  1025. a2ri_erreur_critique_si (ed1 == NULL,
  1026. "Erreur algorithmique. L'arete vient d''etre creee. IK KI ed1 ne peut etre NULL.\na2ri_bpa_regularization");
  1027. temp.sigma_i=sigma_k;
  1028. temp.sigma_j=sigma_i;
  1029. ed2=a2ri_bpa_front_contains_edge_in_fronts(*fronts,temp);
  1030. if(ed2!=NULL)
  1031. a2ri_bpa_glue(fronts,ed1,ed2);
  1032. /*KJ JK*/
  1033. temp.sigma_i=sigma_k;
  1034. temp.sigma_j=sigma_j;
  1035. ed1=a2ri_bpa_front_contains_edge_in_fronts(*fronts,temp);
  1036. a2ri_erreur_critique_si (ed1 == NULL,
  1037. "Erreur algorithmique. L'arete vient d''etre cree. KJ JK ed1 ne peut etre NULL.\na2ri_bpa_regularization");
  1038. temp.sigma_i=sigma_j;
  1039. temp.sigma_j=sigma_k;
  1040. ed2=a2ri_bpa_front_contains_edge_in_fronts(*fronts,temp);
  1041. if(ed2!=NULL)
  1042. a2ri_bpa_glue(fronts,ed1,ed2);
  1043. }
  1044. char a2ri_bpa_compute_ball(point3d p1, point3d p2, point3d p3, vector3d normaleface, double radius, point3d *centre)
  1045. {
  1046. double longueur;
  1047. *centre=circumcircle_center(&p1,&p2,&p3);
  1048. longueur=point3d_length(centre,&p1);
  1049. if(longueur<radius)
  1050. {
  1051. longueur=sqrt(radius*radius-longueur*longueur);
  1052. normaleface.dx*=longueur;
  1053. normaleface.dy*=longueur;
  1054. normaleface.dz*=longueur;
  1055. centre->x=centre->x+normaleface.dx;
  1056. centre->y=centre->y+normaleface.dy;
  1057. centre->z=centre->z+normaleface.dz;
  1058. return 1;
  1059. }
  1060. else
  1061. return 0;
  1062. }
  1063. char a2ri_bpa_verif_contraintes(pt_point3d *listpoint, int sizelistpoint, point3d p1, point3d p2, point3d p3, vector3d normalp1, vector3d normalp2, vector3d normalp3, double radius, point3d *centre)
  1064. {
  1065. vector3d AB,AC,normaleface;
  1066. double prodscal1,prodscal2,prodscal3,distance;
  1067. int index,trouve;
  1068. /*printf("----DEBUT A2RI BPA VERIF CONTAINTES\n");
  1069. printf("points :\n");
  1070. point3d_display(p1);point3d_display(p2);point3d_display(p3);
  1071. printf("normales aux trois points :\n");
  1072. vector3d_display(normalp1);
  1073. vector3d_display(normalp2);
  1074. vector3d_display(normalp3);*/
  1075. vector3d_init (&AB, p2.x - p1.x,p2.y - p1.y,p2.z - p1.z);
  1076. vector3d_init (&AC, p3.x - p1.x,p3.y - p1.y,p3.z - p1.z);
  1077. normaleface=vector3d_vectorialproduct (&AB, &AC);
  1078. vector3d_normalize(&normaleface);
  1079. /*printf("normale au triangle candidat :\n");
  1080. vector3d_display(normaleface);*/
  1081. prodscal1=vector3d_scalarproduct(&normaleface,&normalp1);
  1082. prodscal2=vector3d_scalarproduct(&normaleface,&normalp2);
  1083. prodscal3=vector3d_scalarproduct(&normaleface,&normalp3);
  1084. if(prodscal1>0 && prodscal2>0 && prodscal3>0)
  1085. {
  1086. /*printf("test des normales OK\n");*/
  1087. /*VERIFIER QUE LA BOULE PASSANT PAR LES TROIS POINTS NE CONTIENNENT PAS D'AUTRE POINT DE LA LISTE*/
  1088. /*CALCUL DU CENTRE DE LA BOULE*/
  1089. /*SI ON ARRIVE A TROUVER UNE BOULE TOUCHANT LES TROIS POINTS*/
  1090. if(a2ri_bpa_compute_ball(p1,p2,p3,normaleface,radius,centre))
  1091. {
  1092. /*printf("calcul de la boule OK\ncentre :\n");*/
  1093. /*point3d_display(*centre);*/
  1094. /*VERIFICATION DE NON PRESENCE D'AUTRE POINT DANS LA BOULE*/
  1095. index=0;
  1096. trouve=0;
  1097. /*printf("recherche de points se trouvant dans cette sphere\n");*/
  1098. while(!trouve && index<sizelistpoint)
  1099. {
  1100. /*printf("point index : %d\n",index);
  1101. point3d_display(*(listpoint[index]));*/
  1102. if(!point3d_equal(&p1,listpoint[index]) && !point3d_equal(&p2,listpoint[index]) && !point3d_equal(&p3,listpoint[index]))
  1103. {
  1104. /*printf("longueur au centre de la sphere : %lf\n",point3d_length(*centre,*(listpoint[index])));*/
  1105. if((distance=point3d_length(centre,listpoint[index]))<radius && !egalite(distance-radius,0))
  1106. {
  1107. /*printf("le point se trouve dans la sphere\n");*/
  1108. trouve=1;
  1109. }
  1110. /*else
  1111. {
  1112. if(egalite(distance-radius,0))
  1113. printf("le point ne se trouve pas dans la sphere mais presque, distance : %lf\n",distance);
  1114. else
  1115. printf("le point ne se trouve pas dans la sphere\n");
  1116. }*/
  1117. }
  1118. /*else
  1119. printf("le point est egal a l'un des points du triangle\n");*/
  1120. index++;
  1121. }
  1122. if(!trouve)
  1123. {
  1124. /*printf("pas de point trouve dans la sphere\n");*/
  1125. return 1;
  1126. }
  1127. }
  1128. /*else
  1129. printf("impossible de calculer une boule passant par ces trois points et de rayon %lf\n",radius);*/
  1130. }
  1131. /*else
  1132. printf("probleme dans le test des normales\n----FIN A2RI BPA VERIF CONTAINTES\n");*/
  1133. return 0;
  1134. }
  1135. char a2ri_bpa_find_seed_triangle(vf_model *m, space_partition *sp, vector3d *normal, double radius, int *listused, int sizeused, int *sigma_i, int *sigma_j, int *sigma_k, point3d *centre, int imin)
  1136. {
  1137. point3d p1,p2,p3;
  1138. pt_sp_depth *listcellule=NULL;
  1139. int sizelistcellule=0;
  1140. pt_point3d *listpoint=NULL;
  1141. int sizelistpoint=0;
  1142. int index,index2;
  1143. //printf("----DEBUT A2RI BPA FIND SEED TRIANGLE\n");
  1144. for(int i=imin;i<m->nbvertex;i++)
  1145. {
  1146. if(list_int_contains(listused,sizeused,i)==-1)
  1147. {
  1148. *sigma_i=i;
  1149. point3d_init(&p1,m->ve[i].x,m->ve[i].y,m->ve[i].z);
  1150. free(listcellule);
  1151. listcellule=NULL;
  1152. sizelistcellule=0;
  1153. sizelistpoint=0;
  1154. space_partition_get_neighbour(sp,&p1,1,&listcellule,&sizelistcellule);
  1155. for(int j=0;j<sizelistcellule;j++)
  1156. sizelistpoint+=listcellule[j]->nb_point;
  1157. free(listpoint);
  1158. listpoint=NULL;
  1159. listpoint=(pt_point3d*)malloc(sizelistpoint*sizeof(pt_point3d));
  1160. index=0;
  1161. /*CREATION DE LA LISTE DE POINT SE TROUVANT DANS LES CASES ADJACENTES AU POINT D'INDEX I*/
  1162. for(int j=0;j<sizelistcellule;j++)
  1163. for(int k=0;k<listcellule[j]->nb_point;k++)
  1164. listpoint[index++]=&(listcellule[j]->list_point[k]);
  1165. /*PRISE DES PAIRES DE POINTS DISCTINCTES*/
  1166. //printf("nombre de point : %d\n",sizelistpoint);
  1167. for(int j=0;j<sizelistpoint;j++)
  1168. for(int k=j+1;k<sizelistpoint;k++)
  1169. {
  1170. /*printf("%5d - a2ri_bpa_find_seed_triangle - test du triangle : %d %d %d\n",m->nbface,i,listpoint[j]->att_int,listpoint[k]->att_int);*/
  1171. index=list_int_contains(listused,sizeused,listpoint[j]->att_int);
  1172. index2=list_int_contains(listused,sizeused,listpoint[k]->att_int);
  1173. if(i!=listpoint[j]->att_int && i!=listpoint[k]->att_int && listpoint[j]->att_int!=listpoint[k]->att_int && index==-1 && index2==-1)
  1174. {
  1175. /*VERIFIER SI LES TROIS POINTS VERIFIENT LES CONTRAINTES BPA*/
  1176. /*VERIFIER L'ORIENTATION DE LA NORMALE*/
  1177. point3d_init(&p2,
  1178. m->ve[listpoint[j]->att_int].x,
  1179. m->ve[listpoint[j]->att_int].y,
  1180. m->ve[listpoint[j]->att_int].z);
  1181. point3d_init(&p3,
  1182. m->ve[listpoint[k]->att_int].x,
  1183. m->ve[listpoint[k]->att_int].y,
  1184. m->ve[listpoint[k]->att_int].z);
  1185. if(a2ri_bpa_verif_contraintes(listpoint,
  1186. sizelistpoint,
  1187. p1,p2,p3,
  1188. normal[i],
  1189. normal[listpoint[j]->att_int],
  1190. normal[listpoint[k]->att_int],
  1191. radius,centre))
  1192. {
  1193. //printf("triangle OK\n");
  1194. *sigma_i=i;
  1195. *sigma_j=listpoint[j]->att_int;
  1196. *sigma_k=listpoint[k]->att_int;
  1197. //printf("----FIN A2RI BPA FIND SEED TRIANGLE\n");
  1198. return 1;
  1199. }
  1200. /*else
  1201. printf("le triangle ne respecte pas les contraintes bpa\n");*/
  1202. }
  1203. /*else
  1204. printf("triangle degenere ou un point est deja utilise\n");*/
  1205. }
  1206. }
  1207. }
  1208. free(listpoint);
  1209. free(listcellule);
  1210. *sigma_i=-1;
  1211. *sigma_j=-1;
  1212. *sigma_k=-1;
  1213. //printf("pas de triangle trouve\n----FIN A2RI BPA FIND SEED TRIANGLE\n");
  1214. return 0;
  1215. }
  1216. void a2ri_bpa_ball_pivot(vf_model *m, space_partition *sp, vector3d *normal, double radius, bpa_edge *e, int *listused, int sizeused, bpa_fronts *fronts, int *sigma_k, point3d *centre)
  1217. {
  1218. point3d milieu,p1,p2,p3;
  1219. pt_sp_depth *listcellule=NULL;
  1220. int sizelistcellule=0;
  1221. pt_point3d *listpoint=NULL;
  1222. int sizelistpoint=0;
  1223. int index=0,index2=0;
  1224. pt_point3d *listcentre=NULL;
  1225. double prodscal,max;
  1226. vector3d AB,AC;
  1227. //printf("----DEBUT A2RI BPA BALL PIVOT\n");
  1228. //printf("pivot sur l'arete %d %d - point oppose : %d\n",e->sigma_i,e->sigma_j,e->sigma_o);
  1229. //printf("centre : ");point3d_display(e->cijo);
  1230. point3d_init(&p1,m->ve[e->sigma_i].x,m->ve[e->sigma_i].y,m->ve[e->sigma_i].z);
  1231. point3d_init(&p3,m->ve[e->sigma_j].x,m->ve[e->sigma_j].y,m->ve[e->sigma_j].z);
  1232. point3d_init(&milieu,(p1.x+p3.x)/2.0,(p1.y+p3.y)/2.0,(p1.z+p3.z)/2.0);
  1233. listcellule=NULL;
  1234. sizelistcellule=0;
  1235. space_partition_get_neighbour(sp,&milieu,1,&listcellule,&sizelistcellule);
  1236. for(int j=0;j<sizelistcellule;j++)
  1237. sizelistpoint+=listcellule[j]->nb_point;
  1238. listpoint=(pt_point3d*)malloc(sizelistpoint*sizeof(pt_point3d));
  1239. a2ri_erreur_critique_si(listpoint==NULL,
  1240. "erreur allocation memoire pour listpoint\na2ri_bpa_ball_pivot");
  1241. listcentre=(pt_point3d*)malloc(sizelistpoint*sizeof(pt_point3d));
  1242. a2ri_erreur_critique_si(listcentre==NULL,
  1243. "erreur allocation memoire pour listcentre\na2ri_bpa_ball_pivot");
  1244. index=0;
  1245. /*CREATION DE LA LISTE DE POINT SE TROUVANT DANS LES CASES ADJACENTES AU POINT D'INDEX I*/
  1246. for(int j=0;j<sizelistcellule;j++)
  1247. for(int k=0;k<listcellule[j]->nb_point;k++)
  1248. listpoint[index++]=&(listcellule[j]->list_point[k]);
  1249. /*CONSTRUCTION DES BOULES CANDIDATES*/
  1250. //int nbcandidat=0;
  1251. for(int i=0;i<sizelistpoint;i++)
  1252. {
  1253. if(listpoint[i]->att_int!=e->sigma_i && listpoint[i]->att_int!=e->sigma_j && listpoint[i]->att_int!=e->sigma_o)
  1254. {
  1255. //printf("test triangle %d %d %d\n",e->sigma_i,listpoint[i]->att_int,e->sigma_j);
  1256. point3d_init(&p2,
  1257. m->ve[listpoint[i]->att_int].x,
  1258. m->ve[listpoint[i]->att_int].y,
  1259. m->ve[listpoint[i]->att_int].z);
  1260. if(a2ri_bpa_verif_contraintes(listpoint,
  1261. sizelistpoint,
  1262. p1,p2,p3,
  1263. normal[e->sigma_i],
  1264. normal[listpoint[i]->att_int],
  1265. normal[e->sigma_j],
  1266. radius,centre))
  1267. {
  1268. listcentre[i]=(point3d*)malloc(sizeof(point3d));
  1269. point3d_init(listcentre[i],centre->x,centre->y,centre->z);
  1270. //nbcandidat++;
  1271. //printf("centre OK, %d candidat\n",nbcandidat);
  1272. }
  1273. else
  1274. {
  1275. //printf("centre pas ok\n");
  1276. listcentre[i]=NULL;
  1277. }
  1278. }
  1279. else
  1280. listcentre[i]=NULL;
  1281. }
  1282. //printf("%d candidats sur %d\n",nbcandidat,sizelistpoint);
  1283. /*REGARDER LES BOULES ET CHOISIR LA BONNE*/
  1284. vector3d_init(&AB,e->cijo.x-milieu.x,e->cijo.y-milieu.y,e->cijo.z-milieu.z);
  1285. vector3d_normalize(&AB);
  1286. index=-1;
  1287. max=-1;
  1288. for(int i=0;i<sizelistpoint;i++)
  1289. if(listcentre[i]!=NULL)
  1290. {
  1291. vector3d_init(&AC,listcentre[i]->x-milieu.x,listcentre[i]->y-milieu.y,listcentre[i]->z-milieu.z);
  1292. vector3d_normalize(&AC);
  1293. prodscal=vector3d_scalarproduct(&AB,&AC);
  1294. /*DANS LE CAS OU NOUS N'AVONS PAS ENCORE DE CANDIDAT*/
  1295. if(index==-1)
  1296. {
  1297. index=listpoint[i]->att_int;
  1298. max=prodscal;
  1299. index2=i;
  1300. }
  1301. else
  1302. /*DANS LE CAS OU LA BOULE TESTEE EST MEILLEURE QUE LA PRECEDENTE RETENUE*/
  1303. if(prodscal>max)
  1304. {
  1305. index2=i;
  1306. index=listpoint[i]->att_int;
  1307. max=prodscal;
  1308. }
  1309. else
  1310. {
  1311. /*DANS LE CAS OU LA BOULE TESTEE EST AUSSI BONNE QUE LA PRECEDENTE RETENUE*/
  1312. if(prodscal==max)
  1313. {
  1314. //printf("ATTENTION, NOUS AVONS UNE EGALITE entre les points :\n%d de distance %d\n%d de distance %d\n",index,a2ri_bpa_front_distance(e,index),listpoint[i]->att_int,a2ri_bpa_front_distance(e,listpoint[i]->att_int));
  1315. if(a2ri_bpa_front_distance(e,index)>a2ri_bpa_front_distance(e,listpoint[i]->att_int))
  1316. index=listpoint[i]->att_int;
  1317. }
  1318. }
  1319. }
  1320. if(index!=-1)
  1321. {
  1322. *centre=*(listcentre[index2]);
  1323. point3d_init(&p2,m->ve[index].x,m->ve[index].y,m->ve[index].z);
  1324. /*printf("longueurs : %lf %lf %lf\n",
  1325. point3d_length(p1,*centre),
  1326. point3d_length(p2,*centre),
  1327. point3d_length(p3,*centre));*/
  1328. a2ri_erreur_critique_si(!egalite(point3d_length(&p1,centre),radius),
  1329. "la boule n'est pas bien definie\na2ri_bpa_ball_pivot\n");
  1330. a2ri_erreur_critique_si(!egalite(point3d_length(&p2,centre),radius),
  1331. "la boule n'est pas bien definie\na2ri_bpa_ball_pivot\n");
  1332. a2ri_erreur_critique_si(!egalite(point3d_length(&p3,centre),radius),
  1333. "la boule n'est pas bien definie\na2ri_bpa_ball_pivot\n");
  1334. }
  1335. free(listpoint);
  1336. free(listcellule);
  1337. free(listcentre);
  1338. *sigma_k=index;
  1339. if(list_int_contains(listused,sizeused,*sigma_k)!=-1 && !a2ri_bpa_front_contains_point_in_fronts(fronts,*sigma_k))
  1340. *sigma_k=-1;
  1341. //printf("-- FIN A2RI BPA BALL PIVOT\n");
  1342. }
  1343. void a2ri_vf_bpa(vf_model *m, vector3d *normal, double radius)
  1344. {
  1345. bpa_edge *e;
  1346. int sigma_k,sigma_i,sigma_j,*listused=NULL,sizeused=0;
  1347. bpa_fronts *fronts=NULL;
  1348. point3d centre;
  1349. int imin=0;
  1350. point3d pmin,pmax;
  1351. int nbpartX,nbpartY,nbpartZ;
  1352. space_partition *sp=(space_partition*)malloc(sizeof(space_partition));
  1353. /*INITIALISATION DE L'ALGORITHME*/
  1354. /*CREATION DE LA SPACE PARTITION POUR OPTIMISATION DES RECHERCHES*/
  1355. a2ri_erreur_critique_si(sp==NULL,
  1356. "Erreur allocation memoire pour sp\na2ri_bpa_find_seed_triangle\n");
  1357. point3d_init(&pmin,m->xmin,m->ymin,m->zmin);
  1358. point3d_init(&pmax,m->xmax,m->ymax,m->zmax);
  1359. nbpartX=(int)((m->xmax-m->xmin)/(2*radius));
  1360. if(nbpartX==0)
  1361. nbpartX++;
  1362. nbpartY=(int)((m->ymax-m->ymin)/(2*radius));
  1363. if(nbpartY==0)
  1364. nbpartY++;
  1365. nbpartZ=(int)((m->zmax-m->zmin)/(2*radius));
  1366. if(nbpartZ==0)
  1367. nbpartZ++;
  1368. space_partition_new(sp,&pmin,&pmax,nbpartX,nbpartY,nbpartZ);
  1369. a2ri_vf_space_partition(m,sp);
  1370. /*REVOIR L'ALGO*/
  1371. while(1)
  1372. {
  1373. while((e=a2ri_bpa_get_active_edge_in_fronts(fronts))!=NULL)
  1374. {
  1375. a2ri_bpa_ball_pivot(m,sp,normal,radius,e,listused,sizeused,fronts,&sigma_k,&centre);
  1376. if(sigma_k!=-1)
  1377. {
  1378. list_int_add(&listused,&sizeused,sigma_k,WITHOUT_REDUNDANCE);
  1379. #ifdef _DEBUG
  1380. printf("%c%c%c%c%c%c%c%c%c%c%c%c%lf%c",8,8,8,8,8,8,8,8,8,8,8,8,sizeused*100.0/(m->nbvertex*1.0),37);
  1381. #endif
  1382. //printf("Ajout triangle %d : %d %d %d par pivot\n",m->nbface,e->sigma_i,sigma_k,e->sigma_j);
  1383. a2ri_vf_add_face(m,e->sigma_i,sigma_k,e->sigma_j);
  1384. sigma_i=e->sigma_i;sigma_j=e->sigma_j;
  1385. //a2ri_bpa_display_fronts(fronts);
  1386. a2ri_bpa_join(&e,sigma_k,centre);
  1387. //a2ri_bpa_display_fronts(fronts);
  1388. a2ri_bpa_regularization(&fronts,sigma_i,sigma_j,sigma_k);
  1389. //a2ri_bpa_display_fronts(fronts);
  1390. }
  1391. else
  1392. {
  1393. //printf("arete frontiere\n");
  1394. e->state=BOUNDARY;
  1395. }
  1396. //a2ri_bpa_display_fronts(fronts);
  1397. }
  1398. if(a2ri_bpa_find_seed_triangle(m,sp,normal,radius,listused,sizeused,&sigma_i,&sigma_j,&sigma_k,&centre,imin))
  1399. {
  1400. #ifdef _DEBUG
  1401. printf("%c%c%c%c%c%c%c%c%c%c%c%c%lf%c",8,8,8,8,8,8,8,8,8,8,8,8,sizeused*100.0/(m->nbvertex*1.0),37);
  1402. #endif
  1403. //printf("Ajout triangle %d : %d %d %d par seed triangle\n",m->nbface,sigma_i,sigma_j,sigma_k);
  1404. imin=sigma_i;
  1405. a2ri_vf_add_face(m,sigma_i,sigma_j,sigma_k);
  1406. a2ri_bpa_free_fronts(&fronts);
  1407. fronts=NULL;
  1408. a2ri_bpa_new_front(&fronts,sigma_i,sigma_j,sigma_k,centre);
  1409. //a2ri_bpa_display_fronts(fronts);
  1410. list_int_add(&listused,&sizeused,sigma_i,WITH_REDUNDANCE);
  1411. list_int_add(&listused,&sizeused,sigma_j,WITH_REDUNDANCE);
  1412. list_int_add(&listused,&sizeused,sigma_k,WITH_REDUNDANCE);
  1413. }
  1414. else
  1415. {
  1416. printf("\nBPA termine...\n");
  1417. return;
  1418. }
  1419. }
  1420. return;
  1421. }
  1422. /*
  1423. void a2ri_vf_bpa_multipass(vf_model *m, vector3d *normal, double *listradius, int listsize)
  1424. {
  1425. return;
  1426. }*/
  1427. void a2ri_vf_bpa_without_normal(vf_model *m, double radius)
  1428. {
  1429. vector3d *list=NULL;
  1430. list=(vector3d*)malloc(m->nbvertex*sizeof(vector3d));
  1431. a2ri_erreur_critique_si(list==NULL,
  1432. "erreur allocation memoire pour list\na2ri_vf_bpa_without_normal\n");
  1433. for(int i=0;i<m->nbvertex;i++)
  1434. {
  1435. vector3d_init(&(list[i]),m->ve[i].x-((m->xmin+m->xmax)/2.0),m->ve[i].y-((m->ymin+m->ymax)/2.0),m->ve[i].z-((m->zmin+m->zmax)/2.0));
  1436. vector3d_normalize(&(list[i]));
  1437. }
  1438. a2ri_vf_bpa(m,list,radius);
  1439. free(list);
  1440. }
  1441. void a2ri_bpa_average_radius_suggestion(vf_model *m, double *min, double *max, double *average, double *sd)
  1442. {
  1443. /*TODO optimisation multi thread*/
  1444. space_partition sp;
  1445. point3d ptmin,ptmax;
  1446. double *listelongueur;
  1447. listelongueur=(double*)malloc(sizeof(double)*m->nbvertex);
  1448. a2ri_erreur_critique_si(listelongueur==NULL,"erreur allocation memoire a2ri_bpa_average_radius_suggestion pour listelongueur\n");
  1449. ptmin.x=m->xmin;ptmin.y=m->ymin;ptmin.z=m->zmin;
  1450. ptmax.x=m->xmax;ptmax.y=m->ymax;ptmax.z=m->zmax;
  1451. if(m->nbvertex>=24)
  1452. space_partition_new(&sp,&ptmin,&ptmax,
  1453. (int)(pow((m->nbvertex/24.0),1.0/3.0)),
  1454. (int)(pow((m->nbvertex/24.0),1.0/3.0)),
  1455. ((int)pow((m->nbvertex/24.0),1.0/3.0)));
  1456. else
  1457. space_partition_new(&sp,&ptmin,&ptmax,1,1,1);
  1458. a2ri_vf_space_partition(m,&sp);
  1459. for(int i=0;i<m->nbvertex;i++)
  1460. {
  1461. point3d p1,p2;
  1462. double longueur;
  1463. point3d_init(&p1,m->ve[i].x,m->ve[i].y,m->ve[i].z);
  1464. space_partition_nearest_point(&sp,&p1,&p2,&longueur,REJECT_ZERO_LENGTH);
  1465. listelongueur[i]=longueur;
  1466. }
  1467. *min=list_double_min(listelongueur,m->nbvertex);
  1468. *max=list_double_max(listelongueur,m->nbvertex);
  1469. *average=list_double_average(listelongueur,m->nbvertex);
  1470. *sd=sqrt(list_double_variance(listelongueur,m->nbvertex));
  1471. space_partition_free(&sp);
  1472. }
  1473. void a2ri_bpa_initialisation(vf_model *m, bpa_fronts **fronts, int **listused, int *sizelistused)
  1474. {
  1475. IT_bpa_liste temp;
  1476. int nbtrou=IF_bpa_vf_hole(m,&temp);
  1477. //printf("\n\n%d trous\n",nbtrou);
  1478. //list_int_display(temp.list,temp.nbelt);
  1479. IT_bpa_liste *cycle;
  1480. cycle=(IT_bpa_liste*)malloc(nbtrou*sizeof(IT_bpa_liste));
  1481. int index=0;
  1482. for(int i=0;i<nbtrou;i++)
  1483. {
  1484. cycle[i].list=NULL;
  1485. cycle[i].nbelt=0;
  1486. while(temp.list[index]!=-1)
  1487. {
  1488. list_int_add(&(cycle[i].list),&(cycle[i].nbelt),temp.list[index],WITH_REDUNDANCE);
  1489. index++;
  1490. }
  1491. index++;
  1492. /*printf("cycle %d\n",i);
  1493. list_int_display(cycle[i].list,cycle[i].nbelt);*/
  1494. }
  1495. //cycles trouvés. On va essayer de les rassembler si il y a un point en commun
  1496. if(nbtrou>1)
  1497. {
  1498. int i=0,j,commun=-1;
  1499. while(i<nbtrou)
  1500. {
  1501. if(commun!=-1)
  1502. {
  1503. i=0;
  1504. commun=-1;
  1505. }
  1506. j=i+1;
  1507. while(j<nbtrou && commun==-1)
  1508. {
  1509. int indexi=0,indexj;
  1510. while(indexi<cycle[i].nbelt && commun==-1)
  1511. {
  1512. if((indexj=list_int_contains(cycle[j].list,cycle[j].nbelt,cycle[i].list[indexi]))!=-1)
  1513. commun=cycle[i].list[indexi];
  1514. else
  1515. indexi++;
  1516. }
  1517. if(commun!=-1)
  1518. {
  1519. //fusion des deux listes et mise à 0 de i et 1 de j
  1520. /*printf("attention, conflit entre les cycles %d et %d sur l'element %d\n",i,j,commun);*/
  1521. while(cycle[i].list[cycle[i].nbelt-1]!=commun)
  1522. list_int_shift_right(cycle[i].list,cycle[i].nbelt,1);
  1523. while(cycle[j].list[0]!=commun)
  1524. list_int_shift_left(cycle[j].list,cycle[j].nbelt,1);
  1525. for(int k=1;k<cycle[j].nbelt;k++)
  1526. list_int_add(&(cycle[i].list),&(cycle[i].nbelt),cycle[j].list[k],WITH_REDUNDANCE);
  1527. list_int_add(&(cycle[i].list),&(cycle[i].nbelt),commun,WITH_REDUNDANCE);
  1528. free(cycle[j].list);
  1529. for(int k=j+1;k<nbtrou;k++)
  1530. {
  1531. cycle[k-1].list=cycle[k].list;
  1532. cycle[k-1].nbelt=cycle[k].nbelt;
  1533. }
  1534. nbtrou--;
  1535. }
  1536. else
  1537. j++;
  1538. }
  1539. i++;
  1540. }
  1541. }
  1542. printf("\n\n%d trous\n",nbtrou);
  1543. for(int i=0;i<nbtrou;i++)
  1544. {
  1545. printf("cycle %d\n",i);
  1546. list_int_display(cycle[i].list,cycle[i].nbelt);
  1547. }
  1548. for(int i=0;i<nbtrou;i++)
  1549. free(cycle[i].list);
  1550. free(cycle);
  1551. /*CREER LES FRONTS EN FONCTION DES CYCLES*/
  1552. }