use crate::parallel_scan::ShardRecords;
use ifc_lite_core::EntityScanner;
pub const PREPASS_CLASS_NONE: u8 = 0;
pub const PREPASS_CLASS_STYLED_ITEM: u8 = 4;
pub const PREPASS_CLASS_INDEXED_COLOUR_MAP: u8 = 5;
pub const PREPASS_CLASS_MATERIAL_DEF_REPR: u8 = 6;
pub const PREPASS_CLASS_REL_ASSOCIATES_MATERIAL: u8 = 7;
pub const PREPASS_CLASS_REL_VOIDS: u8 = 8;
pub const PREPASS_CLASS_REL_FILLS: u8 = 9;
pub const PREPASS_CLASS_REL_AGGREGATES: u8 = 10;
pub const PREPASS_CLASS_PROJECT: u8 = 2;
pub const PREPASS_CLASS_SITE: u8 = 3;
pub const PREPASS_CLASS_MATERIAL_LAYER_SET: u8 = 13;
pub const PREPASS_CLASS_FLAG_GEOMETRY_JOB: u8 = 0x80;
pub const PREPASS_CLASS_FLAG_TYPE_CANDIDATE: u8 = 0x40;
pub const PREPASS_CLASS_MAPPED_ITEM: u8 = 11;
pub const PREPASS_CLASS_REL_DEFINES_BY_TYPE: u8 = 12;
pub const PREPASS_CLASS_CODE_MASK: u8 = 0x3F;
pub fn scan_shard_classified(
content: &[u8],
range_start: usize,
range_end: usize,
) -> (ShardRecords, Vec<u8>, Option<usize>) {
let mut scanner = if range_start == 0 {
EntityScanner::new(content)
} else {
EntityScanner::new_at(content, range_start)
};
let mut records = Vec::new();
let mut classes = Vec::new();
let mut handoff = None;
while let Some((id, type_name, start, entity_end)) = scanner.next_entity() {
if start >= range_end {
handoff = Some(start);
break;
}
records.push((id, start, entity_end));
classes.push(classify_type_name(type_name));
}
(records, classes, handoff)
}
pub fn classify_type_name(type_name: &str) -> u8 {
use ifc_lite_core::{has_geometry_by_name, IfcType};
let named = match type_name {
"IFCPROJECT" => PREPASS_CLASS_PROJECT,
"IFCSITE" => return PREPASS_CLASS_SITE, "IFCSTYLEDITEM" => PREPASS_CLASS_STYLED_ITEM,
"IFCINDEXEDCOLOURMAP" => PREPASS_CLASS_INDEXED_COLOUR_MAP,
"IFCMATERIALDEFINITIONREPRESENTATION" => PREPASS_CLASS_MATERIAL_DEF_REPR,
"IFCRELASSOCIATESMATERIAL" => PREPASS_CLASS_REL_ASSOCIATES_MATERIAL,
"IFCRELVOIDSELEMENT" => PREPASS_CLASS_REL_VOIDS,
"IFCRELFILLSELEMENT" => PREPASS_CLASS_REL_FILLS,
"IFCRELAGGREGATES" => PREPASS_CLASS_REL_AGGREGATES,
"IFCMAPPEDITEM" => PREPASS_CLASS_MAPPED_ITEM,
"IFCRELDEFINESBYTYPE" => PREPASS_CLASS_REL_DEFINES_BY_TYPE,
"IFCMATERIALLAYERSET" | "IFCMATERIALLAYERSETUSAGE" => PREPASS_CLASS_MATERIAL_LAYER_SET,
_ => PREPASS_CLASS_NONE,
};
if named != PREPASS_CLASS_NONE {
return named;
}
let mut class = PREPASS_CLASS_NONE;
if type_name.ends_with("TYPE") || type_name.ends_with("STYLE") {
let ty = IfcType::from_str(type_name);
if ty.is_subtype_of(IfcType::IfcTypeProduct) {
class |= PREPASS_CLASS_FLAG_TYPE_CANDIDATE;
}
}
if has_geometry_by_name(type_name) {
class |= PREPASS_CLASS_FLAG_GEOMETRY_JOB;
}
class
}