ph_faces/
polyhedron.rs

1//! Polyhedron PHF TUV on polyhedron faces for Rust
2//!
3
4pub mod tetra;
5pub mod cube; // drawstuff(box) dxlib(cube)
6pub mod octa;
7pub mod sphere; // drawstuff dxlib
8pub mod cylinder; // drawstuff
9pub mod capsule; // drawstuff dxlib
10pub mod cone; // dxlib
11pub mod torus;
12pub mod pipe;
13pub mod pin;
14pub mod revolution;
15
16use crate::{calc_cg_with_volume, translate};
17
18use num::Float;
19
20/// FTVI
21#[derive(Debug, Clone)]
22pub struct FTVI<F: Float> {
23  /// face index of enumerate tri
24  pub fi: usize,
25  /// triangleindex of enumerate f
26  pub ti: usize,
27  /// vertex index of enumerate t
28  pub vi: usize,
29  /// p
30  pub p: [F; 3],
31  /// uv
32  pub uv: [F; 2],
33  /// index of vtx
34  pub idx: usize
35}
36
37/// FTVI
38impl<F: Float> FTVI<F> {
39  /// puv
40  pub fn puv(&self) -> (&[F; 3], &[F; 2]) {
41    (&self.p, &self.uv)
42  }
43}
44
45/// PHF polyhedron face
46pub type PHF<F> = Vec<Vec<Vec<FTVI<F>>>>;
47
48/// trait TUV
49pub trait TUV<F: Float> {
50  /// get uv from each face (i: vertex id of npolygon)
51  fn get_uv_f(&self, n: usize, i: usize, k: usize, c: bool,
52    r: f64, s: f64, o: [f64; 2]) -> [F; 2] { // rot scale offset
53    if c && k == 0 { // center [0]
54      [<F>::from(o[0] + 0.5).unwrap(), <F>::from(o[1] + 0.5).unwrap()]
55    } else {
56      let (m, j) = match c {
57      true => (n, (i + k - 1) % n), // j: c(01) c(12) c(23) c(34) c(40)
58      false => (n + 2, if k == 0 { 0 } else { i + k }) // j: 0(12) 0(23) 0(34)
59      };
60      let t = 2.0 * std::f64::consts::PI * j as f64 / m as f64 + r;
61      let uv = [(1.0 + s * t.cos()) / 2.0, 1.0 - (1.0 + s * t.sin()) / 2.0];
62      [<F>::from(o[0] + uv[0]).unwrap(), <F>::from(o[1] + uv[1]).unwrap()]
63    }
64  }
65  /// get uv from the one texture (f v i: vertex id of expanded polyhedron)
66  fn get_uv_t(&self, fi: usize, ti: usize, vi: usize,
67    r: f64, s: f64, o: [f64; 2]) -> [F; 2]; // rot scale offset
68  /// ref vtx
69  fn ref_vtx(&self) -> &Vec<[F; 3]>;
70  /// ref tri
71  fn ref_tri(&self) -> &Vec<Vec<[u16; 3]>>;
72  /// ref uv
73  fn ref_uv(&self) -> &Vec<Vec<[[F; 2]; 3]>>;
74  /// ref vtx mut
75  fn ref_vtx_mut(&mut self) -> &mut Vec<[F; 3]>;
76  /// ref tri mut
77  fn ref_tri_mut(&mut self) -> &mut Vec<Vec<[u16; 3]>>;
78  /// ref uv mut
79  fn ref_uv_mut(&mut self) -> &mut Vec<Vec<[[F; 2]; 3]>>;
80  /// centered
81  fn centered(&self) -> bool;
82  /// with_uv
83  fn with_uv(&self, tf: bool) -> PHF<F> { self.phf(tf, self.centered()) }
84  /// polyhedron faces by Vec N of Vec P(polygon) indexed triangles
85  fn phf(&self, tf: bool, c: bool) -> PHF<F> {
86    if tf && self.ref_uv().len() == 0 { // will be duplex checked in get_uv_t
87      println!("-- TODO: gen_uv with true expected uv but it is enpty --");
88    }
89    self.ref_tri().iter().enumerate().map(|(fi, f)|
90      f.iter().enumerate().map(|(ti, t)|
91        t.iter().enumerate().map(|(vi, &i)| {
92          self.gen_uv(i as usize, tf, fi, f.len(), ti, vi, c)
93        }).collect()
94      ).collect()
95    ).collect()
96  }
97  /// gen uv
98  fn gen_uv(&self, i: usize, tf: bool,
99    fi: usize, n: usize, ti: usize, vi: usize, c: bool) -> FTVI<F> {
100    let r = std::f64::consts::PI / 2.0; // rot
101    let s = 1.0f64; // scale
102    let o = [0.0f64, 0.0f64]; // offset
103    let p = self.ref_vtx()[i];
104    let uv = match tf {
105    true => self.get_uv_t(fi, ti, vi, 0.0f64, s, o), // on the one texture
106    false => self.get_uv_f(n, ti, vi, c, r, s, o) // texture each face
107    };
108    FTVI::<F>{fi, ti, vi, p, uv, idx: i}
109  }
110  /// calc cg with volume
111  fn calc_cg_with_volume(&self, p: F) -> (Vec<F>, F)
112    where F: std::fmt::Debug + std::iter::Sum {
113    calc_cg_with_volume(self.ref_tri(), self.ref_vtx(), p)
114  }
115  /// calc cg
116  fn calc_cg(&self, p: F) -> Vec<F>
117    where F: std::fmt::Debug + std::iter::Sum {
118//    calc_cg(self.ref_tri(), self.ref_vtx(), p) // OK
119    let (cg, _vol) = self.calc_cg_with_volume(p);
120    cg
121  }
122  /// adjust cg with volume
123  fn adjust_cg_with_volume(&mut self, p: F) -> (Vec<F>, F)
124    where F: std::fmt::Debug + std::iter::Sum {
125//  (can not borrow *self as mutable also borrowed as immutable)
126//    adjust_cg_with_volume(self.ref_tri(), self.ref_vtx_mut(), p) // borrow
127    let (cg, vol) = calc_cg_with_volume(self.ref_tri(), self.ref_vtx(), p);
128    translate(self.ref_vtx_mut(), &[-cg[0], -cg[1], -cg[2]]);
129    (cg, vol)
130  }
131  /// adjust cg
132  fn adjust_cg(&mut self, p: F) -> Vec<F>
133    where F: std::fmt::Debug + std::iter::Sum {
134//  (can not borrow *self as mutable also borrowed as immutable)
135//    adjust_cg(self.ref_tri(), self.ref_vtx_mut(), p) // borrow
136    let (cg, _vol) = self.adjust_cg_with_volume(p);
137    cg
138  }
139  /// translate
140  fn translate(&mut self, o: &[F]) where F: std::fmt::Debug {
141    translate(self.ref_vtx_mut(), o)
142  }
143}
144
145/// Polyhedron
146#[derive(Debug)]
147pub struct Polyhedron<F: Float> {
148  /// vtx
149  pub vtx: Vec<[F; 3]>,
150  /// tri: [n][m] Vec n faces of Vec m indexed triangles
151  pub tri: Vec<Vec<[u16; 3]>>,
152  /// uv: [n][m] Vec n faces of Vec m uv triangles
153  pub uv: Vec<Vec<[[F; 2]; 3]>>,
154  /// volume
155  pub vol: F,
156  /// center
157  pub center: bool
158}
159
160/// impl trait TUV for Polyhedron
161impl<F: Float> TUV<F> for Polyhedron<F> {
162  /// get uv from the one texture (fi ti vi: id of expanded polyhedron)
163  fn get_uv_t(&self, fi: usize, ti: usize, vi: usize,
164    _r: f64, _s: f64, o: [f64; 2]) -> [F; 2] { // TODO: rot scale offset
165    if self.uv.len() == 0 {
166      return [<F>::from(o[0]).unwrap(), <F>::from(o[1]).unwrap()];
167    }
168    let uv = self.uv[fi][ti][vi];
169    [<F>::from(o[0]).unwrap() + uv[0], <F>::from(o[1]).unwrap() + uv[1]]
170  }
171  /// ref vtx
172  fn ref_vtx(&self) -> &Vec<[F; 3]> { &self.vtx }
173  /// ref tri
174  fn ref_tri(&self) -> &Vec<Vec<[u16; 3]>> { &self.tri }
175  /// ref uv
176  fn ref_uv(&self) -> &Vec<Vec<[[F; 2]; 3]>> { &self.uv }
177  /// ref vtx mut
178  fn ref_vtx_mut(&mut self) -> &mut Vec<[F; 3]> { &mut self.vtx }
179  /// ref tri mut
180  fn ref_tri_mut(&mut self) -> &mut Vec<Vec<[u16; 3]>> { &mut self.tri }
181  /// ref uv mut
182  fn ref_uv_mut(&mut self) -> &mut Vec<Vec<[[F; 2]; 3]>> { &mut self.uv }
183  /// centered
184  fn centered(&self) -> bool { self.center }
185}