use std::collections::HashMap;
use crate::ids::{FaceId, HalfEdgeId, VertexId};
use crate::storage::{Face, HalfEdge, MeshStorage};
use super::helpers::TopologyError;
use super::validate::validate_mesh;
pub fn add_triangle(
mesh: &mut MeshStorage,
v0: VertexId,
v1: VertexId,
v2: VertexId,
) -> Result<FaceId, TopologyError> {
if v0 == v1 || v1 == v2 || v0 == v2 {
return Err(TopologyError::DegenerateTriangle);
}
if !mesh.contains_vertex(v0) || !mesh.contains_vertex(v1) || !mesh.contains_vertex(v2) {
return Err(TopologyError::Inconsistent("顶点不存在".into()));
}
let h0 = mesh.add_halfedge(HalfEdge::new(v1)); let h1 = mesh.add_halfedge(HalfEdge::new(v2)); let h2 = mesh.add_halfedge(HalfEdge::new(v0));
for (he, next, prev) in [(h0, h1, h2), (h1, h2, h0), (h2, h0, h1)] {
let h = mesh
.get_halfedge_mut(he)
.expect("he just created by add_halfedge");
h.next = Some(next);
h.prev = Some(prev);
}
let face = mesh.add_face(Face::new());
mesh.get_face_mut(face).expect("face just created").halfedge = Some(h0);
for he in [h0, h1, h2] {
mesh.get_halfedge_mut(he)
.expect("he just created by add_halfedge")
.face = Some(face);
}
let mut boundary_twin_map: HashMap<(VertexId, VertexId), HalfEdgeId> = HashMap::new();
for ehe in mesh.halfedge_ids() {
if ehe == h0 || ehe == h1 || ehe == h2 {
continue;
}
let h = match mesh.get_halfedge(ehe) {
Some(h) => h,
None => continue,
};
if let Some(twin_id) = h.twin
&& let Some(twin_data) = mesh.get_halfedge(twin_id)
&& twin_data.face.is_none()
{
boundary_twin_map.insert((twin_data.vertex, h.vertex), ehe);
}
}
let edges = [(h0, v0, v1), (h1, v1, v2), (h2, v2, v0)];
for (he, src, dst) in edges {
let existing: Option<HalfEdgeId> = boundary_twin_map.get(&(dst, src)).copied();
match existing {
Some(ex) => {
let old_twin = mesh
.get_halfedge(ex)
.expect("ex from boundary_twin_map, validated")
.twin;
if let Some(old) = old_twin {
mesh.remove_halfedge(old);
}
mesh.get_halfedge_mut(he).expect("he just created").twin = Some(ex);
mesh.get_halfedge_mut(ex)
.expect("ex from boundary_twin_map, validated")
.twin = Some(he);
}
None => {
let twin = mesh.add_halfedge(HalfEdge::new(src));
mesh.get_halfedge_mut(he).expect("he just created").twin = Some(twin);
mesh.get_halfedge_mut(twin).expect("twin just created").twin = Some(he);
}
}
}
for (v, he) in [(v0, h0), (v1, h1), (v2, h2)] {
if mesh
.get_vertex(v)
.expect("v validated by contains_vertex")
.halfedge
.is_none()
{
mesh.get_vertex_mut(v)
.expect("v validated by contains_vertex")
.halfedge = Some(he);
}
}
validate_mesh(mesh)?;
Ok(face)
}