1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use prelude::*;
#[derive (Default, Debug, PartialEq, PartialOrd, Ord, Eq, Clone, Hash)]
pub struct Mesh3D<P> where
P: Is3D {
pc: PointCloud3D<P>,
topology: Vec<VId>
}
impl<P> IsMesh<P, Face3> for Mesh3D<P> where
P: IsBuildable3D + Clone {
fn num_faces(&self) -> usize {
self.topology.len() / 3
}
fn num_vertices(&self) -> usize {
self.pc.len()
}
fn face_vertex_ids(&self, faceid: FId) -> Result<Face3> {
let id1 = 3*faceid.val + 0;
let id2 = 3*faceid.val + 1;
let id3 = 3*faceid.val + 2;
if id3 >= self.topology.len() {
return Err(ErrorKind::IncorrectFaceID);
}
Ok(Face3::new(self.topology[id1], self.topology[id2], self.topology[id3]))
}
fn face_vertices(&self, faceid: FId) -> Result<(P, P, P)> {
let face = self.face_vertex_ids(faceid)?;
if let (Ok(v1), Ok(v2), Ok(v3)) = (self.vertex(face.a), self.vertex(face.b), self.vertex(face.c)) {
return Ok((v1, v2, v3));
}
Err(ErrorKind::IncorrectVertexID)
}
fn vertex(&self, vertexid: VId) -> Result<P> {
if vertexid.val >= self.pc.len() {
return Err(ErrorKind::IncorrectVertexID);
}
Ok(self.pc.data[vertexid.val].clone())
}
}
impl<P> IsEditableMesh<P, Face3> for Mesh3D<P> where
P: IsEditable3D + IsBuildable3D + Clone {
fn add_vertex(&mut self, vertex: P) -> VId {
self.pc.push(vertex);
VId{val: self.pc.len() - 1}
}
fn change_vertex(&mut self, vid: VId, vertex: P) -> Result<()> {
if vid.val < self.pc.len() {
self.pc[vid.val] = vertex;
Ok(())
} else {
Err(ErrorKind::IncorrectVertexID)
}
}
fn add_face(&mut self, v1: P, v2: P, v3: P) -> FId {
let vid1 = self.add_vertex(v1);
let vid2 = self.add_vertex(v2);
let vid3 = self.add_vertex(v3);
self.topology.push(vid1);
self.topology.push(vid2);
self.topology.push(vid3);
FId{val: self.topology.len() / 3 - 1}
}
fn try_add_connection(&mut self, vid1: VId, vid2: VId, vid3: VId) -> Result<FId> {
if vid1.val >= self.pc.len() || vid2.val >= self.pc.len() || vid3.val >= self.pc.len() || vid1 == vid2 || vid1 == vid3 || vid2 == vid3 {
return Err(ErrorKind::IncorrectVertexID);
}
self.topology.push(vid1);
self.topology.push(vid2);
self.topology.push(vid3);
Ok(FId{val: self.topology.len() / 3 - 1})
}
}
impl<P> HasBoundingBox3D for Mesh3D<P> where
P: Is3D {
fn bounding_box(&self) -> Result<BoundingBox3D> {
self.pc.bounding_box()
}
}
impl<P> HasCenterOfGravity3D for Mesh3D<P> where
P: Is3D {
fn center_of_gravity(&self) -> Result<Point3D> {
self.pc.center_of_gravity()
}
}