use crate::core::shape::{CreateShape, ALL_TRIANGLE_MESHES}; use crate::core::texture::FloatTexture; use crate::shapes::mesh::TriangleMesh; use crate::{Arena, FileLoc, ParameterDictionary}; use anyhow::{bail, Result}; use log::warn; use shared::core::shape::Shape; use shared::shapes::TriangleShape; use shared::{Ptr, Transform}; use std::collections::HashMap; use std::sync::Arc; impl CreateShape for TriangleShape { fn create( render_from_object: Transform, _object_from_render: Transform, reverse_orientation: bool, parameters: ParameterDictionary, _float_texture: &HashMap>, _loc: FileLoc, arena: &Arena, ) -> Result>> { let mut vertex_indices = parameters.get_int_array("indices")?; let p = parameters.get_point3f_array("P")?; let mut uvs = parameters.get_point2f_array("uv")?; let mut s = parameters.get_vector3f_array("S")?; let mut n = parameters.get_normal3f_array("N")?; if vertex_indices.is_empty() { if p.len() == 3 { } else { bail!("Vertex indices \"indices\" must be provided with triangle mesh."); } } else if vertex_indices.len() % 3 != 0 { let excess = vertex_indices.len() % 3; warn!( "Number of vertex indices {} not a multiple of 3. Discarding {} excess.", vertex_indices.len(), excess ); let new_len = vertex_indices.len() - excess; vertex_indices.truncate(new_len); } if p.is_empty() { bail!("Vertex positions \"P\" must be provided with triangle mesh."); } if !uvs.is_empty() && uvs.len() != p.len() { warn!("Number of \"uv\"s for triangle mesh must match \"P\"s. Discarding uvs."); uvs.clear(); } if !s.is_empty() && s.len() != p.len() { warn!("Number of \"S\"s for triangle mesh must match \"P\"s. Discarding \"S\"s."); s.clear(); } if !n.is_empty() && n.len() != p.len() { warn!("Number of \"N\"s for triangle mesh must match \"P\"s. Discarding \"N\"s."); n.clear(); } for (_, &index) in vertex_indices.iter().enumerate() { // Check for negative indices (if keeping i32) or out of bounds if index < 0 || index as usize >= p.len() { bail!( "TriangleMesh has out-of-bounds vertex index {} ({} \"P\" values were given). Discarding this mesh.", index, p.len() ); } } let mut face_indices = parameters.get_int_array("faceIndices")?; let n_triangles = vertex_indices.len() / 3; if !face_indices.is_empty() && face_indices.len() != n_triangles { warn!( "Number of face indices {} does not match number of triangles {}. Discarding face indices.", face_indices.len(), n_triangles ); face_indices.clear(); } let host = TriangleMesh::new( &render_from_object, reverse_orientation, vertex_indices, p, n, s, uvs, face_indices, ); let host_arc = Arc::new(host); let mut global_store = ALL_TRIANGLE_MESHES.lock(); // let mesh_index = global_store.len() as u32; global_store.push(host_arc.clone()); drop(global_store); let n_patches = host_arc.device.n_triangles; let mesh_ptr = Ptr::from(&host_arc.device); let mut shapes = Vec::with_capacity(n_patches as usize); for i in 0..n_patches { shapes.push(arena.alloc(Shape::Triangle(TriangleShape { mesh: mesh_ptr, tri_index: i as i32, }))); } Ok(shapes) } }