use num_traits::{AsPrimitive, PrimInt};
pub fn update_for_points_with_bvh<Index, Real>(
bvhnode2aabb: &mut [[Real; 6]],
i_bvhnode: usize,
bvhnodes: &[[Index; 3]],
vtx2xyz0: &[[Real; 3]],
vtx2xyz1: Option<&[[Real; 3]]>,
) where
Real: num_traits::Float,
Index: PrimInt + AsPrimitive<usize>,
{
assert_eq!(bvhnode2aabb.len(), bvhnodes.len());
assert!(i_bvhnode < bvhnodes.len());
assert!(if let Some(vtx2xyz1) = vtx2xyz1 {
vtx2xyz1.len() == vtx2xyz0.len()
} else {
true
});
if bvhnodes[i_bvhnode][2] == Index::max_value() {
let i_elem: usize = bvhnodes[i_bvhnode][1].as_();
let aabb0 = crate::vtx2xyz::to_xyz(vtx2xyz0.as_flattened(), i_elem).aabb();
let aabb = if let Some(vtx2xyz1) = vtx2xyz1 {
let aabb1 = crate::vtx2xyz::to_xyz(vtx2xyz1.as_flattened(), i_elem).aabb();
del_geo_core::aabb3::from_two_aabbs(&aabb0, &aabb1)
} else {
aabb0
};
bvhnode2aabb[i_bvhnode] = aabb;
} else {
let i_bvhnode_child0: usize = bvhnodes[i_bvhnode][1].as_();
let i_bvhnode_child1: usize = bvhnodes[i_bvhnode][2].as_();
assert_eq!(bvhnodes[i_bvhnode_child0][0].as_(), i_bvhnode);
assert_eq!(bvhnodes[i_bvhnode_child1][0].as_(), i_bvhnode);
update_for_points_with_bvh::<Index, Real>(
bvhnode2aabb,
i_bvhnode_child0,
bvhnodes,
vtx2xyz0,
vtx2xyz1,
);
update_for_points_with_bvh::<Index, Real>(
bvhnode2aabb,
i_bvhnode_child1,
bvhnodes,
vtx2xyz0,
vtx2xyz1,
);
let aabb = del_geo_core::aabb3::from_two_aabbs(
&bvhnode2aabb[i_bvhnode_child0],
&bvhnode2aabb[i_bvhnode_child1],
);
bvhnode2aabb[i_bvhnode] = aabb;
}
}
pub fn update_for_uniform_mesh_with_bvh<Index, Real, const NNOEL: usize>(
bvhnode2aabb: &mut [[Real; 6]],
i_bvhnode: usize,
bvhnodes: &[[Index; 3]],
elem2vtx: &[[Index; NNOEL]],
vtx2xyz0: &[[Real; 3]],
vtx2xyz1: Option<&[[Real; 3]]>,
) where
Real: num_traits::Float,
Index: PrimInt + AsPrimitive<usize>,
{
assert_eq!(bvhnode2aabb.len(), bvhnodes.len());
assert!(i_bvhnode < bvhnodes.len());
assert!(if let Some(vtx2xyz1) = vtx2xyz1 {
vtx2xyz1.len() == vtx2xyz0.len()
} else {
true
});
if bvhnodes[i_bvhnode][2] == Index::max_value() {
let i_elem: usize = bvhnodes[i_bvhnode][1].as_();
let aabb = {
let aabb0 =
crate::vtx2xyz::aabb3_indexed(elem2vtx[i_elem].as_slice(), vtx2xyz0, Real::zero());
if let Some(vtx2xyz1) = vtx2xyz1 {
let aabb1 = crate::vtx2xyz::aabb3_indexed(
elem2vtx[i_elem].as_slice(),
vtx2xyz1,
Real::zero(),
);
del_geo_core::aabb3::from_two_aabbs(&aabb0, &aabb1)
} else {
aabb0
}
};
bvhnode2aabb[i_bvhnode] = aabb;
} else {
let i_bvhnode_child0: usize = bvhnodes[i_bvhnode][1].as_();
let i_bvhnode_child1: usize = bvhnodes[i_bvhnode][2].as_();
assert_eq!(bvhnodes[i_bvhnode_child0][0].as_(), i_bvhnode);
assert_eq!(bvhnodes[i_bvhnode_child1][0].as_(), i_bvhnode);
update_for_uniform_mesh_with_bvh::<Index, Real, NNOEL>(
bvhnode2aabb,
i_bvhnode_child0,
bvhnodes,
elem2vtx,
vtx2xyz0,
vtx2xyz1,
);
update_for_uniform_mesh_with_bvh::<Index, Real, NNOEL>(
bvhnode2aabb,
i_bvhnode_child1,
bvhnodes,
elem2vtx,
vtx2xyz0,
vtx2xyz1,
);
let aabb = del_geo_core::aabb3::from_two_aabbs(
&bvhnode2aabb[i_bvhnode_child0],
&bvhnode2aabb[i_bvhnode_child1],
);
bvhnode2aabb[i_bvhnode] = aabb;
}
}
pub fn from_uniform_mesh_with_bvh<Index, Real, const NNOEL: usize>(
i_bvhnode: usize,
bvhnodes: &[[Index; 3]],
elem2vtx: &[[Index; NNOEL]],
vtx2xyz0: &[[Real; 3]],
vtx2xyz1: Option<&[[Real; 3]]>,
) -> Vec<[Real; 6]>
where
Real: num_traits::Float,
Index: PrimInt + AsPrimitive<usize>,
{
let num_bvhnode = bvhnodes.len();
let mut bvhnode2aabb = vec![[Real::zero(); 6]; num_bvhnode];
update_for_uniform_mesh_with_bvh::<Index, Real, NNOEL>(
&mut bvhnode2aabb,
i_bvhnode,
bvhnodes,
elem2vtx,
vtx2xyz0,
vtx2xyz1,
);
bvhnode2aabb
}
pub fn update_for_polygon_polyhedron_mesh_with_bvh<Index, Real>(
bvhnode2aabb: &mut [[Real; 6]],
i_bvhnode: usize,
bvhnodes: &[[Index; 3]],
elem2idx: &[Index],
idx2vtx: &[Index],
vtx2xyz: &[[Real; 3]],
) where
Real: num_traits::Float,
Index: PrimInt + AsPrimitive<usize>,
{
assert_eq!(bvhnode2aabb.len(), bvhnodes.len());
assert!(i_bvhnode < bvhnodes.len());
if bvhnodes[i_bvhnode][2] == Index::max_value() {
let i_elem: usize = bvhnodes[i_bvhnode][1].as_();
let aabb = {
let zero = Real::zero();
let idx0: usize = elem2idx[i_elem].as_();
let idx1: usize = elem2idx[i_elem + 1].as_();
let p0 = &vtx2xyz[idx2vtx[idx0].as_()];
let mut aabb3 = [zero; 6];
del_geo_core::aabb3::set_as_cube(&mut aabb3, p0, zero);
for &i_vtx in &idx2vtx[idx0 + 1..idx1] {
del_geo_core::aabb3::add_point(&mut aabb3, &vtx2xyz[i_vtx.as_()], zero);
}
aabb3
};
bvhnode2aabb[i_bvhnode] = aabb;
} else {
let i_bvhnode_child0: usize = bvhnodes[i_bvhnode][1].as_();
let i_bvhnode_child1: usize = bvhnodes[i_bvhnode][2].as_();
assert_eq!(bvhnodes[i_bvhnode_child0][0].as_(), i_bvhnode);
assert_eq!(bvhnodes[i_bvhnode_child1][0].as_(), i_bvhnode);
update_for_polygon_polyhedron_mesh_with_bvh::<Index, Real>(
bvhnode2aabb,
i_bvhnode_child0,
bvhnodes,
elem2idx,
idx2vtx,
vtx2xyz,
);
update_for_polygon_polyhedron_mesh_with_bvh::<Index, Real>(
bvhnode2aabb,
i_bvhnode_child1,
bvhnodes,
elem2idx,
idx2vtx,
vtx2xyz,
);
let aabb = del_geo_core::aabb3::from_two_aabbs(
&bvhnode2aabb[i_bvhnode_child0],
&bvhnode2aabb[i_bvhnode_child1],
);
bvhnode2aabb[i_bvhnode] = aabb;
}
}
pub fn from_polygon_polyhedron_mesh_with_bvh<Index, Real>(
i_bvhnode: usize,
bvhnodes: &[[Index; 3]],
elem2idx: &[Index],
idx2vtx: &[Index],
vtx2xyz: &[[Real; 3]],
) -> Vec<[Real; 6]>
where
Real: num_traits::Float,
Index: PrimInt + AsPrimitive<usize>,
{
let num_bvhnode = bvhnodes.len();
let mut bvhnode2aabb = vec![[Real::zero(); 6]; num_bvhnode];
update_for_polygon_polyhedron_mesh_with_bvh(
&mut bvhnode2aabb,
i_bvhnode,
bvhnodes,
elem2idx,
idx2vtx,
vtx2xyz,
);
bvhnode2aabb
}