#![cfg(not(target_arch = "wasm32"))] use truck_meshalgo::prelude::*; use truck_topology::*; use vtkio::model::*; fn truck_simple_cube() -> PolygonMesh { let positions = vec![ Point3::new(0.0, 0.0, 0.0), Point3::new(1.0, 0.0, 0.0), Point3::new(0.0, 1.0, 0.0), Point3::new(1.0, 1.0, 0.0), Point3::new(0.0, 0.0, 1.0), Point3::new(1.0, 0.0, 1.0), Point3::new(0.0, 1.0, 1.0), Point3::new(1.0, 1.0, 1.0), ]; let faces: Faces = vec![ [0, 2, 3].as_slice(), &[0, 3, 1], &[0, 1, 5, 4], &[1, 3, 7, 5], &[3, 2, 6, 7], &[2, 0, 4, 6], &[4, 5, 7, 6], ] .into_iter() .collect(); PolygonMesh::new( StandardAttributes { positions, ..Default::default() }, faces, ) } fn vtk_simple_cube() -> DataSet { #[rustfmt::skip] let points = IOBuffer::F64(vec![ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, ]); let vertex_numbers = VertexNumbers::XML { #[rustfmt::skip] connectivity: vec![ 0, 2, 3, 0, 3, 1, 0, 1, 5, 4, 1, 3, 7, 5, 3, 2, 6, 7, 2, 0, 4, 6, 4, 5, 7, 6, ], offsets: vec![3, 6, 10, 14, 18, 22, 26], }; let piece = PolyDataPiece { points, polys: Some(vertex_numbers), ..Default::default() }; DataSet::PolyData { meta: None, pieces: vec![Piece::Inline(Box::new(piece))], } } #[test] fn polygon() { assert_eq!(truck_simple_cube().to_data_set(), vtk_simple_cube()); } #[test] fn vertex() { let v = Vertex::new(Point3::new(0.0, 0.0, 0.0)); let data = v.to_data_set(); let ans_data = DataSet::UnstructuredGrid { meta: None, pieces: vec![Piece::Inline(Box::new(UnstructuredGridPiece { points: IOBuffer::F64(vec![0.0, 0.0, 0.0]), cells: Cells { cell_verts: VertexNumbers::XML { connectivity: vec![0], offsets: vec![1], }, types: vec![CellType::Vertex], }, data: Default::default(), }))], }; assert_eq!(data, ans_data); } #[test] fn edge() { let edge = Edge::new( &Vertex::new(Point3::new(0.0, 0.0, 0.0)), &Vertex::new(Point3::new(0.0, 1.0, 0.0)), PolylineCurve(vec![ Point3::new(0.0, 0.0, 0.0), Point3::new(1.0, 0.0, 0.0), Point3::new(1.0, 1.0, 0.0), Point3::new(0.0, 1.0, 0.0), ]), ); let data = edge.to_data_set(); let ans_data = DataSet::UnstructuredGrid { meta: None, pieces: vec![Piece::Inline(Box::new(UnstructuredGridPiece { points: IOBuffer::F64(vec![ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, ]), cells: Cells { cell_verts: VertexNumbers::XML { connectivity: vec![0, 1, 2, 3, 0, 3], offsets: vec![4, 5, 6], }, types: vec![CellType::PolyLine, CellType::Vertex, CellType::Vertex], }, data: Default::default(), }))], }; assert_eq!(data, ans_data); // inverse case let data = edge.inverse().to_data_set(); let ans_data = DataSet::UnstructuredGrid { meta: None, pieces: vec![Piece::Inline(Box::new(UnstructuredGridPiece { points: IOBuffer::F64(vec![ 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, ]), cells: Cells { cell_verts: VertexNumbers::XML { connectivity: vec![0, 1, 2, 3, 0, 3], offsets: vec![4, 5, 6], }, types: vec![CellType::PolyLine, CellType::Vertex, CellType::Vertex], }, data: Default::default(), }))], }; assert_eq!(data, ans_data); } #[test] fn wire() { let p = [ Point3::new(0.0, 0.0, 0.0), Point3::new(1.0, 0.0, 0.0), Point3::new(1.0, 1.0, 0.0), Point3::new(0.0, 1.0, 0.0), ]; let v = Vertex::news(p); let q = Point3::new(2.0, 0.0, 0.0); let wire: Wire> = vec![ Edge::new(&v[0], &v[1], PolylineCurve(vec![p[0], p[1]])), Edge::new(&v[2], &v[1], PolylineCurve(vec![p[2], q, p[1]])).inverse(), Edge::new(&v[3], &v[0], PolylineCurve(vec![p[3], p[0]])), ] .into(); let data = wire.to_data_set(); let ans_data = DataSet::UnstructuredGrid { meta: None, pieces: vec![Piece::Inline(Box::new(UnstructuredGridPiece { points: IOBuffer::F64(vec![ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 2.0, 0.0, 0.0, ]), cells: Cells { cell_verts: VertexNumbers::XML { connectivity: vec![0, 1, 1, 4, 2, 3, 0, 0, 1, 2, 3], offsets: vec![2, 5, 7, 8, 9, 10, 11], }, types: vec![ CellType::PolyLine, CellType::PolyLine, CellType::PolyLine, CellType::Vertex, CellType::Vertex, CellType::Vertex, CellType::Vertex, ], }, data: Default::default(), }))], }; assert_eq!(data, ans_data); } fn shell_topology() -> Shell, PolygonMesh> { let p = [ Point3::new(0.0, 0.0, 0.0), Point3::new(1.0, 0.0, 0.0), Point3::new(0.0, 1.0, 0.0), Point3::new(1.0, 1.0, 0.0), Point3::new(0.0, 0.0, -1.0), Point3::new(1.0, 0.0, -1.0), Point3::new(0.5, 0.25, 0.0), Point3::new(0.75, 0.5, 0.0), Point3::new(0.5, 0.75, 0.0), Point3::new(0.25, 0.5, 0.0), ]; let v = Vertex::news(p); let q = [ Point3::new(0.75, 0.25, 0.0), Point3::new(0.75, 0.75, 0.0), Point3::new(0.25, 0.75, 0.0), Point3::new(0.25, 0.25, 0.0), ]; let e = [ Edge::new(&v[0], &v[1], PolylineCurve(vec![p[0], p[1]])), Edge::new(&v[1], &v[3], PolylineCurve(vec![p[1], p[3]])), Edge::new(&v[3], &v[2], PolylineCurve(vec![p[3], p[2]])), Edge::new(&v[2], &v[0], PolylineCurve(vec![p[2], p[0]])), Edge::new(&v[0], &v[4], PolylineCurve(vec![p[0], p[4]])), Edge::new(&v[4], &v[5], PolylineCurve(vec![p[4], p[5]])), Edge::new(&v[5], &v[1], PolylineCurve(vec![p[5], p[1]])), Edge::new(&v[6], &v[7], PolylineCurve(vec![p[6], q[0], p[7]])), Edge::new(&v[7], &v[8], PolylineCurve(vec![p[7], q[1], p[8]])), Edge::new(&v[8], &v[9], PolylineCurve(vec![p[8], q[2], p[9]])), Edge::new(&v[9], &v[6], PolylineCurve(vec![p[9], q[3], p[6]])), ]; let polygon0 = PolygonMesh::new( StandardAttributes { positions: [&p[0..4], &p[6..10], &q[0..4]].concat().to_owned(), uv_coords: vec![ p[0].to_vec().truncate(), p[1].to_vec().truncate(), p[2].to_vec().truncate(), p[3].to_vec().truncate(), p[6].to_vec().truncate(), p[7].to_vec().truncate(), p[8].to_vec().truncate(), p[9].to_vec().truncate(), q[0].to_vec().truncate(), q[1].to_vec().truncate(), q[2].to_vec().truncate(), q[3].to_vec().truncate(), ], normals: vec![Vector3::new(0.0, 0.0, 1.0)], }, Faces::from_iter([ [ (0, Some(0), Some(0)), (4, Some(4), Some(0)), (11, Some(11), Some(0)), ], [ (0, Some(0), Some(0)), (1, Some(1), Some(0)), (4, Some(4), Some(0)), ], [ (1, Some(1), Some(0)), (8, Some(8), Some(0)), (4, Some(4), Some(0)), ], [ (1, Some(1), Some(0)), (5, Some(5), Some(0)), (8, Some(8), Some(0)), ], [ (1, Some(1), Some(0)), (3, Some(3), Some(0)), (5, Some(5), Some(0)), ], [ (3, Some(3), Some(0)), (9, Some(9), Some(0)), (5, Some(5), Some(0)), ], [ (3, Some(3), Some(0)), (6, Some(6), Some(0)), (9, Some(9), Some(0)), ], [ (3, Some(3), Some(0)), (2, Some(2), Some(0)), (6, Some(6), Some(0)), ], [ (2, Some(2), Some(0)), (10, Some(10), Some(0)), (6, Some(6), Some(0)), ], [ (2, Some(2), Some(0)), (7, Some(7), Some(0)), (10, Some(10), Some(0)), ], [ (2, Some(2), Some(0)), (0, Some(0), Some(0)), (7, Some(7), Some(0)), ], [ (0, Some(0), Some(0)), (11, Some(11), Some(0)), (7, Some(7), Some(0)), ], ]), ); let polygon1 = PolygonMesh::new( StandardAttributes { positions: vec![p[0], p[1], p[4], p[5]], uv_coords: vec![ Vector2::new(0.0, 0.0), Vector2::new(1.0, 0.0), Vector2::new(0.0, 1.0), Vector2::new(1.0, 1.0), ], normals: vec![Vector3::new(0.0, 1.0, 0.0)], }, Faces::from_iter([[ (1, Some(3), Some(0)), (3, Some(1), Some(0)), (2, Some(0), Some(0)), (0, Some(2), Some(0)), ]]), ); vec![ Face::new( vec![ vec![e[0].clone(), e[1].clone(), e[2].clone(), e[3].clone()].into(), vec![ e[10].inverse(), e[9].inverse(), e[8].inverse(), e[7].inverse(), ] .into(), ], polygon0, ), Face::new( vec![vec![e[0].clone(), e[6].inverse(), e[5].inverse(), e[4].inverse()].into()], polygon1, ) .inverse(), ] .into() } fn shell_unstructured_grid() -> DataSet { #[rustfmt::skip] let points: Vec = vec![ 0.0, 0.0, 0.0, 0.5, 0.25, 0.0, 0.25, 0.25, 0.0, 1.0, 0.0, 0.0, 0.75, 0.25, 0.0, 0.75, 0.5, 0.0, 1.0, 1.0, 0.0, 0.75, 0.75, 0.0, 0.5, 0.75, 0.0, 0.0, 1.0, 0.0, 0.25, 0.75, 0.0, 0.25, 0.5, 0.0, ]; #[rustfmt::skip] let uvs: Vec = vec![ 0.0, 0.0, 0.5, 0.25, 0.25, 0.25, 1.0, 0.0, 0.75, 0.25, 0.75, 0.5, 1.0, 1.0, 0.75, 0.75, 0.5, 0.75, 0.0, 1.0, 0.25, 0.75, 0.25, 0.5, ]; #[rustfmt::skip] let normals: Vec = vec![ 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, ]; #[rustfmt::skip] let connectivity: Vec = vec![ 0, 1, 2, 0, 3, 1, 3, 4, 1, 3, 5, 4, 3, 6, 5, 6, 7, 5, 6, 8, 7, 6, 9, 8, 9, 10, 8, 9, 11, 10, 9, 0, 11, 0, 2, 11, 0, 3, 3, 6, 6, 9, 9, 0, 1, 2, 11, 11, 10, 8, 8, 7, 5, 5, 4, 1, 0, 3, 6, 9, 1, 11, 8, 5, ]; let offsets: Vec = vec![ 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 38, 40, 42, 44, 47, 50, 53, 56, 57, 58, 59, 60, 61, 62, 63, 64, ]; let types = vec![ CellType::Polygon, CellType::Polygon, CellType::Polygon, CellType::Polygon, CellType::Polygon, CellType::Polygon, CellType::Polygon, CellType::Polygon, CellType::Polygon, CellType::Polygon, CellType::Polygon, CellType::Polygon, CellType::PolyLine, CellType::PolyLine, CellType::PolyLine, CellType::PolyLine, CellType::PolyLine, CellType::PolyLine, CellType::PolyLine, CellType::PolyLine, CellType::Vertex, CellType::Vertex, CellType::Vertex, CellType::Vertex, CellType::Vertex, CellType::Vertex, CellType::Vertex, CellType::Vertex, ]; let piece0 = Piece::Inline(Box::new(UnstructuredGridPiece { points: IOBuffer::F64(points), cells: Cells { cell_verts: VertexNumbers::XML { connectivity, offsets, }, types, }, data: vtkio::model::Attributes { point: vec![ Attribute::DataArray(DataArray { name: "TCoords".to_owned(), elem: ElementType::TCoords(2), data: IOBuffer::F64(uvs), }), Attribute::DataArray(DataArray { name: "Normals".to_owned(), elem: ElementType::Normals, data: IOBuffer::F64(normals), }), ], ..Default::default() }, })); #[rustfmt::skip] let points: Vec = vec![ 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, ]; #[rustfmt::skip] let uvs: Vec = vec![ 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, ]; #[rustfmt::skip] let normals: Vec = vec![ 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, ]; #[rustfmt::skip] let connectivity: Vec = vec![ 0, 1, 2, 3, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 2, 3, ]; let offsets: Vec = vec![4, 6, 8, 10, 12, 13, 14, 15, 16]; let types = vec![ CellType::Polygon, CellType::PolyLine, CellType::PolyLine, CellType::PolyLine, CellType::PolyLine, CellType::Vertex, CellType::Vertex, CellType::Vertex, CellType::Vertex, ]; let piece1 = Piece::Inline(Box::new(UnstructuredGridPiece { points: IOBuffer::F64(points), cells: Cells { cell_verts: VertexNumbers::XML { connectivity, offsets, }, types, }, data: vtkio::model::Attributes { point: vec![ Attribute::DataArray(DataArray { name: "TCoords".to_owned(), elem: ElementType::TCoords(2), data: IOBuffer::F64(uvs), }), Attribute::DataArray(DataArray { name: "Normals".to_owned(), elem: ElementType::Normals, data: IOBuffer::F64(normals), }), ], ..Default::default() }, })); DataSet::UnstructuredGrid { meta: None, pieces: vec![piece0, piece1], } } #[test] fn face() { let data = shell_topology()[0].to_data_set(); let DataSet::UnstructuredGrid { pieces, .. } = shell_unstructured_grid() else { unreachable!() }; let ans_data = DataSet::UnstructuredGrid { meta: None, pieces: vec![pieces[0].clone()], }; assert_eq!(data, ans_data); } #[test] fn shell() { assert_eq!(shell_topology().to_data_set(), shell_unstructured_grid()); } #[test] fn cshell() { assert_eq!( shell_topology().compress().to_data_set(), shell_unstructured_grid() ); }