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
use crate::mesh::geometry::{Geometry, GeometryAttributes, GeometryPrimitives};
use std::fmt::{Error, Write};
use tabled::{builder::Builder, settings::Style, Table};

pub fn debug(geometry: &Geometry) -> Result<String, Error> {
    let mut result = String::default();
    if !geometry.attributes.is_empty() {
        writeln!(&mut result, "* Geometry attributes:")?;
        writeln!(&mut result, "{}", debug_attributes(&geometry.attributes))?;
    }
    if !geometry.vertices.attributes.is_empty() {
        writeln!(&mut result, "* Geometry vertices attributes:")?;
        writeln!(
            &mut result,
            "{}",
            debug_attributes(&geometry.vertices.attributes)
        )?;
    }
    writeln!(&mut result, "* Geometry vertices:")?;
    let mut builder = Builder::default();
    builder.push_record(
        std::iter::once("#".to_owned()).chain(
            geometry
                .vertices
                .columns_types()
                .map(|(name, value_type)| format!("{}\n({:?})", name, value_type)),
        ),
    );
    for (index, attributes) in geometry.vertices.iter().enumerate() {
        builder.push_record(
            std::iter::once(index.to_string()).chain(
                geometry
                    .vertices
                    .columns_types()
                    .map(|(name, _)| attributes.get(name).unwrap().to_string()),
            ),
        );
    }
    let mut table = builder.build();
    table.with(Style::modern());
    writeln!(&mut result, "{}", table)?;
    match &geometry.primitives {
        GeometryPrimitives::Triangles(triangles) => {
            if !triangles.attributes.is_empty() {
                writeln!(&mut result, "* Geometry triangles attributes:")?;
                writeln!(&mut result, "{}", debug_attributes(&triangles.attributes))?;
            }
            writeln!(&mut result, "* Geometry triangles:")?;
            let mut builder = Builder::default();
            builder.push_record(["Index A", "Index B", "Index C", "Attributes"]);
            for point in &triangles.items {
                builder.push_record([
                    point.indices[0].to_string(),
                    point.indices[1].to_string(),
                    point.indices[2].to_string(),
                    format!("{}", debug_attributes(&point.attributes)),
                ]);
            }
            let mut table = builder.build();
            table.with(Style::modern());
            writeln!(&mut result, "{}", table)?;
        }
        GeometryPrimitives::Lines(lines) => {
            if !lines.attributes.is_empty() {
                writeln!(&mut result, "* Geometry lines attributes:")?;
                writeln!(&mut result, "{}", debug_attributes(&lines.attributes))?;
            }
            writeln!(&mut result, "* Geometry lines:")?;
            let mut builder = Builder::default();
            builder.push_record(["Index A", "Index B", "Attributes"]);
            for point in &lines.items {
                builder.push_record([
                    point.indices[0].to_string(),
                    point.indices[1].to_string(),
                    format!("{}", debug_attributes(&point.attributes)),
                ]);
            }
            let mut table = builder.build();
            table.with(Style::modern());
            writeln!(&mut result, "{}", table)?;
        }
        GeometryPrimitives::Points(points) => {
            if !points.attributes.is_empty() {
                writeln!(&mut result, "* Geometry points attributes:")?;
                writeln!(&mut result, "{}", debug_attributes(&points.attributes))?;
            }
            writeln!(&mut result, "* Geometry points:")?;
            let mut builder = Builder::default();
            builder.push_record(["Index", "Attributes"]);
            for point in &points.items {
                builder.push_record([
                    point.index.to_string(),
                    format!("{}", debug_attributes(&point.attributes)),
                ]);
            }
            let mut table = builder.build();
            table.with(Style::modern());
            writeln!(&mut result, "{}", table)?;
        }
    }
    Ok(result)
}

fn debug_attributes(attributes: &GeometryAttributes) -> Table {
    let mut builder = Builder::default();
    for (name, value) in attributes.iter() {
        builder.push_record([name.to_string(), format!("{:?}", value)]);
    }
    let mut table = builder.build();
    table.with(Style::modern());
    table
}