Skip to content

Commit d9a5be3

Browse files
committed
Some inititial infrastructure for custom mesh data.
1 parent a6ab33f commit d9a5be3

File tree

8 files changed

+167
-54
lines changed

8 files changed

+167
-54
lines changed

src/custom_data.rs

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use crate::IndexType;
2+
use crate::tmf::SectionType;
3+
#[derive(Clone)]
4+
pub struct CustomDataSegment {
5+
name: [u8; u8::MAX as usize],
6+
name_len: u8,
7+
data: CustomData,
8+
}
9+
#[derive(Debug, Copy, Clone)]
10+
pub enum DataSegmentError {
11+
NoName,
12+
NameTooLong,
13+
}
14+
impl CustomDataSegment {
15+
pub fn new(data: CustomData, name: &str) -> Result<Self, DataSegmentError> {
16+
let bytes = name.as_bytes();
17+
let len = name.len();
18+
if len > u8::MAX as usize {
19+
return Err(DataSegmentError::NameTooLong);
20+
} else if len == 0 {
21+
return Err(DataSegmentError::NoName);
22+
}
23+
let name_len = len as u8;
24+
let mut name = [0; u8::MAX as usize];
25+
for index in 0..bytes.len() {
26+
name[index] = bytes[index];
27+
}
28+
Ok(Self {
29+
name,
30+
name_len,
31+
data,
32+
})
33+
}
34+
}
35+
#[derive(Clone)]
36+
pub enum CustomData {
37+
CustomIndex(Box<[IndexType]>),
38+
}
39+
impl CustomData{
40+
fn section_type(&self)->SectionType{
41+
match self{
42+
Self::CustomIndex(_)=>SectionType::CustomIndexSegment,
43+
}
44+
}
45+
}
46+
impl From<&[IndexType]> for CustomData {
47+
fn from(indices: &[IndexType]) -> Self {
48+
Self::CustomIndex(indices.into())
49+
}
50+
}
51+
impl CustomDataSegment{
52+
pub(crate) fn write<W:std::io::Write>(&self,target:&mut W)->std::io::Result<()>{
53+
target.write(&(self.data.section_type() as u16).to_le_bytes())?;
54+
todo!();
55+
}
56+
fn read<R:std::io::Read>(src:&mut R)->Self{
57+
todo!();
58+
}
59+
}
60+
#[cfg(test)]
61+
fn init_test_env() {
62+
std::fs::create_dir_all("target/test_res").unwrap();
63+
}
64+
#[test]
65+
#[cfg(all(feature = "obj_import",test))]
66+
fn index_data() {
67+
use crate::{TMFMesh,TMFPrecisionInfo};
68+
init_test_env();
69+
let mut file = std::fs::File::open("testing/susan.obj").unwrap();
70+
let (mut tmf_mesh, name) = TMFMesh::read_from_obj_one(&mut file).unwrap();
71+
let index_data:[IndexType;10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
72+
let index_data_seg = CustomDataSegment::new(CustomData::from(&index_data[..]), "custom_index").unwrap();
73+
tmf_mesh.add_custom_data(index_data_seg);
74+
tmf_mesh.verify().unwrap();
75+
assert!(name == "Suzanne", "Name should be Suzanne but is {name}");
76+
let prec = TMFPrecisionInfo::default();
77+
let mut out = Vec::new();
78+
{
79+
tmf_mesh.write_tmf_one(&mut out, &prec, name).unwrap();
80+
}
81+
let (r_mesh, name) = TMFMesh::read_tmf_one(&mut (&out as &[u8])).unwrap();
82+
assert!(name == "Suzanne", "Name should be Suzanne but is {name}");
83+
r_mesh.verify().unwrap();
84+
}

src/lib.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//! This means that while saving a model may take a slightly longer time (2-4x loading), models can be loaded at considerable speed(loading a model with around 40 000 points takes 1.6 ms)
88
//! ## Feature flags
99
#![doc = document_features::document_features!()]
10+
mod custom_data;
1011
mod material;
1112
#[cfg(feature = "model_importer")]
1213
mod model_importer;
@@ -16,10 +17,10 @@ mod obj;
1617
/// Module used when saving vertex grups
1718
mod pile_map;
1819
mod tmf;
20+
mod tmf_segment;
1921
/// Module used to handle reads of data which is not bit aligned(for example, 3 or 17 bits). This is the module that allows for heavy compression used in this format.
2022
#[doc(hidden)]
2123
pub mod unaligned_rw;
22-
mod tmf_segment;
2324
mod utilis;
2425
mod uv;
2526
mod verify;
@@ -48,6 +49,8 @@ pub type FloatType = f64;
4849
pub type Vector3 = (FloatType, FloatType, FloatType);
4950
/// Type used for representing 2d floating-point vectors
5051
pub type Vector2 = (FloatType, FloatType);
52+
use crate::custom_data::CustomData;
53+
use crate::custom_data::CustomDataSegment;
5154
#[doc(inline)]
5255
use crate::material::MaterialInfo;
5356
#[doc(inline)]
@@ -92,6 +95,7 @@ pub struct TMFMesh {
9295
uvs: Option<Box<[Vector2]>>,
9396
uv_triangles: Option<Box<[IndexType]>>,
9497
materials: Option<MaterialInfo>,
98+
custom_data: Vec<CustomDataSegment>,
9599
}
96100
impl Default for TMFMesh {
97101
/// Creates default, empty [`TMFMesh`]. Equivalent to [`TMFMesh::empty`] call.
@@ -575,6 +579,7 @@ impl TMFMesh {
575579
vertex_triangles: None,
576580
vertices: None,
577581
materials: None,
582+
custom_data: Vec::new(),
578583
}
579584
}
580585
/// Reads all meshes from a .tmf file.
@@ -627,6 +632,9 @@ impl TMFMesh {
627632
Ok(vec_first(meshes))
628633
}
629634
}
635+
pub fn add_custom_data(&mut self, custom_data: CustomDataSegment) {
636+
self.custom_data.push(custom_data);
637+
}
630638
}
631639
#[cfg(test)]
632640
mod testing {

src/lz77.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ fn bwise_memcpy(
224224
todo!("Coping not implemented yet, but target is:{target:?}!");
225225
}
226226
//Not finished yet!
227-
#[test]#[ignore]
227+
#[test]
228+
#[ignore]
228229
fn test_bwise_cpy() {
229230
let a: [CompressionType; 2] = [
230231
0b0000000111110110111110110100001111100001100011101011001000000010,

src/normals.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use crate::unaligned_rw::{UnalignedRWMode, UnalignedReader, UnalignedWriter};
22
use crate::{FloatType, IndexType, Vector3};
3-
use std::io::{Read, Result, Write};
4-
#[cfg(feature = "double_precision")]
5-
use std::f64::consts::FRAC_PI_2;
63
#[cfg(not(feature = "double_precision"))]
74
use std::f32::consts::FRAC_PI_2;
5+
#[cfg(feature = "double_precision")]
6+
use std::f64::consts::FRAC_PI_2;
7+
use std::io::{Read, Result, Write};
88
#[derive(Clone, Copy, PartialEq)]
99
/// Setting dictating how much can any normal in a model deviate, expressed as an angle.
1010
pub struct NormalPrecisionMode(u8);
@@ -279,7 +279,7 @@ mod test_normal {
279279
fn map_size(prec: &NormalPrecisionMode) -> u128 {
280280
let asine_bits = prec.bits();
281281
let z_bits = prec.bits();
282-
let sign_bits = 3;//3 signs 1 bit each
282+
let sign_bits = 3; //3 signs 1 bit each
283283
let toatal_bits = asine_bits + z_bits + sign_bits;
284284
1 << toatal_bits
285285
}
@@ -317,7 +317,8 @@ pub(crate) fn map_prune(
317317
}
318318
}
319319
for index in normal_faces {
320-
*index = map[normal_to_map_index(normals[*index as usize], &prec.normal_precision) as usize];
320+
*index =
321+
map[normal_to_map_index(normals[*index as usize], &prec.normal_precision) as usize];
321322
//assert!(((*index) as usize) < new_normals.len());
322323
}
323324
*normals = new_normals;

src/obj.rs

+18-15
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ pub fn read_from_obj<R: Read>(reader: &mut R) -> Result<Vec<(TMFMesh, String)>>
3232
let lines = reader.lines();
3333
let mut res = Vec::new();
3434
for line in lines {
35-
if let Some(mesh_and_name) = parse_line(line, &mut oi)? { res.push(mesh_and_name) };
35+
if let Some(mesh_and_name) = parse_line(line, &mut oi)? {
36+
res.push(mesh_and_name)
37+
};
3638
}
3739
res.push(oi.finish());
3840
Ok(res)
@@ -153,22 +155,21 @@ fn save_obj<W: Write>(
153155
};
154156
// Ensure normal triangle array, if present, has the right length.
155157
if let Some(normal_triangles) = mesh.get_normal_triangles() {
156-
if normal_triangles.len() != vert_triangle_len {
157-
return Err(Error::new(
158-
ErrorKind::Other,
159-
"Number of triangles in the vertex triangle and normal triangle array differs.",
160-
));
161-
}
158+
if normal_triangles.len() != vert_triangle_len {
159+
return Err(Error::new(
160+
ErrorKind::Other,
161+
"Number of triangles in the vertex triangle and normal triangle array differs.",
162+
));
163+
}
162164
}
163165
// Ensure uv triangle array, if present, has the right length.
164166
if let Some(uv_triangles) = mesh.get_uv_triangles() {
165-
166-
if uv_triangles.len() != vert_triangle_len {
167-
return Err(Error::new(
168-
ErrorKind::Other,
169-
"Number of triangles in the vertex triangle and uv triangle array differs.",
170-
));
171-
}
167+
if uv_triangles.len() != vert_triangle_len {
168+
return Err(Error::new(
169+
ErrorKind::Other,
170+
"Number of triangles in the vertex triangle and uv triangle array differs.",
171+
));
172+
}
172173
}
173174
// TODO: this part can be rewritten to be more efficient by checking if arrays are present beforehand.
174175
for i in 0..vert_triangle_len {
@@ -187,7 +188,9 @@ fn save_obj<W: Write>(
187188
}
188189
}
189190
}
190-
if let Some(normals) = normals { write!(w, "/{}", normals[i] + index_offset.2)? };
191+
if let Some(normals) = normals {
192+
write!(w, "/{}", normals[i] + index_offset.2)?
193+
};
191194
if i % 3 == 2 {
192195
writeln!(w)?
193196
} else {

src/pile_map.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ impl<T: PartialEq + 'static> PileMap<T> {
2626
}
2727
}
2828
impl<T: PartialEq> From<PileMap<T>> for Vec<T> {
29-
fn from(val: PileMap<T>) -> Self {
30-
val.pile
31-
29+
fn from(val: PileMap<T>) -> Self {
30+
val.pile
3231
}
3332
}

src/tmf.rs

+35-18
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,20 @@ pub(crate) enum SectionType {
88
NormalTriangleSegment = 4,
99
UvSegment = 5,
1010
UvTriangleSegment = 6,
11-
// MaterialInfo = 7,
12-
// Materialtriangles = 8,
11+
ColorSegment = 7,
12+
ColorTriangleSegment = 8,
13+
TangentSegment = 9,
14+
TangentTriangleSegment = 10,
15+
MaterialInfo = 11,
16+
MaterialTriangleRanges = 12,
17+
GroupInfo = 13,
18+
GroupTriangleRanges = 14,
19+
CustomIndexSegment = 15,
20+
CustomFloatSegment = 16,
21+
CustomUnit2Segment = 17,
22+
CustomUnit3Segment = 18,
23+
CustomVector2Segment = 19,
24+
CustomVector3Segment = 20,
1325
}
1426
impl SectionType {
1527
pub fn from_u16(input: u16) -> Self {
@@ -77,7 +89,7 @@ fn calc_shortest_edge(
7789
) -> Result<FloatType> {
7890
let shortest_edge = match vertex_triangles {
7991
Some(vertex_triangles) => {
80-
if vertex_triangles.is_empty(){
92+
if vertex_triangles.is_empty() {
8193
//TODO: handle 0 faced mesh as mesh with no faces!
8294
return Ok(1.0);
8395
}
@@ -148,21 +160,21 @@ fn save_vertices<W: Write>(
148160
shortest_edge: FloatType,
149161
) -> Result<()> {
150162
if let Some(vertices) = vertices {
151-
use crate::vertices::save_tmf_vertices;
152-
save_tmf_vertices(
153-
vertices,
154-
p_info.vertex_precision,
155-
curr_segment_data,
156-
shortest_edge,
157-
)?;
158-
write_segment_header(
159-
w,
160-
SectionType::VertexSegment,
161-
curr_segment_data.len(),
162-
CompressionType::None,
163-
)?;
164-
w.write_all(curr_segment_data)?;
165-
curr_segment_data.clear();
163+
use crate::vertices::save_tmf_vertices;
164+
save_tmf_vertices(
165+
vertices,
166+
p_info.vertex_precision,
167+
curr_segment_data,
168+
shortest_edge,
169+
)?;
170+
write_segment_header(
171+
w,
172+
SectionType::VertexSegment,
173+
curr_segment_data.len(),
174+
CompressionType::None,
175+
)?;
176+
w.write_all(curr_segment_data)?;
177+
curr_segment_data.clear();
166178
}
167179
Ok(())
168180
}
@@ -338,6 +350,11 @@ pub(crate) fn write_mesh<W: Write>(
338350
}
339351
None => (),
340352
};
353+
for data in &mesh.custom_data{
354+
data.write(&mut curr_segment_data)?;
355+
w.write_all(&curr_segment_data)?;
356+
curr_segment_data.clear();
357+
}
341358
Ok(())
342359
}
343360
pub(crate) fn write_string<W: Write>(w: &mut W, s: &str) -> Result<()> {

src/tmf_segment.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{Vector3,TMFMesh};
1+
use crate::{TMFMesh, Vector3};
22
#[repr(u16)]
33
#[derive(Debug)]
44
pub(crate) enum SectionType {
@@ -42,21 +42,21 @@ impl CompressionType {
4242
}
4343
}
4444
}
45-
struct EncodedSegment{
46-
seg_type:SectionType,
47-
compresion_type:CompressionType,
48-
seg_data:Vec<u8>,
45+
struct EncodedSegment {
46+
seg_type: SectionType,
47+
compresion_type: CompressionType,
48+
seg_data: Vec<u8>,
4949
}
50-
enum DecodedSegement{
50+
enum DecodedSegement {
5151
VertexSegment(Vec<Vector3>),
5252
}
53-
impl DecodedSegement{
54-
fn encode(self)->EncodedSegment{
53+
impl DecodedSegement {
54+
fn encode(self) -> EncodedSegment {
5555
todo!("Not working yet!");
5656
}
57-
fn apply(self,mesh:&mut TMFMesh){
58-
match self{
59-
DecodedSegement::VertexSegment(vertices)=>{
57+
fn apply(self, mesh: &mut TMFMesh) {
58+
match self {
59+
DecodedSegement::VertexSegment(vertices) => {
6060
/*match mesh.get_vertices(){
6161
Some(vertices)=>
6262
}*/

0 commit comments

Comments
 (0)