| Crates.io | eulumdat-photweb |
| lib.rs | eulumdat-photweb |
| version | 0.3.0 |
| created_at | 2025-12-11 13:10:07.314357+00 |
| updated_at | 2025-12-16 12:38:00.417853+00 |
| description | Photometric web representation, sampling, and 3D mesh generation for EULUMDAT/IES lighting data |
| homepage | https://eulumdat.icu |
| repository | https://github.com/holg/eulumdat-rs |
| max_upload_size | |
| id | 1979638 |
| size | 35,815 |
Photometric web representation, sampling, and 3D mesh generation for EULUMDAT/IES lighting data.
This crate extends the eulumdat library with advanced sampling and 3D visualization capabilities for photometric data.
use eulumdat::Eulumdat;
use eulumdat_photweb::PhotometricWeb;
// Load photometric data
let ldt = Eulumdat::from_file("luminaire.ldt")?;
// Create a photometric web
let web = PhotometricWeb::from(&ldt);
// Sample intensity at any angle (with bilinear interpolation)
let intensity = web.sample(45.0, 30.0); // C=45°, γ=30°
println!("Intensity at C45/G30: {} cd/klm", intensity);
// Sample normalized (0.0 to 1.0, relative to max intensity)
let normalized = web.sample_normalized(45.0, 30.0);
println!("Normalized: {:.2}", normalized);
// Check symmetry and bounds
println!("Max intensity: {} cd/klm", web.max_intensity());
println!("Symmetry: {:?}", web.symmetry());
Generate photometric solids (LDC - Luminous Distribution Curve) for 3D visualization:
use eulumdat::Eulumdat;
use eulumdat_photweb::{PhotometricWeb, LdcMesh};
let ldt = Eulumdat::from_file("luminaire.ldt")?;
let web = PhotometricWeb::from(&ldt);
// Generate mesh with 5° C-plane steps, 5° gamma steps, scale=1.0
let mesh = web.generate_ldc_mesh(5.0, 5.0, 1.0);
println!("Vertices: {}", mesh.vertex_count());
println!("Triangles: {}", mesh.triangle_count());
// Get data for graphics APIs (OpenGL, WebGPU, etc.)
let positions: Vec<f32> = mesh.positions_flat(); // [x0, y0, z0, x1, y1, z1, ...]
let normals: Vec<f32> = mesh.normals_flat(); // [nx0, ny0, nz0, ...]
let indices: &[u32] = &mesh.indices; // Triangle indices
The generated mesh uses a Y-up coordinate system:
The PhotometricWeb automatically handles all EULUMDAT symmetry types:
| Symmetry | Description | Stored C-planes |
|---|---|---|
None |
Full 360° data | 0°-360° |
VerticalAxis |
Rotationally symmetric | Single plane |
PlaneC0C180 |
Mirror across C0-C180 | 0°-180° |
PlaneC90C270 |
Mirror across C90-C270 | 90°-270° |
BothPlanes |
Quarter data | 0°-90° |
You can query any angle regardless of stored symmetry:
// Even with BothPlanes symmetry (only 0-90° stored),
// you can sample the full 360° range
let i_c0 = web.sample(0.0, 45.0);
let i_c180 = web.sample(180.0, 45.0);
let i_c270 = web.sample(270.0, 45.0);
// These are automatically mirrored from stored data
let mesh = web.generate_ldc_mesh(5.0, 5.0, 1.0);
// Create vertex buffer
let vertex_data: Vec<f32> = mesh.vertices
.iter()
.flat_map(|v| [v.x, v.y, v.z, v.nx, v.ny, v.nz])
.collect();
// Create index buffer
let index_data: &[u32] = &mesh.indices;
const mesh = photweb.generate_ldc_mesh(5.0, 5.0, 1.0);
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(mesh.positions_flat(), 3));
geometry.setAttribute('normal', new THREE.Float32BufferAttribute(mesh.normals_flat(), 3));
geometry.setIndex(Array.from(mesh.indices));
eulumdat - Core EULUMDAT/IES parsing libraryeulumdat-cli - Command-line tooleulumdat-wasm - WebAssembly bindingsLicensed under either of:
at your option.