162 lines
4.5 KiB
Rust
162 lines
4.5 KiB
Rust
use crate::core::pbrt::Float;
|
|
use crate::geometry::{Normal3f, Point2f, Point3f, Vector3f};
|
|
use crate::utils::sampling::PiecewiseConstant2D;
|
|
use crate::utils::transform::Transform;
|
|
use std::sync::Arc;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct TriangleMesh {
|
|
pub n_triangles: usize,
|
|
pub n_vertices: usize,
|
|
pub vertex_indices: Arc<Vec<usize>>,
|
|
pub p: Arc<Vec<Point3f>>,
|
|
pub n: Option<Arc<Vec<Normal3f>>>,
|
|
pub s: Option<Arc<Vec<Vector3f>>>,
|
|
pub uv: Option<Arc<Vec<Point2f>>>,
|
|
pub face_indices: Option<Arc<Vec<usize>>>,
|
|
pub reverse_orientation: bool,
|
|
pub transform_swaps_handedness: bool,
|
|
}
|
|
|
|
impl TriangleMesh {
|
|
#[allow(clippy::too_many_arguments)]
|
|
pub fn new(
|
|
render_from_object: &Transform<Float>,
|
|
reverse_orientation: bool,
|
|
indices: Vec<usize>,
|
|
mut p: Vec<Point3f>,
|
|
mut s: Vec<Vector3f>,
|
|
mut n: Vec<Normal3f>,
|
|
uv: Vec<Point2f>,
|
|
face_indices: Vec<usize>,
|
|
) -> Self {
|
|
let n_triangles = indices.len() / 3;
|
|
let n_vertices = p.len();
|
|
for pt in p.iter_mut() {
|
|
*pt = render_from_object.apply_to_point(*pt);
|
|
}
|
|
|
|
let transform_swaps_handedness = render_from_object.swaps_handedness();
|
|
|
|
let uv = if !uv.is_empty() {
|
|
assert_eq!(n_vertices, uv.len());
|
|
Some(uv)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let n = if !n.is_empty() {
|
|
assert_eq!(n_vertices, n.len());
|
|
for nn in n.iter_mut() {
|
|
*nn = render_from_object.apply_to_normal(*nn);
|
|
if reverse_orientation {
|
|
*nn = -*nn;
|
|
}
|
|
}
|
|
Some(n)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let s = if !s.is_empty() {
|
|
assert_eq!(n_vertices, s.len());
|
|
for ss in s.iter_mut() {
|
|
*ss = render_from_object.apply_to_vector(*ss);
|
|
}
|
|
Some(s)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let face_indices = if !face_indices.is_empty() {
|
|
assert_eq!(n_triangles, face_indices.len());
|
|
Some(face_indices)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
assert!(p.len() <= i32::MAX as usize);
|
|
assert!(indices.len() <= i32::MAX as usize);
|
|
|
|
Self {
|
|
n_triangles,
|
|
n_vertices,
|
|
vertex_indices: Arc::new(indices),
|
|
p: Arc::new(p),
|
|
n: n.map(Arc::new),
|
|
s: s.map(Arc::new),
|
|
uv: uv.map(Arc::new),
|
|
face_indices: face_indices.map(Arc::new),
|
|
reverse_orientation,
|
|
transform_swaps_handedness,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct BilinearPatchMesh {
|
|
pub reverse_orientation: bool,
|
|
pub transform_swaps_handedness: bool,
|
|
pub n_patches: usize,
|
|
pub n_vertices: usize,
|
|
pub vertex_indices: Arc<Vec<usize>>,
|
|
pub p: Arc<Vec<Point3f>>,
|
|
pub n: Option<Arc<Vec<Normal3f>>>,
|
|
pub uv: Option<Arc<Vec<Point2f>>>,
|
|
pub image_distribution: Option<PiecewiseConstant2D>,
|
|
}
|
|
|
|
impl BilinearPatchMesh {
|
|
pub fn new(
|
|
render_from_object: &Transform<Float>,
|
|
reverse_orientation: bool,
|
|
indices: Vec<usize>,
|
|
mut p: Vec<Point3f>,
|
|
mut n: Vec<Normal3f>,
|
|
uv: Vec<Point2f>,
|
|
image_distribution: PiecewiseConstant2D,
|
|
) -> Self {
|
|
let n_patches = indices.len() / 3;
|
|
let n_vertices = p.len();
|
|
for pt in p.iter_mut() {
|
|
*pt = render_from_object.apply_to_point(*pt);
|
|
}
|
|
|
|
let transform_swaps_handedness = render_from_object.swaps_handedness();
|
|
|
|
let uv = if !uv.is_empty() {
|
|
assert_eq!(n_vertices, uv.len());
|
|
Some(uv)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let n = if !n.is_empty() {
|
|
assert_eq!(n_vertices, n.len());
|
|
for nn in n.iter_mut() {
|
|
*nn = render_from_object.apply_to_normal(*nn);
|
|
if reverse_orientation {
|
|
*nn = -*nn;
|
|
}
|
|
}
|
|
Some(n)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
assert!(p.len() <= i32::MAX as usize);
|
|
assert!(indices.len() <= i32::MAX as usize);
|
|
|
|
Self {
|
|
n_patches,
|
|
n_vertices,
|
|
vertex_indices: Arc::new(indices),
|
|
p: Arc::new(p),
|
|
n: n.map(Arc::new),
|
|
uv: uv.map(Arc::new),
|
|
reverse_orientation,
|
|
transform_swaps_handedness,
|
|
image_distribution: Some(image_distribution),
|
|
}
|
|
}
|
|
}
|