57 lines
1.9 KiB
C++
57 lines
1.9 KiB
C++
|
|
#pragma once
|
||
|
|
/**
|
||
|
|
* @file brep_face_split.h
|
||
|
|
* @brief B-Rep face splitting by plane
|
||
|
|
*
|
||
|
|
* Splits faces that partially intersect a cutting plane, producing
|
||
|
|
* cleanly separated face fragments. Used to improve boolean operation
|
||
|
|
* quality by replacing coarse centroid-based IN/OUT classification
|
||
|
|
* with precise geometric splitting.
|
||
|
|
*
|
||
|
|
* @ingroup brep
|
||
|
|
*/
|
||
|
|
#include "vde/brep/brep.h"
|
||
|
|
#include "vde/core/point.h"
|
||
|
|
#include <vector>
|
||
|
|
|
||
|
|
namespace vde::brep {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Split a face by a plane
|
||
|
|
*
|
||
|
|
* Cuts a single B-Rep face with an infinite plane, producing up to
|
||
|
|
* two face fragments (one on each side of the plane). Each fragment
|
||
|
|
* is a valid BrepModel with proper loop topology.
|
||
|
|
*
|
||
|
|
* **Algorithm:**
|
||
|
|
* 1. Get the face's ordered vertices by traversing the outer loop
|
||
|
|
* 2. Classify each vertex as positive (distance ≥ 0) or negative (distance < 0)
|
||
|
|
* 3. If all vertices are on the same side: return the face as a single fragment
|
||
|
|
* 4. Otherwise: build two new faces:
|
||
|
|
* - Face A: vertices on the positive side + intersection points
|
||
|
|
* - Face B: vertices on the negative side + intersection points
|
||
|
|
*
|
||
|
|
* @param body Source B-Rep body containing the face
|
||
|
|
* @param face_id Index of the face to split
|
||
|
|
* @param plane_point A point on the cutting plane
|
||
|
|
* @param plane_normal Normal vector of the cutting plane (need not be unit-length)
|
||
|
|
* @return Vector of 0, 1, or 2 face fragment BrepModels
|
||
|
|
*
|
||
|
|
* @code{.cpp}
|
||
|
|
* auto box = make_box(2, 2, 2);
|
||
|
|
* // Split face 0 of the box with the YZ plane (x=0)
|
||
|
|
* auto frags = split_face_by_plane(box, 0, Point3D(0,0,0), Vector3D(1,0,0));
|
||
|
|
* // frags.size() == 2: left half and right half
|
||
|
|
* for (auto& f : frags) {
|
||
|
|
* // Each fragment has its own vertices, edges, loop, and surface
|
||
|
|
* assert(f.is_valid());
|
||
|
|
* }
|
||
|
|
* @endcode
|
||
|
|
*/
|
||
|
|
[[nodiscard]] std::vector<BrepModel> split_face_by_plane(
|
||
|
|
const BrepModel& body, int face_id,
|
||
|
|
const core::Point3D& plane_point,
|
||
|
|
const core::Vector3D& plane_normal);
|
||
|
|
|
||
|
|
} // namespace vde::brep
|