parry3d/transformation/to_outline/
round_convex_polyhedron_to_outline.rs

1use crate::math::Vector;
2use crate::shape::RoundConvexPolyhedron;
3use crate::transformation::utils;
4use alloc::{vec, vec::Vec};
5
6impl RoundConvexPolyhedron {
7    /// Outlines this round convex polyhedron’s shape using polylines.
8    pub fn to_outline(&self, nsubdivs: u32) -> (Vec<Vector>, Vec<[u32; 2]>) {
9        let mut out_vtx = vec![];
10        let mut out_idx = vec![];
11        let poly = &self.inner_shape;
12
13        // 1. Compute the offset vertices.
14        for (vid, ref_vtx) in poly.vertices().iter().enumerate() {
15            let ref_pt = poly.points()[vid];
16            let range = ref_vtx.first_adj_face_or_edge as usize
17                ..(ref_vtx.first_adj_face_or_edge + ref_vtx.num_adj_faces_or_edge) as usize;
18            let adj_faces = &poly.faces_adj_to_vertex()[range];
19
20            for fid in adj_faces {
21                let face = poly.faces()[*fid as usize];
22                out_vtx.push(ref_pt + face.normal * self.border_radius);
23            }
24        }
25
26        // 2. Compute the straight edges.
27        // TODO: right now, each vertex of the final polyline will be duplicated
28        //       here, to simplify the index buffer generation for the straight edges.
29        for face in poly.faces() {
30            let i1 = face.first_vertex_or_edge;
31            let i2 = i1 + face.num_vertices_or_edges;
32            let base = out_vtx.len() as u32;
33
34            for idx in &poly.vertices_adj_to_face()[i1 as usize..i2 as usize] {
35                out_vtx.push(poly.points()[*idx as usize] + face.normal * self.border_radius);
36            }
37
38            for i in 0..face.num_vertices_or_edges - 1 {
39                out_idx.push([base + i, base + i + 1]);
40            }
41
42            out_idx.push([base, base + face.num_vertices_or_edges - 1]);
43        }
44
45        // 3. Compute the arcs.
46        let mut arc_base = 0;
47        for (vid, ref_vtx) in poly.vertices().iter().enumerate() {
48            let ref_pt = poly.points()[vid];
49            let n = ref_vtx.num_adj_faces_or_edge;
50
51            if n > 0 {
52                for k1 in 0..n {
53                    for k2 in k1 + 1..n {
54                        utils::push_arc_and_idx(
55                            ref_pt,
56                            arc_base + k1,
57                            arc_base + k2,
58                            nsubdivs,
59                            &mut out_vtx,
60                            &mut out_idx,
61                        );
62                    }
63                }
64
65                arc_base += n;
66            }
67        }
68
69        (out_vtx, out_idx)
70    }
71}