Skip to content

fix : découpe et amincissement — deux lectures de mémoire indéfinie qui rendaient roofer non déterministe - #2

Merged
guhur merged 2 commits into
argile/v1.0.0from
fix/determinism-cropper-thinning
Oct 4, 2026
Merged

guhur merged 2 commits into
argile/v1.0.0from
fix/determinism-cropper-thinning

Conversation

@guhur

@guhur guhur commented Oct 4, 2026

Copy link
Copy Markdown

Pourquoi

En portant le déterminisme (#1) sur le main officiel (3DBAG#181), un bâtiment changeait encore d'une passe à l'autre. Deux lectures de mémoire indéfinie étaient en cause, hors de la reconstruction. Elles existent depuis 2024, donc aussi dans notre v1.0.0. Sur nos 7 393 bâtiments, elles ne s'étaient pas manifestées par chance.

Ce qui est corrigé (un commit chacun, repris de 3DBAG#181)

  1. Découpe (StreamCropper.cpp, do_post_process) : la boucle qui ajoute au nuage de chaque emprise les points sol de sa zone tampon déclarait size_t poly_i; sans l'initialiser. Elle part maintenant de 0, donc ces points sont toujours ajoutés, comme le prévoit le commentaire.
  2. Amincissement (PointcloudRasteriser.cpp, gridthinPointcloud) : le test i > size() laissait passer i == size(). Un point de cette cellule lisait alors une case après la fin du raster de comptage. Qu'il soit gardé ou non, et donc tous les tirages aléatoires suivants, dépendait de cette mémoire. Ce sont les points sol de la zone tampon, hors du raster de l'emprise, qui tombent dans ce cas.

Vérification

Mêmes 7 393 bâtiments, géométrie et attributs rf_* comparés, hors rf_t_run :

bâtiments différents
deux passes, 32 processus 0
chemins de sortie courts vs longs 0

Par rapport au fork actuel (#1) :

  • 34 bâtiments sur 6 787 changent de maquette LoD 2.2, dont 5 de plus de 1 % en volume (au plus 5,9 %) ;
  • l'erreur de roofer (rf_rmse_lod22) s'améliore de plus de 1 cm sur 1 bâtiment et ne se dégrade nulle part.

Hors périmètre

Pour un point hors de l'emprise, l'indice de cellule (static_cast<size_t>(floor(...))) déborde. Un point à droite tombe dans la ligne suivante, un point négatif fait un tour complet. Les points sol de la zone tampon sont donc soit écartés par l'amincissement, soit comptés dans une autre cellule. Je ne l'ai pas corrigé : cela change les points sol gardés. C'est signalé dans 3DBAG#181.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LZBFfd55Us1zg7chCUDs5C

guhur and others added 2 commits October 4, 2026 17:14
The loop that merges each footprint's buffer ground points into its point
cloud started from an uninitialised index, so whether those points were merged
depended on whatever the stack held. It now starts at 0, so they are always
merged, as the comment above the loop intends.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LZBFfd55Us1zg7chCUDs5C
…ng past it

gridthinPointcloud skipped points whose cell index was greater than the count
raster's size, but not the one equal to it, so a point mapping to that cell
read one element past the array. Whether it was kept, and whether a random
draw was consumed, then depended on that memory, and so did every following
point's draw. Footprint buffer ground points, which lie outside the
footprint's raster, hit this case.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LZBFfd55Us1zg7chCUDs5C
@guhur
guhur merged commit d4f3c99 into argile/v1.0.0 Oct 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant