differt-core 0.0.32__tar.gz → 0.0.34__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {differt_core-0.0.32 → differt_core-0.0.34}/Cargo.lock +6 -5
- {differt_core-0.0.32 → differt_core-0.0.34}/PKG-INFO +1 -1
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/Cargo.toml +3 -3
- {differt_core-0.0.32 → differt_core-0.0.34/differt-core}/python/differt_core/_differt_core/scene/sionna.pyi +3 -1
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/src/geometry/triangle_mesh.rs +12 -7
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/src/scene/sionna.rs +153 -42
- {differt_core-0.0.32 → differt_core-0.0.34/differt-core}/src/scene/triangle_scene.rs +6 -2
- {differt_core-0.0.32/differt-core → differt_core-0.0.34}/python/differt_core/_differt_core/scene/sionna.pyi +3 -1
- {differt_core-0.0.32 → differt_core-0.0.34}/src/geometry/triangle_mesh.rs +12 -7
- {differt_core-0.0.32 → differt_core-0.0.34}/src/scene/sionna.rs +153 -42
- {differt_core-0.0.32/differt-core → differt_core-0.0.34}/src/scene/triangle_scene.rs +6 -2
- {differt_core-0.0.32 → differt_core-0.0.34}/Cargo.toml +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/LICENSE.md +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/README.md +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/LICENSE.md +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/README.md +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/benches/bench_main.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/benches/benchmarks/graph_iterators.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/benches/benchmarks/mod.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/__init__.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/_differt_core/__init__.pyi +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/_differt_core/geometry/triangle_mesh.pyi +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/_differt_core/rt/__init__.pyi +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/_differt_core/rt/graph.pyi +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/_differt_core/scene/triangle_scene.pyi +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/geometry/__init__.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/geometry/_triangle_mesh.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/py.typed +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/rt/__init__.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/rt/_graph.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/scene/__init__.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/scene/_sionna.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/scene/_triangle_scene.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/src/geometry/mod.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/src/lib.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/src/rt/graph.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/src/rt/mod.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/src/scene/mod.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/tests/__init__.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/tests/rt/__init__.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/differt-core/tests/rt/test_graph.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/pyproject.toml +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/__init__.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/_differt_core/__init__.pyi +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/_differt_core/geometry/triangle_mesh.pyi +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/_differt_core/rt/__init__.pyi +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/_differt_core/rt/graph.pyi +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/_differt_core/scene/triangle_scene.pyi +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/geometry/__init__.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/geometry/_triangle_mesh.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/py.typed +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/rt/__init__.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/rt/_graph.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/scene/__init__.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/scene/_sionna.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/scene/_triangle_scene.py +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/src/geometry/mod.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/src/lib.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/src/rt/graph.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/src/rt/mod.rs +0 -0
- {differt_core-0.0.32 → differt_core-0.0.34}/src/scene/mod.rs +0 -0
|
@@ -247,7 +247,7 @@ checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
|
|
|
247
247
|
|
|
248
248
|
[[package]]
|
|
249
249
|
name = "differt-core"
|
|
250
|
-
version = "0.0.
|
|
250
|
+
version = "0.0.34"
|
|
251
251
|
dependencies = [
|
|
252
252
|
"criterion",
|
|
253
253
|
"indexmap",
|
|
@@ -825,8 +825,9 @@ dependencies = [
|
|
|
825
825
|
|
|
826
826
|
[[package]]
|
|
827
827
|
name = "pyo3-log"
|
|
828
|
-
version = "0.
|
|
829
|
-
source = "
|
|
828
|
+
version = "0.12.2"
|
|
829
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
830
|
+
checksum = "4b78e4983ba15bc62833a0e0941d965bc03690163f1127864f1408db25063466"
|
|
830
831
|
dependencies = [
|
|
831
832
|
"arc-swap",
|
|
832
833
|
"log",
|
|
@@ -869,9 +870,9 @@ dependencies = [
|
|
|
869
870
|
|
|
870
871
|
[[package]]
|
|
871
872
|
name = "quick-xml"
|
|
872
|
-
version = "0.
|
|
873
|
+
version = "0.37.2"
|
|
873
874
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
874
|
-
checksum = "
|
|
875
|
+
checksum = "165859e9e55f79d67b96c5d96f4e88b6f2695a1972849c15a6a3f5c59fc2c003"
|
|
875
876
|
dependencies = [
|
|
876
877
|
"memchr",
|
|
877
878
|
"serde",
|
|
@@ -11,8 +11,8 @@ numpy = "0.24"
|
|
|
11
11
|
obj-rs = "0.7.1"
|
|
12
12
|
ply-rs = "0.1.3"
|
|
13
13
|
pyo3 = {version = "0.24", features = ["abi3-py310", "indexmap", "generate-import-lib"]}
|
|
14
|
-
pyo3-log =
|
|
15
|
-
quick-xml = {version = "0.
|
|
14
|
+
pyo3-log = "0.12.2"
|
|
15
|
+
quick-xml = {version = "0.37.2", features = ["serialize", "serde-types"]}
|
|
16
16
|
serde = {version = "1.0.197", features = ["derive"]}
|
|
17
17
|
|
|
18
18
|
[dev-dependencies]
|
|
@@ -37,4 +37,4 @@ unexpected_cfgs = {level = "warn", check-cfg = ['cfg(tarpaulin_include)']}
|
|
|
37
37
|
edition = "2021"
|
|
38
38
|
name = "differt-core"
|
|
39
39
|
rust-version = "1.78.0"
|
|
40
|
-
version = "0.0.
|
|
40
|
+
version = "0.0.34"
|
|
@@ -281,7 +281,10 @@ impl TriangleMesh {
|
|
|
281
281
|
pub(crate) fn load_obj(_: &Bound<'_, PyType>, filename: &str) -> PyResult<Self> {
|
|
282
282
|
let input = BufReader::new(File::open(filename)?);
|
|
283
283
|
let mut obj: RawObj = parse_obj(input).map_err(|err| {
|
|
284
|
-
PyValueError::new_err(format!(
|
|
284
|
+
PyValueError::new_err(format!(
|
|
285
|
+
"An error occurred while reading obj file {filename:#?}: {}",
|
|
286
|
+
err
|
|
287
|
+
))
|
|
285
288
|
})?;
|
|
286
289
|
|
|
287
290
|
for material_file in obj.material_libraries.iter_mut() {
|
|
@@ -317,7 +320,7 @@ impl TriangleMesh {
|
|
|
317
320
|
|
|
318
321
|
let header = vertex_parser.read_header(&mut input).map_err(|err| {
|
|
319
322
|
PyValueError::new_err(format!(
|
|
320
|
-
"An error occurred while reading the header of ply file: {}",
|
|
323
|
+
"An error occurred while reading the header of ply file {filename:#?}: {}",
|
|
321
324
|
err
|
|
322
325
|
))
|
|
323
326
|
})?;
|
|
@@ -334,7 +337,7 @@ impl TriangleMesh {
|
|
|
334
337
|
.map_err(|err| {
|
|
335
338
|
PyValueError::new_err(format!(
|
|
336
339
|
"An error occurred while reading the vertex elements of ply \
|
|
337
|
-
file: {}",
|
|
340
|
+
file {filename:#?}: {}",
|
|
338
341
|
err
|
|
339
342
|
))
|
|
340
343
|
})?
|
|
@@ -349,7 +352,7 @@ impl TriangleMesh {
|
|
|
349
352
|
.map_err(|err| {
|
|
350
353
|
PyValueError::new_err(format!(
|
|
351
354
|
"An error occurred while reading the face elements of PLY \
|
|
352
|
-
file: {}",
|
|
355
|
+
file {filename:#?}: {}",
|
|
353
356
|
err
|
|
354
357
|
))
|
|
355
358
|
})?
|
|
@@ -423,14 +426,16 @@ impl From<RawObj> for TriangleMesh {
|
|
|
423
426
|
},
|
|
424
427
|
Err(e) => {
|
|
425
428
|
log::warn!(
|
|
426
|
-
"An error occurred when parsing MTL file {material_file}:
|
|
429
|
+
"An error occurred when parsing MTL file {material_file:#?}: \
|
|
430
|
+
{e}."
|
|
427
431
|
);
|
|
428
432
|
},
|
|
429
433
|
}
|
|
430
434
|
},
|
|
431
435
|
Err(e) => {
|
|
432
436
|
log::warn!(
|
|
433
|
-
"An error occurred when trying to read MTL file {material_file}:
|
|
437
|
+
"An error occurred when trying to read MTL file {material_file:#?}: \
|
|
438
|
+
{e}."
|
|
434
439
|
);
|
|
435
440
|
},
|
|
436
441
|
}
|
|
@@ -460,7 +465,7 @@ impl From<RawObj> for TriangleMesh {
|
|
|
460
465
|
}
|
|
461
466
|
} else {
|
|
462
467
|
log::warn!(
|
|
463
|
-
"Material {material_name} was listed in OBJ material libraries, but is \
|
|
468
|
+
"Material {material_name:#?} was listed in OBJ material libraries, but is \
|
|
464
469
|
not present is mesh groups."
|
|
465
470
|
);
|
|
466
471
|
}
|
|
@@ -74,12 +74,47 @@ where
|
|
|
74
74
|
#[pyclass(get_all)]
|
|
75
75
|
#[derive(Clone, Debug, Default)]
|
|
76
76
|
pub(crate) struct Material {
|
|
77
|
-
/// str: The material
|
|
77
|
+
/// str: The material name.
|
|
78
78
|
///
|
|
79
79
|
/// This can be, e.g., an ITU identifier.
|
|
80
|
+
pub(crate) name: String,
|
|
81
|
+
/// str: The material ID.
|
|
82
|
+
///
|
|
83
|
+
/// This is used to match the material id used in shapes.
|
|
80
84
|
pub(crate) id: String,
|
|
81
|
-
/// tuple[float, float, float]: The material color, used
|
|
82
|
-
|
|
85
|
+
/// tuple[float, float, float]: The material color, used for plotting.
|
|
86
|
+
///
|
|
87
|
+
/// The color is obtained from a---possibly-nested---``<rgb>`` element,
|
|
88
|
+
/// or from a ``<string>`` element with a ``type`` attribute. In the latter
|
|
89
|
+
/// case, the color is chosen from a predefined list of colors.
|
|
90
|
+
pub(crate) color: [f32; 3],
|
|
91
|
+
/// typing.Optional[float]: The thickness of the material.
|
|
92
|
+
pub(crate) thickness: Option<f32>,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fn deserialize_rgb<'de, D>(deserializer: D) -> Result<[f32; 3], D::Error>
|
|
96
|
+
where
|
|
97
|
+
D: de::Deserializer<'de>,
|
|
98
|
+
{
|
|
99
|
+
let value = <String>::deserialize(deserializer)?;
|
|
100
|
+
|
|
101
|
+
match value
|
|
102
|
+
.split_ascii_whitespace()
|
|
103
|
+
.collect::<Vec<_>>()
|
|
104
|
+
.as_slice()
|
|
105
|
+
{
|
|
106
|
+
[r_str, g_str, b_str] => {
|
|
107
|
+
let r = r_str.parse().map_err(de::Error::custom)?;
|
|
108
|
+
let g = g_str.parse().map_err(de::Error::custom)?;
|
|
109
|
+
let b = b_str.parse().map_err(de::Error::custom)?;
|
|
110
|
+
Ok([r, g, b])
|
|
111
|
+
},
|
|
112
|
+
_ => {
|
|
113
|
+
Err(de::Error::custom(
|
|
114
|
+
"value of <rgb> element must contain three floats",
|
|
115
|
+
))
|
|
116
|
+
},
|
|
117
|
+
}
|
|
83
118
|
}
|
|
84
119
|
|
|
85
120
|
impl<'de> Deserialize<'de> for Material {
|
|
@@ -87,56 +122,129 @@ impl<'de> Deserialize<'de> for Material {
|
|
|
87
122
|
where
|
|
88
123
|
D: de::Deserializer<'de>,
|
|
89
124
|
{
|
|
90
|
-
#[derive(Deserialize)]
|
|
91
|
-
struct RawMaterial {
|
|
92
|
-
#[serde(rename(deserialize = "@id"))]
|
|
93
|
-
id: String,
|
|
94
|
-
#[serde(rename = "$value")]
|
|
95
|
-
rgb: PossiblyNestedRgb,
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
#[derive(Deserialize)]
|
|
125
|
+
#[derive(Debug, Deserialize)]
|
|
99
126
|
struct Rgb {
|
|
100
|
-
#[serde(rename(deserialize = "@value"))]
|
|
101
|
-
|
|
127
|
+
#[serde(rename(deserialize = "@value"), deserialize_with = "deserialize_rgb")]
|
|
128
|
+
color: [f32; 3],
|
|
102
129
|
}
|
|
103
130
|
|
|
104
|
-
#[derive(Deserialize)]
|
|
131
|
+
#[derive(Debug, Deserialize)]
|
|
105
132
|
#[serde(rename_all = "snake_case")]
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
133
|
+
struct Bsdf {
|
|
134
|
+
#[serde(rename = "rgb")]
|
|
135
|
+
rgb: Rgb,
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
#[derive(Debug)]
|
|
139
|
+
enum Type {
|
|
140
|
+
Struct { value: String },
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
quick_xml::impl_deserialize_for_internally_tagged_enum! {
|
|
144
|
+
Type, "@name",
|
|
145
|
+
("type" => Struct {
|
|
146
|
+
#[serde(rename = "@value")]
|
|
147
|
+
value: String }),
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
#[derive(Debug)]
|
|
151
|
+
enum Thickness {
|
|
152
|
+
Struct { value: f32 },
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
quick_xml::impl_deserialize_for_internally_tagged_enum! {
|
|
156
|
+
Thickness, "@name",
|
|
157
|
+
("thickness" => Struct {
|
|
158
|
+
#[serde(rename = "@value")]
|
|
159
|
+
value: f32,
|
|
160
|
+
}),
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
#[derive(Debug)]
|
|
164
|
+
enum RawMaterial {
|
|
165
|
+
TwoSided {
|
|
166
|
+
id: String,
|
|
167
|
+
bsdf: Bsdf,
|
|
168
|
+
//thickness: Option<f32>,
|
|
110
169
|
},
|
|
111
|
-
|
|
112
|
-
|
|
170
|
+
ItuRadioMaterial {
|
|
171
|
+
id: String,
|
|
172
|
+
r#type: Type,
|
|
173
|
+
thickness: Option<Thickness>,
|
|
113
174
|
},
|
|
114
175
|
}
|
|
115
176
|
|
|
177
|
+
quick_xml::impl_deserialize_for_internally_tagged_enum! {
|
|
178
|
+
RawMaterial, "@type",
|
|
179
|
+
("twosided" => TwoSided {
|
|
180
|
+
#[serde(rename = "@id")]
|
|
181
|
+
id: String,
|
|
182
|
+
bsdf: Bsdf,
|
|
183
|
+
}),
|
|
184
|
+
("itu-radio-material" => ItuRadioMaterial {
|
|
185
|
+
#[serde(rename = "@id")]
|
|
186
|
+
id: String,
|
|
187
|
+
#[serde(rename = "string")]
|
|
188
|
+
r#type: Type,
|
|
189
|
+
#[serde(skip)]
|
|
190
|
+
thickness: Option<Thickness>,
|
|
191
|
+
}),
|
|
192
|
+
}
|
|
193
|
+
|
|
116
194
|
let raw_mat = RawMaterial::deserialize(deserializer)?;
|
|
117
195
|
|
|
118
|
-
|
|
119
|
-
RawMaterial {
|
|
120
|
-
id,
|
|
121
|
-
rgb: PossiblyNestedRgb::Rgb { value },
|
|
122
|
-
} => (id, value),
|
|
123
|
-
RawMaterial {
|
|
196
|
+
match raw_mat {
|
|
197
|
+
RawMaterial::TwoSided {
|
|
124
198
|
id,
|
|
125
|
-
|
|
126
|
-
} =>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
let b = b_str.parse().map_err(de::Error::custom)?;
|
|
134
|
-
Ok(Material { id, rgb: [r, g, b] })
|
|
199
|
+
bsdf: Bsdf { rgb: Rgb { color } },
|
|
200
|
+
} => {
|
|
201
|
+
Ok(Material {
|
|
202
|
+
name: id.strip_prefix("mat-").unwrap_or(&id).to_string(),
|
|
203
|
+
id,
|
|
204
|
+
color,
|
|
205
|
+
thickness: None,
|
|
206
|
+
})
|
|
135
207
|
},
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
208
|
+
RawMaterial::ItuRadioMaterial {
|
|
209
|
+
id,
|
|
210
|
+
r#type: Type::Struct { value: r#type },
|
|
211
|
+
thickness,
|
|
212
|
+
} => {
|
|
213
|
+
let color = match r#type.as_str() {
|
|
214
|
+
// Copied from Sionna-RT's code, to match their colors:
|
|
215
|
+
// https://github.com/NVlabs/sionna-rt/blob/main/src/sionna/rt/radio_materials/itu_material.py
|
|
216
|
+
// v1.0.0
|
|
217
|
+
"marble" => [0.701, 0.644, 0.485],
|
|
218
|
+
"concrete" => [0.539, 0.539, 0.539],
|
|
219
|
+
"wood" => [0.266, 0.109, 0.060],
|
|
220
|
+
"metal" => [0.220, 0.220, 0.254],
|
|
221
|
+
"brick" => [0.402, 0.112, 0.087],
|
|
222
|
+
"glass" => [0.168, 0.139, 0.509],
|
|
223
|
+
"floorboard" => [0.539, 0.386, 0.025],
|
|
224
|
+
"ceiling_board" => [0.376, 0.539, 0.117],
|
|
225
|
+
"chipboard" => [0.509, 0.159, 0.323],
|
|
226
|
+
"plasterboard" => [0.051, 0.539, 0.133],
|
|
227
|
+
"plywood" => [0.136, 0.076, 0.539],
|
|
228
|
+
"very_dry_ground" => [0.539, 0.319, 0.223],
|
|
229
|
+
"medium_dry_ground" => [0.539, 0.181, 0.076],
|
|
230
|
+
"wet_ground" => [0.539, 0.027, 0.147],
|
|
231
|
+
_ => {
|
|
232
|
+
log::warn!(
|
|
233
|
+
"unknown material type: {type:#?}, using default color, i.e., black",
|
|
234
|
+
);
|
|
235
|
+
[0.0, 0.0, 0.0]
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
Ok(Material {
|
|
239
|
+
name: format!("itu_{type}"),
|
|
240
|
+
id,
|
|
241
|
+
color,
|
|
242
|
+
thickness: thickness.map(|t| {
|
|
243
|
+
match t {
|
|
244
|
+
Thickness::Struct { value: thickness } => thickness,
|
|
245
|
+
}
|
|
246
|
+
}),
|
|
247
|
+
})
|
|
140
248
|
},
|
|
141
249
|
}
|
|
142
250
|
}
|
|
@@ -218,7 +326,10 @@ impl SionnaScene {
|
|
|
218
326
|
pub(crate) fn load_xml(_: &Bound<'_, PyType>, file: &str) -> PyResult<Self> {
|
|
219
327
|
let input = BufReader::new(File::open(file)?);
|
|
220
328
|
quick_xml::de::from_reader(input).map_err(|err| {
|
|
221
|
-
PyValueError::new_err(format!(
|
|
329
|
+
PyValueError::new_err(format!(
|
|
330
|
+
"An error occurred while reading XML file {file:#?}: {}",
|
|
331
|
+
err
|
|
332
|
+
))
|
|
222
333
|
})
|
|
223
334
|
}
|
|
224
335
|
}
|
|
@@ -60,10 +60,14 @@ impl TriangleScene {
|
|
|
60
60
|
},
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
let
|
|
63
|
+
let material = sionna.materials.get(&shape.material_id);
|
|
64
|
+
|
|
65
|
+
let color = material.map(|mat| mat.color);
|
|
66
|
+
|
|
67
|
+
let material_name = material.map(|mat| mat.name.clone());
|
|
64
68
|
|
|
65
69
|
other_mesh.set_face_color(color.as_ref());
|
|
66
|
-
other_mesh.set_face_material(
|
|
70
|
+
other_mesh.set_face_material(material_name);
|
|
67
71
|
|
|
68
72
|
mesh.append(&mut other_mesh);
|
|
69
73
|
}
|
|
@@ -281,7 +281,10 @@ impl TriangleMesh {
|
|
|
281
281
|
pub(crate) fn load_obj(_: &Bound<'_, PyType>, filename: &str) -> PyResult<Self> {
|
|
282
282
|
let input = BufReader::new(File::open(filename)?);
|
|
283
283
|
let mut obj: RawObj = parse_obj(input).map_err(|err| {
|
|
284
|
-
PyValueError::new_err(format!(
|
|
284
|
+
PyValueError::new_err(format!(
|
|
285
|
+
"An error occurred while reading obj file {filename:#?}: {}",
|
|
286
|
+
err
|
|
287
|
+
))
|
|
285
288
|
})?;
|
|
286
289
|
|
|
287
290
|
for material_file in obj.material_libraries.iter_mut() {
|
|
@@ -317,7 +320,7 @@ impl TriangleMesh {
|
|
|
317
320
|
|
|
318
321
|
let header = vertex_parser.read_header(&mut input).map_err(|err| {
|
|
319
322
|
PyValueError::new_err(format!(
|
|
320
|
-
"An error occurred while reading the header of ply file: {}",
|
|
323
|
+
"An error occurred while reading the header of ply file {filename:#?}: {}",
|
|
321
324
|
err
|
|
322
325
|
))
|
|
323
326
|
})?;
|
|
@@ -334,7 +337,7 @@ impl TriangleMesh {
|
|
|
334
337
|
.map_err(|err| {
|
|
335
338
|
PyValueError::new_err(format!(
|
|
336
339
|
"An error occurred while reading the vertex elements of ply \
|
|
337
|
-
file: {}",
|
|
340
|
+
file {filename:#?}: {}",
|
|
338
341
|
err
|
|
339
342
|
))
|
|
340
343
|
})?
|
|
@@ -349,7 +352,7 @@ impl TriangleMesh {
|
|
|
349
352
|
.map_err(|err| {
|
|
350
353
|
PyValueError::new_err(format!(
|
|
351
354
|
"An error occurred while reading the face elements of PLY \
|
|
352
|
-
file: {}",
|
|
355
|
+
file {filename:#?}: {}",
|
|
353
356
|
err
|
|
354
357
|
))
|
|
355
358
|
})?
|
|
@@ -423,14 +426,16 @@ impl From<RawObj> for TriangleMesh {
|
|
|
423
426
|
},
|
|
424
427
|
Err(e) => {
|
|
425
428
|
log::warn!(
|
|
426
|
-
"An error occurred when parsing MTL file {material_file}:
|
|
429
|
+
"An error occurred when parsing MTL file {material_file:#?}: \
|
|
430
|
+
{e}."
|
|
427
431
|
);
|
|
428
432
|
},
|
|
429
433
|
}
|
|
430
434
|
},
|
|
431
435
|
Err(e) => {
|
|
432
436
|
log::warn!(
|
|
433
|
-
"An error occurred when trying to read MTL file {material_file}:
|
|
437
|
+
"An error occurred when trying to read MTL file {material_file:#?}: \
|
|
438
|
+
{e}."
|
|
434
439
|
);
|
|
435
440
|
},
|
|
436
441
|
}
|
|
@@ -460,7 +465,7 @@ impl From<RawObj> for TriangleMesh {
|
|
|
460
465
|
}
|
|
461
466
|
} else {
|
|
462
467
|
log::warn!(
|
|
463
|
-
"Material {material_name} was listed in OBJ material libraries, but is \
|
|
468
|
+
"Material {material_name:#?} was listed in OBJ material libraries, but is \
|
|
464
469
|
not present is mesh groups."
|
|
465
470
|
);
|
|
466
471
|
}
|
|
@@ -74,12 +74,47 @@ where
|
|
|
74
74
|
#[pyclass(get_all)]
|
|
75
75
|
#[derive(Clone, Debug, Default)]
|
|
76
76
|
pub(crate) struct Material {
|
|
77
|
-
/// str: The material
|
|
77
|
+
/// str: The material name.
|
|
78
78
|
///
|
|
79
79
|
/// This can be, e.g., an ITU identifier.
|
|
80
|
+
pub(crate) name: String,
|
|
81
|
+
/// str: The material ID.
|
|
82
|
+
///
|
|
83
|
+
/// This is used to match the material id used in shapes.
|
|
80
84
|
pub(crate) id: String,
|
|
81
|
-
/// tuple[float, float, float]: The material color, used
|
|
82
|
-
|
|
85
|
+
/// tuple[float, float, float]: The material color, used for plotting.
|
|
86
|
+
///
|
|
87
|
+
/// The color is obtained from a---possibly-nested---``<rgb>`` element,
|
|
88
|
+
/// or from a ``<string>`` element with a ``type`` attribute. In the latter
|
|
89
|
+
/// case, the color is chosen from a predefined list of colors.
|
|
90
|
+
pub(crate) color: [f32; 3],
|
|
91
|
+
/// typing.Optional[float]: The thickness of the material.
|
|
92
|
+
pub(crate) thickness: Option<f32>,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fn deserialize_rgb<'de, D>(deserializer: D) -> Result<[f32; 3], D::Error>
|
|
96
|
+
where
|
|
97
|
+
D: de::Deserializer<'de>,
|
|
98
|
+
{
|
|
99
|
+
let value = <String>::deserialize(deserializer)?;
|
|
100
|
+
|
|
101
|
+
match value
|
|
102
|
+
.split_ascii_whitespace()
|
|
103
|
+
.collect::<Vec<_>>()
|
|
104
|
+
.as_slice()
|
|
105
|
+
{
|
|
106
|
+
[r_str, g_str, b_str] => {
|
|
107
|
+
let r = r_str.parse().map_err(de::Error::custom)?;
|
|
108
|
+
let g = g_str.parse().map_err(de::Error::custom)?;
|
|
109
|
+
let b = b_str.parse().map_err(de::Error::custom)?;
|
|
110
|
+
Ok([r, g, b])
|
|
111
|
+
},
|
|
112
|
+
_ => {
|
|
113
|
+
Err(de::Error::custom(
|
|
114
|
+
"value of <rgb> element must contain three floats",
|
|
115
|
+
))
|
|
116
|
+
},
|
|
117
|
+
}
|
|
83
118
|
}
|
|
84
119
|
|
|
85
120
|
impl<'de> Deserialize<'de> for Material {
|
|
@@ -87,56 +122,129 @@ impl<'de> Deserialize<'de> for Material {
|
|
|
87
122
|
where
|
|
88
123
|
D: de::Deserializer<'de>,
|
|
89
124
|
{
|
|
90
|
-
#[derive(Deserialize)]
|
|
91
|
-
struct RawMaterial {
|
|
92
|
-
#[serde(rename(deserialize = "@id"))]
|
|
93
|
-
id: String,
|
|
94
|
-
#[serde(rename = "$value")]
|
|
95
|
-
rgb: PossiblyNestedRgb,
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
#[derive(Deserialize)]
|
|
125
|
+
#[derive(Debug, Deserialize)]
|
|
99
126
|
struct Rgb {
|
|
100
|
-
#[serde(rename(deserialize = "@value"))]
|
|
101
|
-
|
|
127
|
+
#[serde(rename(deserialize = "@value"), deserialize_with = "deserialize_rgb")]
|
|
128
|
+
color: [f32; 3],
|
|
102
129
|
}
|
|
103
130
|
|
|
104
|
-
#[derive(Deserialize)]
|
|
131
|
+
#[derive(Debug, Deserialize)]
|
|
105
132
|
#[serde(rename_all = "snake_case")]
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
133
|
+
struct Bsdf {
|
|
134
|
+
#[serde(rename = "rgb")]
|
|
135
|
+
rgb: Rgb,
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
#[derive(Debug)]
|
|
139
|
+
enum Type {
|
|
140
|
+
Struct { value: String },
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
quick_xml::impl_deserialize_for_internally_tagged_enum! {
|
|
144
|
+
Type, "@name",
|
|
145
|
+
("type" => Struct {
|
|
146
|
+
#[serde(rename = "@value")]
|
|
147
|
+
value: String }),
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
#[derive(Debug)]
|
|
151
|
+
enum Thickness {
|
|
152
|
+
Struct { value: f32 },
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
quick_xml::impl_deserialize_for_internally_tagged_enum! {
|
|
156
|
+
Thickness, "@name",
|
|
157
|
+
("thickness" => Struct {
|
|
158
|
+
#[serde(rename = "@value")]
|
|
159
|
+
value: f32,
|
|
160
|
+
}),
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
#[derive(Debug)]
|
|
164
|
+
enum RawMaterial {
|
|
165
|
+
TwoSided {
|
|
166
|
+
id: String,
|
|
167
|
+
bsdf: Bsdf,
|
|
168
|
+
//thickness: Option<f32>,
|
|
110
169
|
},
|
|
111
|
-
|
|
112
|
-
|
|
170
|
+
ItuRadioMaterial {
|
|
171
|
+
id: String,
|
|
172
|
+
r#type: Type,
|
|
173
|
+
thickness: Option<Thickness>,
|
|
113
174
|
},
|
|
114
175
|
}
|
|
115
176
|
|
|
177
|
+
quick_xml::impl_deserialize_for_internally_tagged_enum! {
|
|
178
|
+
RawMaterial, "@type",
|
|
179
|
+
("twosided" => TwoSided {
|
|
180
|
+
#[serde(rename = "@id")]
|
|
181
|
+
id: String,
|
|
182
|
+
bsdf: Bsdf,
|
|
183
|
+
}),
|
|
184
|
+
("itu-radio-material" => ItuRadioMaterial {
|
|
185
|
+
#[serde(rename = "@id")]
|
|
186
|
+
id: String,
|
|
187
|
+
#[serde(rename = "string")]
|
|
188
|
+
r#type: Type,
|
|
189
|
+
#[serde(skip)]
|
|
190
|
+
thickness: Option<Thickness>,
|
|
191
|
+
}),
|
|
192
|
+
}
|
|
193
|
+
|
|
116
194
|
let raw_mat = RawMaterial::deserialize(deserializer)?;
|
|
117
195
|
|
|
118
|
-
|
|
119
|
-
RawMaterial {
|
|
120
|
-
id,
|
|
121
|
-
rgb: PossiblyNestedRgb::Rgb { value },
|
|
122
|
-
} => (id, value),
|
|
123
|
-
RawMaterial {
|
|
196
|
+
match raw_mat {
|
|
197
|
+
RawMaterial::TwoSided {
|
|
124
198
|
id,
|
|
125
|
-
|
|
126
|
-
} =>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
let b = b_str.parse().map_err(de::Error::custom)?;
|
|
134
|
-
Ok(Material { id, rgb: [r, g, b] })
|
|
199
|
+
bsdf: Bsdf { rgb: Rgb { color } },
|
|
200
|
+
} => {
|
|
201
|
+
Ok(Material {
|
|
202
|
+
name: id.strip_prefix("mat-").unwrap_or(&id).to_string(),
|
|
203
|
+
id,
|
|
204
|
+
color,
|
|
205
|
+
thickness: None,
|
|
206
|
+
})
|
|
135
207
|
},
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
208
|
+
RawMaterial::ItuRadioMaterial {
|
|
209
|
+
id,
|
|
210
|
+
r#type: Type::Struct { value: r#type },
|
|
211
|
+
thickness,
|
|
212
|
+
} => {
|
|
213
|
+
let color = match r#type.as_str() {
|
|
214
|
+
// Copied from Sionna-RT's code, to match their colors:
|
|
215
|
+
// https://github.com/NVlabs/sionna-rt/blob/main/src/sionna/rt/radio_materials/itu_material.py
|
|
216
|
+
// v1.0.0
|
|
217
|
+
"marble" => [0.701, 0.644, 0.485],
|
|
218
|
+
"concrete" => [0.539, 0.539, 0.539],
|
|
219
|
+
"wood" => [0.266, 0.109, 0.060],
|
|
220
|
+
"metal" => [0.220, 0.220, 0.254],
|
|
221
|
+
"brick" => [0.402, 0.112, 0.087],
|
|
222
|
+
"glass" => [0.168, 0.139, 0.509],
|
|
223
|
+
"floorboard" => [0.539, 0.386, 0.025],
|
|
224
|
+
"ceiling_board" => [0.376, 0.539, 0.117],
|
|
225
|
+
"chipboard" => [0.509, 0.159, 0.323],
|
|
226
|
+
"plasterboard" => [0.051, 0.539, 0.133],
|
|
227
|
+
"plywood" => [0.136, 0.076, 0.539],
|
|
228
|
+
"very_dry_ground" => [0.539, 0.319, 0.223],
|
|
229
|
+
"medium_dry_ground" => [0.539, 0.181, 0.076],
|
|
230
|
+
"wet_ground" => [0.539, 0.027, 0.147],
|
|
231
|
+
_ => {
|
|
232
|
+
log::warn!(
|
|
233
|
+
"unknown material type: {type:#?}, using default color, i.e., black",
|
|
234
|
+
);
|
|
235
|
+
[0.0, 0.0, 0.0]
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
Ok(Material {
|
|
239
|
+
name: format!("itu_{type}"),
|
|
240
|
+
id,
|
|
241
|
+
color,
|
|
242
|
+
thickness: thickness.map(|t| {
|
|
243
|
+
match t {
|
|
244
|
+
Thickness::Struct { value: thickness } => thickness,
|
|
245
|
+
}
|
|
246
|
+
}),
|
|
247
|
+
})
|
|
140
248
|
},
|
|
141
249
|
}
|
|
142
250
|
}
|
|
@@ -218,7 +326,10 @@ impl SionnaScene {
|
|
|
218
326
|
pub(crate) fn load_xml(_: &Bound<'_, PyType>, file: &str) -> PyResult<Self> {
|
|
219
327
|
let input = BufReader::new(File::open(file)?);
|
|
220
328
|
quick_xml::de::from_reader(input).map_err(|err| {
|
|
221
|
-
PyValueError::new_err(format!(
|
|
329
|
+
PyValueError::new_err(format!(
|
|
330
|
+
"An error occurred while reading XML file {file:#?}: {}",
|
|
331
|
+
err
|
|
332
|
+
))
|
|
222
333
|
})
|
|
223
334
|
}
|
|
224
335
|
}
|
|
@@ -60,10 +60,14 @@ impl TriangleScene {
|
|
|
60
60
|
},
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
let
|
|
63
|
+
let material = sionna.materials.get(&shape.material_id);
|
|
64
|
+
|
|
65
|
+
let color = material.map(|mat| mat.color);
|
|
66
|
+
|
|
67
|
+
let material_name = material.map(|mat| mat.name.clone());
|
|
64
68
|
|
|
65
69
|
other_mesh.set_face_color(color.as_ref());
|
|
66
|
-
other_mesh.set_face_material(
|
|
70
|
+
other_mesh.set_face_material(material_name);
|
|
67
71
|
|
|
68
72
|
mesh.append(&mut other_mesh);
|
|
69
73
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{differt_core-0.0.32 → differt_core-0.0.34}/differt-core/benches/benchmarks/graph_iterators.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/geometry/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/scene/__init__.py
RENAMED
|
File without changes
|
{differt_core-0.0.32 → differt_core-0.0.34}/differt-core/python/differt_core/scene/_sionna.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{differt_core-0.0.32 → differt_core-0.0.34}/python/differt_core/_differt_core/rt/__init__.pyi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|