#![allow(dead_code)]
use std::collections::{BTreeMap, HashMap};
use brepkit_math::tolerance::Tolerance;
use brepkit_math::vec::Point3;
use brepkit_topology::Topology;
use brepkit_topology::edge::EdgeId;
use brepkit_topology::face::{FaceId, FaceSurface};
use brepkit_topology::vertex::{Vertex, VertexId};
use brepkit_topology::wire::WireId;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum EdgeClass {
Tangent,
Convex {
angle: f64,
},
Concave {
angle: f64,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VertexClass {
Convex,
Concave,
Mixed,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OffsetStatus {
Done,
Excluded,
Failed,
}
#[derive(Debug, Clone)]
pub struct OffsetFace {
pub original: FaceId,
pub surface: FaceSurface,
pub distance: f64,
pub status: OffsetStatus,
}
#[derive(Debug, Clone)]
pub struct FaceIntersection {
pub original_edge: EdgeId,
pub face_a: FaceId,
pub face_b: FaceId,
pub curve_points: Vec<Point3>,
pub new_edges: Vec<EdgeId>,
}
#[derive(Debug, Clone)]
pub struct SplitPoint {
pub parameter: f64,
pub vertex: VertexId,
}
#[derive(Debug, Clone)]
pub struct EdgeSplitRecord {
pub original: EdgeId,
pub splits: Vec<SplitPoint>,
pub new_edges: Vec<EdgeId>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum JointType {
#[default]
Intersection,
Arc,
}
#[derive(Debug, Clone)]
pub struct OffsetOptions {
pub joint: JointType,
pub tolerance: Tolerance,
pub remove_self_intersections: bool,
}
#[allow(clippy::derivable_impls)] impl Default for OffsetOptions {
fn default() -> Self {
Self {
joint: JointType::default(),
tolerance: Tolerance::default(),
remove_self_intersections: false,
}
}
}
#[derive(Debug, Clone)]
pub struct OffsetData {
pub distance: f64,
pub options: OffsetOptions,
pub excluded_faces: Vec<FaceId>,
pub edge_class: BTreeMap<usize, EdgeClass>,
pub vertex_class: BTreeMap<usize, VertexClass>,
pub offset_faces: HashMap<FaceId, OffsetFace>,
pub intersections: Vec<FaceIntersection>,
pub edge_splits: BTreeMap<usize, EdgeSplitRecord>,
pub boundary_edges: HashMap<FaceId, Vec<EdgeId>>,
pub joint_faces: Vec<FaceId>,
pub face_wires: HashMap<FaceId, Vec<WireId>>,
}
impl OffsetData {
#[must_use]
pub fn new(distance: f64, options: OffsetOptions, excluded_faces: Vec<FaceId>) -> Self {
Self {
distance,
options,
excluded_faces,
edge_class: BTreeMap::new(),
vertex_class: BTreeMap::new(),
offset_faces: HashMap::new(),
intersections: Vec::new(),
edge_splits: BTreeMap::new(),
boundary_edges: HashMap::new(),
joint_faces: Vec::new(),
face_wires: HashMap::new(),
}
}
}
pub fn find_or_create_vertex(
topo: &mut Topology,
cache: &mut Vec<(Point3, VertexId)>,
point: Point3,
tol: f64,
) -> VertexId {
for &(cached_pt, vid) in cache.iter() {
let dx = point.x() - cached_pt.x();
let dy = point.y() - cached_pt.y();
let dz = point.z() - cached_pt.z();
if dx * dx + dy * dy + dz * dz <= tol * tol {
return vid;
}
}
let vid = topo.add_vertex(Vertex::new(point, tol));
cache.push((point, vid));
vid
}