use ifc_lite_processing::process_geometry;
use std::path::PathBuf;
const BOILER_TYPE_ID: u32 = 43;
fn fixture(name: &str) -> Option<String> {
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../tests/models/buildingsmart/annex_e/tessellated-shape-with-style")
.join(name);
std::fs::read_to_string(path).ok()
}
#[test]
fn blob_texture_decodes_to_rgba_with_uvs() {
let Some(content) = fixture("tessellation-with-blob-texture.ifc") else {
eprintln!("skipping: fixture missing — run `pnpm fixtures`");
return;
};
let result = process_geometry(&content);
let mesh = result
.meshes
.iter()
.find(|m| m.express_id == BOILER_TYPE_ID)
.expect("boiler type #43 should render");
let texture = mesh.texture.as_ref().expect("blob texture should decode");
assert!(texture.width > 0 && texture.height > 0, "decoded image has size");
assert!(texture.texture_id > 0, "texture carries its IfcSurfaceTexture id");
let rgba = texture.rgba.as_ref().expect("blob texture ships decoded pixels");
assert_eq!(
rgba.len(),
(texture.width as usize) * (texture.height as usize) * 4,
"RGBA8 buffer is width*height*4"
);
let uvs = mesh.uvs.as_ref().expect("textured mesh carries UVs");
assert_eq!(
uvs.len(),
(mesh.positions.len() / 3) * 2,
"UVs are 2 floats per vertex, 1:1 with positions"
);
let verts = mesh.positions.len() / 3;
assert!(verts >= 3, "non-empty welded vertex buffer, got {verts}");
assert_eq!(mesh.indices.len() % 3, 0, "index buffer is whole triangles");
let max_u = uvs.iter().step_by(2).cloned().fold(f32::MIN, f32::max);
assert!(max_u <= 1.5, "UVs should map ~1:1 (authored coords), got max u = {max_u}");
}
#[test]
fn pixel_texture_decodes_known_pixels() {
let Some(content) = fixture("tessellation-with-pixel-texture.ifc") else {
eprintln!("skipping: fixture missing — run `pnpm fixtures`");
return;
};
let result = process_geometry(&content);
let mesh = result
.meshes
.iter()
.find(|m| m.express_id == BOILER_TYPE_ID)
.expect("boiler type #43 should render");
let texture = mesh.texture.as_ref().expect("pixel texture should decode");
assert_eq!(texture.width, 256, "pixel texture width");
assert_eq!(texture.height, 256, "pixel texture height");
let rgba = texture.rgba.as_ref().expect("pixel texture ships decoded pixels");
assert_eq!(rgba.len(), 256 * 256 * 4, "RGBA8 256x256");
assert_eq!(
&rgba[0..4],
&[0, 0, 0, 255],
"first pixel is opaque black"
);
assert!(mesh.uvs.is_some(), "textured mesh carries UVs");
}