pub struct MeshData {Show 20 fields
pub express_id: u32,
pub ifc_type: String,
pub global_id: Option<String>,
pub name: Option<String>,
pub presentation_layer: Option<String>,
pub positions: Vec<f32>,
pub normals: Vec<f32>,
pub indices: Vec<u32>,
pub color: [f32; 4],
pub material_name: Option<String>,
pub geometry_item_id: Option<u32>,
pub material_id: Option<u32>,
pub properties: Option<BTreeMap<String, String>>,
pub uvs: Option<Vec<f32>>,
pub texture: Option<MeshTextureData>,
pub geometry_class: u8,
pub origin: [f64; 3],
pub instance: Option<InstanceMeta>,
pub local_bounds: Option<[f32; 6]>,
pub local_to_world: Option<[f64; 16]>,
}Expand description
Individual mesh data with geometry and metadata.
Fields§
§express_id: u32Express ID of the IFC element.
ifc_type: StringIFC type name (e.g., “IfcWall”).
global_id: Option<String>IFC GlobalId (Root attribute #0) when available.
name: Option<String>IFC Name (Root/Object attribute #2) when available.
presentation_layer: Option<String>IFC presentation layer assignment name when available.
positions: Vec<f32>Vertex positions (x, y, z triplets).
normals: Vec<f32>Vertex normals (x, y, z triplets).
indices: Vec<u32>Triangle indices.
color: [f32; 4]RGBA color [r, g, b, a] in 0-1 range.
material_name: Option<String>Optional material/style name resolved from per-item IFC styling.
geometry_item_id: Option<u32>The IfcRepresentationItem this mesh was tessellated from.
ALWAYS a representation item, and never a material — a host can follow
it to source and land on the entity that produced the geometry. Before
#3199 this field also carried the IfcMaterial id for material-layered
walls and slabs, so following it landed on the wrong entity with nothing
to warn the caller.
None where the identity is genuinely merged away: the single-mesh
fallback and the cached IfcMappedItem path. A boolean result reports
the IfcBooleanResult id, which is a real entity. GPU-instanced
occurrences used to be None here too; they now carry the id through
RawInstanceOccurrence::geometry_item_id and the IFNS wire format.
material_id: Option<u32>The IfcMaterial whose layer this mesh is a slice of.
ALWAYS a material, and never a representation item. Set only on the
material-layer path (router/layers.rs), and DISJOINT from
Self::geometry_item_id — never both, so a consumer that ignores the
distinction still cannot read one as the other (#3199).
properties: Option<BTreeMap<String, String>>Optional IFC property set values keyed by IFC property names. Primarily attached for IfcSpace/IfcZone so downstream tools can build room attribute UIs.
uvs: Option<Vec<f32>>Per-vertex texture coordinates (u, v pairs, 1:1 with positions),
present only for textured meshes (issue #961).
texture: Option<MeshTextureData>Decoded surface texture, present only for textured meshes (#961).
geometry_class: u8Provenance of the geometry for the viewer’s Model/Types switch (#957):
0 = ordinary occurrence, 1 = orphan type-product RepresentationMap (no
occurrence instantiates it), 2 = instanced type-product map (the type
library shape; its occurrences already draw the real geometry), 3 =
occurrence geometry of a material-layer wall (GEOM_CLASS_LAYER_SLICE).
Serde-default so existing JSON payloads and disk caches stay readable;
skipped when 0 so ordinary meshes serialize byte-identically.
origin: [f64; 3]Per-mesh local origin (world/RTC frame, f64). positions are stored
RELATIVE to this — the world position of a vertex is origin + position —
so building/georef-scale placement never collapses adjacent vertices to
bit-identical f32. The renderer applies it as a per-mesh translation
(camera-relative). [0, 0, 0] ⇒ positions are absolute (legacy/local).
Serde-default + skip-when-zero so existing payloads/caches stay readable
and local meshes serialize byte-identically.
instance: Option<InstanceMeta>GPU-instancing metadata (rep-identity + per-occurrence world transform),
attached only when IFC_LITE_INSTANCING is on and the element is a clean
single-item mapped instance. Purely in-memory for the native streaming
path — #[serde(skip)] because instancing is recomputed fresh each load
and never round-trips through the JSON/disk cache.
local_bounds: Option<[f32; 6]>Local (pre-placement, object-space) AABB (issue #1474) — see
ifc_lite_geometry::Mesh::local_bounds. Purely in-memory, like
instance — #[serde(skip)], recomputed fresh each load.
local_to_world: Option<[f64; 16]>The resolved IfcLocalPlacement chain applied to this mesh (issue
#1474), row-major — see ifc_lite_geometry::Mesh::local_to_world.
Purely in-memory, like instance — #[serde(skip)].
Implementations§
Source§impl MeshData
impl MeshData
Sourcepub fn new(
express_id: u32,
ifc_type: String,
positions: Vec<f32>,
normals: Vec<f32>,
indices: Vec<u32>,
color: [f32; 4],
) -> Self
pub fn new( express_id: u32, ifc_type: String, positions: Vec<f32>, normals: Vec<f32>, indices: Vec<u32>, color: [f32; 4], ) -> Self
Create a new MeshData from geometry components.
Sourcepub fn with_instance(self, instance: Option<InstanceMeta>) -> Self
pub fn with_instance(self, instance: Option<InstanceMeta>) -> Self
Attach GPU-instancing metadata (see the instance field).
Sourcepub fn with_local_bounds(self, local_bounds: Option<[f32; 6]>) -> Self
pub fn with_local_bounds(self, local_bounds: Option<[f32; 6]>) -> Self
Set the local (pre-placement, object-space) AABB (see local_bounds).
Sourcepub fn with_local_to_world(self, local_to_world: Option<[f64; 16]>) -> Self
pub fn with_local_to_world(self, local_to_world: Option<[f64; 16]>) -> Self
Set the resolved placement transform (see local_to_world).
Sourcepub fn with_geometry_class(self, geometry_class: u8) -> Self
pub fn with_geometry_class(self, geometry_class: u8) -> Self
Tag the geometry’s provenance for the Model/Types view switch (#957).
Sourcepub fn with_origin(self, origin: [f64; 3]) -> Self
pub fn with_origin(self, origin: [f64; 3]) -> Self
Set the per-mesh local origin (positions are relative to it).
Sourcepub fn with_element_metadata(
self,
global_id: Option<String>,
name: Option<String>,
presentation_layer: Option<String>,
) -> Self
pub fn with_element_metadata( self, global_id: Option<String>, name: Option<String>, presentation_layer: Option<String>, ) -> Self
Set element-level IFC metadata.
Sourcepub fn with_style_metadata(
self,
material_name: Option<String>,
source_id: Option<u32>,
id_is_material: bool,
) -> Self
pub fn with_style_metadata( self, material_name: Option<String>, source_id: Option<u32>, id_is_material: bool, ) -> Self
Set material name and the source id, routed to whichever of the two disjoint fields the id actually IS.
Takes the discriminator rather than the destination field so a caller
cannot put a material id in geometry_item_id by picking the wrong
setter — the confusion #3199 removes is exactly that, and a two-setter
API would leave it one typo away.
A source id of 0 becomes None, on BOTH fields. STEP instance
names start at #1, so 0 is never an entity; every producer that
hands one here is passing its own “no reference” sentinel through.
material_layer_index.rs is the live case: IfcMaterialLayer.Material
is OPTIONAL and the layer’s material_id is get_ref(0).unwrap_or(0),
so an air gap or ventilated cavity arrives as 0. Storing that would
make material_id say “a slice of IfcMaterial #0”, and a host that
followed it — the one thing this field exists for — would land on
nothing. That is the defect #3199 fixes, one field over, so the filter
lives HERE rather than at each producer, where the next producer would
have to remember it.
Sourcepub fn style_geometry_item_id(
source_id: Option<u32>,
id_is_material: bool,
) -> Option<u32>
pub fn style_geometry_item_id( source_id: Option<u32>, id_is_material: bool, ) -> Option<u32>
The geometry_item_id a producer’s source_id resolves to, given the
#3199 discriminator: None when the id is a material’s, and None for
the 0 sentinel (see Self::with_style_metadata, which owns the why).
Passing the NEGATED discriminator gives the material_id half.
Both rules live HERE because both are invisible when violated. element.rs
computes the same id for a don’t-bake RawInstanceOccurrence, which has no
MeshData to run with_style_metadata over, so it calls this rather than
restating the pair.
Sourcepub fn with_properties(
self,
properties: Option<BTreeMap<String, String>>,
) -> Self
pub fn with_properties( self, properties: Option<BTreeMap<String, String>>, ) -> Self
Attach optional IFC property set values.
Sourcepub fn vertex_count(&self) -> usize
pub fn vertex_count(&self) -> usize
Get the number of vertices.
Sourcepub fn triangle_count(&self) -> usize
pub fn triangle_count(&self) -> usize
Get the number of triangles.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for MeshData
impl<'de> Deserialize<'de> for MeshData
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for MeshData
impl RefUnwindSafe for MeshData
impl Send for MeshData
impl Sync for MeshData
impl Unpin for MeshData
impl UnwindSafe for MeshData
Blanket Implementations§
§impl<U> As for U
impl<U> As for U
§fn as_<T>(self) -> Twhere
T: CastFrom<U>,
fn as_<T>(self) -> Twhere
T: CastFrom<U>,
self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. Read moreSource§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> Pointable for T
impl<T> Pointable for T
§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read more§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.