use super::{BooleanClippingProcessor, CsgSolidProcessor};
use crate::diagnostics::{BoolFailureReason, BoolOp};
use crate::router::builtin_processor;
use crate::{Mesh, Result, TessellationQuality};
use ifc_lite_core::{DecodedEntity, EntityDecoder, IfcType};
pub(crate) const MAX_OPERAND_VISITS: u32 = 1024;
#[derive(Default)]
pub(crate) struct OperandPath {
path: rustc_hash::FxHashSet<u32>,
visits: u32,
}
impl OperandPath {
pub(crate) fn insert(&mut self, id: u32) -> bool {
self.path.insert(id)
}
pub(crate) fn remove(&mut self, id: u32) {
self.path.remove(&id);
}
pub(crate) fn len(&self) -> usize {
self.path.len()
}
pub(crate) fn charge(&mut self) -> bool {
if self.visits >= MAX_OPERAND_VISITS {
return false;
}
self.visits += 1;
true
}
}
impl BooleanClippingProcessor {
pub(super) fn process_operand_with_depth(
&self,
operand: &DecodedEntity,
decoder: &mut EntityDecoder,
depth: u32,
quality: TessellationQuality,
visited: &mut OperandPath,
) -> Result<Mesh> {
Ok(self
.process_operand_checked(BoolOp::Unknown, operand, decoder, depth, quality, visited)?
.0)
}
pub(super) fn process_operand_checked(
&self,
op: BoolOp,
operand: &DecodedEntity,
decoder: &mut EntityDecoder,
depth: u32,
quality: TessellationQuality,
visited: &mut OperandPath,
) -> Result<(Mesh, bool)> {
let mut unsupported = false;
let mesh = match operand.ifc_type {
IfcType::IfcCsgSolid => {
let csg = CsgSolidProcessor::with_skip_small_cuts(self.skip_small_cuts);
let out = csg.process_with_boolean_cycle_guard(
operand,
decoder,
&self.schema,
0,
quality,
visited,
);
self.absorb_failures(csg.take_failures());
out
}
IfcType::IfcBooleanResult | IfcType::IfcBooleanClippingResult => {
self.process_with_depth(operand, decoder, &self.schema, depth + 1, quality, visited)
}
other => match builtin_processor(other, &self.schema) {
Some(processor) => processor.process(operand, decoder, &self.schema, quality),
None => {
self.record_failure(
op,
BoolFailureReason::UnsupportedOperand(other.to_string()),
);
unsupported = true;
Ok(Mesh::new())
}
},
}?;
Ok((mesh, unsupported))
}
}