Fix CSG edge case causing intersection line to hit on common edge of 2 triangles.

The previous implementation assumed that the intersection entered or exited a
shape when it hit right on the common edge of 2 triangles. However, there is
also a case where it just "skirts" the other shape on the outside.

To fix this, we added code to check the intersection distance and if the
normals of the faces are pointed in the same direction as the intersection or
not (e.g. inner product > 0). This handles the case where the intersection
line hits the common edge of 2 triangles and skirts the other shape on the
outside.

Extended code to cover a third case.

Fixes #58637.

Co-authored-by: OldBelge <StevenGeens@users.noreply.github.com>
This commit is contained in:
K. S. Ernest (iFire) Lee
2023-03-13 07:13:25 -07:00
committed by Rémi Verschelde
parent 352ebe9725
commit eaa84bc682
4 changed files with 80 additions and 17 deletions

View File

@@ -135,6 +135,17 @@ struct CSGBrushOperation {
return h;
}
};
struct Intersection {
bool found = false;
real_t conormal = FLT_MAX;
real_t distance_squared = FLT_MAX;
real_t origin_angle = FLT_MAX;
};
struct IntersectionDistance {
bool is_conormal;
real_t distance_squared;
};
Vector<Vector3> points;
Vector<Face> faces;
@@ -143,7 +154,7 @@ struct CSGBrushOperation {
OAHashMap<VertexKey, int, VertexKeyHash> snap_cache;
float vertex_snap = 0.0;
inline void _add_distance(List<real_t> &r_intersectionsA, List<real_t> &r_intersectionsB, bool p_from_B, real_t p_distance) const;
inline void _add_distance(List<IntersectionDistance> &r_intersectionsA, List<IntersectionDistance> &r_intersectionsB, bool p_from_B, real_t p_distance, bool p_is_conormal) const;
inline bool _bvh_inside(FaceBVH *facebvhptr, int p_max_depth, int p_bvh_first, int p_face_idx) const;
inline int _create_bvh(FaceBVH *facebvhptr, FaceBVH **facebvhptrptr, int p_from, int p_size, int p_depth, int &r_max_depth, int &r_max_alloc);