Repository navigation
Conversation
…ger race updated_polygons_around_vertex (and the solid equivalent) checked the cache without the lock, then reset and recomputed it: two const callers could reassign the cached vector while a third was reading it. An isolated vertex was also recomputed on every call. CachedValue::recompute_if_invalid keeps the lock-free fast path and re-checks validity under the lock before recomputing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
create_*_meshes_aabb_trees only skipped meshes without vertices: a surface with vertices but no polygons (or a line without edges) got an empty mesh tree and bounding_box() threw. Such components are now skipped like empty meshes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sign was taken from the first non-degenerate fan triangle from vertex 0, which is wrong for concave polygons. It now uses the exact corner orientation at the lexicographically smallest vertex, which is always convex. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…normal Coplanar segments were projected by dropping the thinnest bounding box axis; when the segments plane contains that axis both segments collapse on a single 2D line and crossings are missed, e.g. (0,0,0)-(1,1,0.2) and (1,1,0)-(0,0,0.2). The dropped axis is now the largest component of the plane normal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 2D triangle test only looked for crossing edges: a triangle strictly inside another one, or nested in its corner at a common vertex, was not reported. A non-common vertex of each triangle is now located in the other. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
polygons_intersection_detection rebuilt the fan triangles of the other polygon for every triangle of the first one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The propagation stopped after 1000 polygons and reported broken adjacencies for any valid vertex with more polygons (e.g. a fan center). The bound now depends on the number of polygons of the mesh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The safety counter of propagate_around_edge was never incremented, so the guard against broken adjacencies could not trigger. It is now incremented and scaled with the number of polyhedra. The new test checks broken adjacencies around an edge are handled (it cannot loop forever with tetrahedra, so it also passes without the counter fix). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cpp-Linter Report
|
Summary
OpenGeode root causes found while reviewing OpenGeode-Inspector. There is one commit per fix, and each fix comes with a test.
polygons_around_vertex/polyhedra_around_vertexrace.updated_polygons_around_vertexchecked the cache without the lock, then reset and recomputed it. Two const callers could therefore reassign the cached vector while a third was reading it. The Inspector hits this by running topology checks (is_vertex_on_border) and mesh checks on the same meshes in parallel. An isolated vertex was also recomputed on every call. The newCachedValue::recompute_if_invalidkeeps the lock-free fast path and re-checks validity under the lock. No lock is added on the hot read path.bounding_box()then threw. Such meshes are now skipped.polygon_area_signwith concave polygons. It used the first fan triangle, which is wrong for concave polygons, e.g.(0,0),(2,1),(4,0),(2,3). It now uses the exact corner orientation at the lexicographically smallest vertex.segment_segment_intersection_detectionprojection. It dropped the thinnest bounding box axis, so segments whose plane contains that axis collapsed onto a single line. The dropped axis is now the largest component of the plane normal.polygons_around_vertexsafety bound. The fixed bound of 1000 polygons threw for valid high valence vertices; it now scales with the number of polygons. Thepropagate_around_edgesafety counter was never incremented; it now is.🤖 Generated with Claude Code