ifc_lite_geometry/router/
brep_signatures.rs1use super::*;
8
9#[derive(Clone, Default)]
13pub struct SharedBrepSignatureCache(Arc<Mutex<FxHashMap<u32, u128>>>);
14
15impl GeometryRouter {
16 pub fn new_brep_signature_cache() -> SharedBrepSignatureCache {
18 SharedBrepSignatureCache::default()
19 }
20
21 pub fn enable_shared_brep_signature_cache(&mut self, cache: SharedBrepSignatureCache) {
24 self.shared_brep_signatures = Some(cache);
25 }
26
27 fn brep_key_with_params(&self, structural: u128, rtc: (f64, f64, f64)) -> u128 {
28 super::content_hash::key_with_params(structural, self.tessellation_quality.to_index(), self.unit_scale, rtc)
29 }
30
31 #[cfg(test)]
33 pub(super) fn item_dedup_key(&self, item: &DecodedEntity, decoder: &mut EntityDecoder) -> Option<u128> {
34 self.item_dedup_key_in_frame(item, decoder, self.rtc_offset)
35 }
36
37 pub(super) fn item_dedup_key_in_frame(
46 &self,
47 item: &DecodedEntity,
48 decoder: &mut EntityDecoder,
49 rtc: (f64, f64, f64),
50 ) -> Option<u128> {
51 self.item_dedup_cache.as_ref()?;
52 let base = matches!(
54 item.ifc_type,
55 IfcType::IfcFacetedBrep
56 | IfcType::IfcBooleanResult
57 | IfcType::IfcBooleanClippingResult
58 | IfcType::IfcExtrudedAreaSolid
59 );
60 let extra = Self::build_dedup_extra_enabled()
64 && matches!(
65 item.ifc_type,
66 IfcType::IfcPolygonalFaceSet
67 | IfcType::IfcTriangulatedFaceSet
68 | IfcType::IfcShellBasedSurfaceModel
69 | IfcType::IfcFaceBasedSurfaceModel
70 );
71 if !(base || extra) {
72 return None;
73 }
74 if item.ifc_type == IfcType::IfcFacetedBrep {
77 if let Some(cache) = &self.shared_brep_signatures {
78 let hit = cache.0.lock().unwrap_or_else(|e| e.into_inner()).get(&item.id).copied();
79 if let Some(signature) = hit {
80 return Some(self.brep_key_with_params(signature, rtc));
81 }
82 }
83 if let Some(face_count) = super::content_hash::faceted_brep_face_count(decoder, item.id) {
84 if face_count > super::content_hash::FACETED_BREP_DEDUP_FACE_LIMIT {
85 return None;
86 }
87 }
88 }
89 if item.ifc_type == IfcType::IfcFacetedBrep {
92 if let Some(cache) = &self.shared_brep_signatures {
93 if super::content_hash::is_faceted_brep(decoder, item.id) {
94 if let Some(signature) = super::content_hash::try_faceted_brep_signature(decoder, item.id) {
95 self.content_sig_memo.borrow_mut().insert(item.id, signature);
96 cache.0.lock().unwrap_or_else(|e| e.into_inner()).insert(item.id, signature);
97 return Some(self.brep_key_with_params(signature, rtc));
98 }
99 }
100 let mut memo = self.content_sig_memo.borrow_mut();
101 let mut refused = self.content_hash_oversized_ref_drops.borrow_mut();
102 let signature = super::content_hash::item_signature_after_failed_brep(decoder, item.id, &mut memo, &mut refused);
103 return Some(self.brep_key_with_params(signature, rtc));
104 }
105 }
106 let structural = {
107 let mut memo = self.content_sig_memo.borrow_mut();
108 let mut refused = self.content_hash_oversized_ref_drops.borrow_mut();
109 super::content_hash::item_signature(decoder, item.id, &mut memo, &mut refused)
110 };
111 Some(super::content_hash::key_with_params(
112 structural,
113 self.tessellation_quality.to_index(),
114 self.unit_scale,
115 rtc,
116 ))
117 }
118
119}
120
121#[cfg(test)]
122#[path = "brep_signatures_tests.rs"]
123mod tests;