ifc_lite_processing/
prepass_styled.rs1use ifc_lite_core::EntityDecoder;
10use rustc_hash::FxHashMap;
11
12use crate::prepass::{collect_geometry_style_info, extract_style_info_from_styled_item, surface_style_from_styled_item, Span};
13use crate::style::{GeometryStyleInfo, SpecularMaterial};
14
15pub type StyleSeeds = (FxHashMap<u32, [f32; 4]>, FxHashMap<u32, GeometryStyleInfo>);
17
18pub fn resolve_styled_items_into(
26 styled_items: &[Span],
27 decoder: &mut EntityDecoder,
28 defer_attached_styles: bool,
29 orphan_styled_items: &mut FxHashMap<u32, [f32; 4]>,
30 geometry_style_index: &mut FxHashMap<u32, GeometryStyleInfo>,
31 deferred_attached_styled_spans: &mut Vec<(usize, usize)>,
32) {
33 for &(id, start, end) in styled_items {
34 let Ok(styled_item) = decoder.decode_at_with_id(id, start, end) else {
35 if defer_attached_styles {
36 deferred_attached_styled_spans.push((start, end));
39 }
40 continue;
41 };
42 if styled_item.get_ref(0).is_none() {
43 if let Some(info) = extract_style_info_from_styled_item(&styled_item, decoder) {
47 orphan_styled_items.insert(id, info.color);
48 }
49 } else if defer_attached_styles {
50 deferred_attached_styled_spans.push((start, end));
51 } else {
52 collect_geometry_style_info(geometry_style_index, &styled_item, decoder);
53 }
54 }
55}
56
57
58pub fn resolve_geometry_finishes(
72 styled_items: &[Span],
73 decoder: &mut EntityDecoder,
74) -> FxHashMap<u32, SpecularMaterial> {
75 let mut finishes: FxHashMap<u32, SpecularMaterial> = FxHashMap::default();
76 let mut claimed_without_finish: rustc_hash::FxHashSet<u32> = Default::default();
77 for &(id, start, end) in styled_items {
78 let Ok(styled_item) = decoder.decode_at_with_id(id, start, end) else { continue };
79 let Some(geometry_id) = styled_item.get_ref(0) else { continue };
80 if finishes.contains_key(&geometry_id) || claimed_without_finish.contains(&geometry_id) {
81 continue;
82 }
83 match surface_style_from_styled_item(&styled_item, decoder) {
84 Some((style_id, _)) => {
85 let finish = crate::style::extract_surface_style_specular(style_id, decoder).unwrap_or_default();
86 finishes.insert(geometry_id, finish);
87 }
88 None if extract_style_info_from_styled_item(&styled_item, decoder).is_some() => {
90 claimed_without_finish.insert(geometry_id);
91 }
92 None => {}
93 }
94 }
95 finishes
96}
97
98pub fn flat_styles_rgba8_from_geometry_columns(
108 geom_ids: &[u32],
109 geom_colors: &[f32],
110 resolved: &crate::prepass::ResolvedPrepass,
111 decoder: &mut EntityDecoder,
112) -> (Vec<u32>, Vec<u8>) {
113 debug_assert!(resolved.geometry_style_index.is_empty());
114 let mut overlay: FxHashMap<u32, [f32; 4]> = FxHashMap::default();
116 for (&geometry_id, &color) in &resolved.indexed_colour_index {
117 overlay.entry(geometry_id).or_insert(color);
118 }
119 let material_styles = crate::style::build_material_style_index(
120 &resolved.material_def_reprs,
121 &resolved.orphan_styled_items,
122 decoder,
123 );
124 for (&mat_id, &color) in crate::style::flatten_material_color_index(&material_styles).iter() {
125 overlay.entry(mat_id).or_insert(color);
126 }
127 for (&element_id, colors) in &resolved.element_material_colors {
128 if let Some(&color) = colors.first() {
129 overlay.entry(element_id).or_insert(color);
130 }
131 }
132
133 let mut geom_order: Vec<u32> = (0..geom_ids.len() as u32).collect();
135 geom_order.sort_unstable_by_key(|&i| geom_ids[i as usize]);
136 let mut overlay_sorted: Vec<(u32, [f32; 4])> = overlay.into_iter().collect();
137 overlay_sorted.sort_unstable_by_key(|&(id, _)| id);
138
139 let mut ids: Vec<u32> = Vec::with_capacity(geom_ids.len() + overlay_sorted.len());
140 let mut rgba: Vec<u8> = Vec::with_capacity((geom_ids.len() + overlay_sorted.len()) * 4);
141 let push = |id: u32, color: [f32; 4], ids: &mut Vec<u32>, rgba: &mut Vec<u8>| {
142 ids.push(id);
143 rgba.extend_from_slice(&crate::style::Rgba::from_array(color).to_rgba8());
144 };
145 let mut oi = 0;
146 for &gi in &geom_order {
147 let id = geom_ids[gi as usize];
148 while oi < overlay_sorted.len() && overlay_sorted[oi].0 < id {
149 let (oid, oc) = overlay_sorted[oi];
150 push(oid, oc, &mut ids, &mut rgba);
151 oi += 1;
152 }
153 if oi < overlay_sorted.len() && overlay_sorted[oi].0 == id {
154 oi += 1; }
156 let c = gi as usize * 4;
157 push(
158 id,
159 [geom_colors[c], geom_colors[c + 1], geom_colors[c + 2], geom_colors[c + 3]],
160 &mut ids,
161 &mut rgba,
162 );
163 }
164 while oi < overlay_sorted.len() {
165 let (oid, oc) = overlay_sorted[oi];
166 push(oid, oc, &mut ids, &mut rgba);
167 oi += 1;
168 }
169 (ids, rgba)
170}