@@ -353,86 +353,94 @@ BisectionResult bisectEdge(MeshGraph &mesh, size_t edgeId)
353353
354354size_t refineTriangle (MeshGraph &mesh, const TriangleId &tri, int maxDepth)
355355{
356- if (maxDepth <= 0 )
357- {
358- spdlog::warn (" refineTriangle: max depth reached, stopping refinement" );
359- return 0 ;
360- }
356+ size_t trianglesCreated = 0 ;
357+ TriangleId currentTri = tri;
361358
362- auto vertices = getTriangleVertices (mesh, tri);
363- if (vertices[0 ] == 0 && vertices[1 ] == 0 && vertices[2 ] == 0 )
359+ // Loop handles retries after neighbor refinement invalidates our triangle.
360+ // Depth is only consumed by neighbor propagation, not by retries.
361+ for (;;)
364362 {
365- spdlog::debug (" refineTriangle: triangle (edge={}, side={}) has invalid vertices" , tri.edgeId , tri.side );
366- return 0 ;
367- }
363+ if (maxDepth <= 0 )
364+ {
365+ spdlog::warn (" refineTriangle: max depth reached, stopping refinement" );
366+ return trianglesCreated;
367+ }
368368
369- size_t longestEdgeId = findLongestEdge (mesh, tri );
370- if (longestEdgeId == 0 )
371- {
372- spdlog::debug (" refineTriangle: could not find longest edge for triangle (edge={}, side={})" , tri .edgeId ,
373- tri .side );
374- return 0 ;
375- }
369+ auto vertices = getTriangleVertices (mesh, currentTri );
370+ if (vertices[ 0 ] == 0 && vertices[ 1 ] == 0 && vertices[ 2 ] == 0 )
371+ {
372+ spdlog::debug (" refineTriangle: triangle (edge={}, side={}) has invalid vertices " , currentTri .edgeId ,
373+ currentTri .side );
374+ return trianglesCreated ;
375+ }
376376
377- const auto *longestEdge = mesh.getEdge (longestEdgeId);
378- if (!longestEdge)
379- return 0 ;
377+ size_t longestEdgeId = findLongestEdge (mesh, currentTri);
378+ if (longestEdgeId == 0 )
379+ {
380+ spdlog::debug (" refineTriangle: could not find longest edge for triangle (edge={}, side={})" ,
381+ currentTri.edgeId , currentTri.side );
382+ return trianglesCreated;
383+ }
380384
381- // conforming refinement: bisect at the longest edge, refining the neighbor first if needed
382- size_t trianglesCreated = 0 ;
385+ const auto *longestEdge = mesh.getEdge (longestEdgeId);
386+ if (!longestEdge)
387+ return trianglesCreated;
383388
384- if (!longestEdge->payload .border )
385- {
386- int ourSide = -1 ;
387- for (int v = 0 ; v < 3 ; v++)
389+ // conforming refinement: bisect at the longest edge, refining the neighbor first if needed
390+ if (!longestEdge->payload .border )
388391 {
389- int side = findTriangleSide (mesh, longestEdgeId, vertices[v]) ;
390- if (side > = 0 )
392+ int ourSide = - 1 ;
393+ for ( int v = 0 ; v < 3 ; v++ )
391394 {
392- ourSide = side;
393- break ;
395+ int side = findTriangleSide (mesh, longestEdgeId, vertices[v]);
396+ if (side >= 0 )
397+ {
398+ ourSide = side;
399+ break ;
400+ }
394401 }
395- }
396-
397- if (ourSide >= 0 )
398- {
399- TriangleId neighbor = {longestEdgeId, 1 - ourSide};
400402
401- size_t neighborLongest = findLongestEdge (mesh, neighbor);
402- if (neighborLongest != 0 && neighborLongest != longestEdgeId)
403+ if (ourSide >= 0 )
403404 {
404- trianglesCreated += refineTriangle (mesh, neighbor, maxDepth - 1 ) ;
405+ TriangleId neighbor = {longestEdgeId, 1 - ourSide} ;
405406
406- // The recursive refinement may have bisected our longest edge,
407- // invalidating this triangle — re-locate via original vertices
408- Eigen::Vector3d center = Eigen::Vector3d::Zero ();
409- for (int i = 0 ; i < 3 ; i++)
407+ size_t neighborLongest = findLongestEdge (mesh, neighbor);
408+ if (neighborLongest != 0 && neighborLongest != longestEdgeId)
410409 {
411- const auto *n = mesh.getNode (vertices[i]);
412- if (n)
413- center += n->payload .location ;
414- }
415- center /= 3.0 ;
410+ trianglesCreated += refineTriangle (mesh, neighbor, maxDepth - 1 );
416411
417- TriangleId newTri = findTriangleNearVertices (mesh, vertices, center.x (), center.y ());
418- if (newTri.edgeId != 0 )
419- {
420- return trianglesCreated + refineTriangle (mesh, newTri, maxDepth - 1 );
412+ // The recursive refinement may have bisected our longest edge,
413+ // invalidating this triangle — re-locate via original vertices
414+ Eigen::Vector3d center = Eigen::Vector3d::Zero ();
415+ for (int i = 0 ; i < 3 ; i++)
416+ {
417+ const auto *n = mesh.getNode (vertices[i]);
418+ if (n)
419+ center += n->payload .location ;
420+ }
421+ center /= 3.0 ;
422+
423+ TriangleId newTri = findTriangleNearVertices (mesh, vertices, center.x (), center.y ());
424+ if (newTri.edgeId == 0 )
425+ return trianglesCreated;
426+
427+ // Retry with the re-located triangle without consuming depth
428+ currentTri = newTri;
429+ continue ;
421430 }
422- return trianglesCreated;
423431 }
424432 }
425- }
426433
427- bool wasBorder = longestEdge->payload .border ;
428- auto result = bisectEdge (mesh, longestEdgeId);
429- if (result.newVertexId != 0 )
430- {
431- // We created 2 new triangles on each side (4 total, or 2 if border)
432- trianglesCreated += wasBorder ? 2 : 4 ;
433- }
434+ bool wasBorder = longestEdge->payload .border ;
435+ auto result = bisectEdge (mesh, longestEdgeId);
436+ if (result.newVertexId != 0 )
437+ {
438+ // We created 2 new triangles on each side (4 total, or 2 if border)
439+ trianglesCreated += wasBorder ? 2 : 4 ;
440+ }
434441
435- return trianglesCreated;
442+ return trianglesCreated;
443+ }
436444}
437445
438446size_t refineAtPoint (MeshGraph &mesh, double x, double y, int levels)
0 commit comments