parry3d/transformation/to_outline/
round_convex_polyhedron_to_outline.rs

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