Merge PR #1045: complete UNION behavior

This commit is contained in:
Hakan Seven committed 2026-09-07 18:36:04 +03:00
commit 050fbb0a6b
11 files changed
+528 -85

No files matched your search

+4
View File
@@ -163,6 +163,10 @@ pub fn kernel_surface_body(surface: &Surface) -> Option<KernelBody> {
kernel_acis_body(&surface.acis_data)
}
pub fn kernel_region_body(region: &Region) -> Option<KernelBody> {
kernel_acis_body(&region.acis_data)
}
fn kernel_acis_body(acis: &acadrust::entities::AcisData) -> Option<KernelBody> {
let sat = parse_acis(
|| acis.parse(),
+3
View File
@@ -605,6 +605,9 @@ impl Scene {
Some(EntityType::Surface(surface)) => {
crate::scene::convert::solid3d_tess::kernel_surface_body(surface)
}
Some(EntityType::Region(region)) => {
crate::scene::convert::solid3d_tess::kernel_region_body(region)
}
_ => None,
})?;
Some((handle, body))
+51
View File
@@ -214,6 +214,21 @@ pub fn has_specialized_primitive_properties(
)
}
/// Solid history results whose public Properties palette is fully described by
/// the common entity rows plus [`primitive_properties`]. A generic B-rep has
/// no stable primitive dimensions to expose, but it still uses the compact
/// Solid History palette rather than the internal ACIS/cache diagnostics.
pub fn has_compact_solid_properties(
document: &acadrust::CadDocument,
handle: acadrust::Handle,
) -> bool {
has_specialized_primitive_properties(document, handle)
|| matches!(
document.solid_history_operation(handle),
Some(SolidHistoryOperation::Brep(_))
)
}
pub fn reference_point(operation: &SolidHistoryOperation) -> Option<glam::DVec3> {
match operation {
SolidHistoryOperation::Box(value) | SolidHistoryOperation::Wedge(value) => world_point(
@@ -975,6 +990,41 @@ fn cone_properties(
]
}
fn brep_properties(
document: &acadrust::CadDocument,
handle: acadrust::Handle,
) -> Vec<PropSection> {
let (record_history, object_show_history, show_history_mode) =
history_flags(document, handle).unwrap_or((false, false, 1));
let (show_history, show_history_editable) =
displayed_history_state(object_show_history, show_history_mode);
vec![PropSection {
title: t!("Solid History").into_owned(),
props: vec![
Property {
label: t!("History").into_owned(),
field: PROP_HISTORY,
value: PropValue::Choice {
selected: if record_history { "Record" } else { "None" }.to_string(),
options: vec!["None".to_string(), "Record".to_string()],
},
},
Property {
label: t!("Show History").into_owned(),
field: PROP_SHOW_HISTORY,
value: if show_history_editable {
PropValue::Choice {
selected: if show_history { "Yes" } else { "No" }.to_string(),
options: vec!["No".to_string(), "Yes".to_string()],
}
} else {
PropValue::ReadOnly(if show_history { "Yes" } else { "No" }.to_string())
},
},
],
}]
}
fn cylinder_properties(
document: &acadrust::CadDocument,
handle: acadrust::Handle,
@@ -1411,6 +1461,7 @@ pub fn primitive_properties(
extrusion_properties(document, handle, value)
}
SolidHistoryOperation::Revolve(value) => revolve_properties(document, handle, value),
SolidHistoryOperation::Brep(_) => brep_properties(document, handle),
_ => Vec::new(),
}
}
+6 -1
View File
@@ -365,13 +365,18 @@ pub enum Bool {
/// missing, and passing that on unchanged is the point: a half-done boolean
/// looks finished.
pub fn boolean(op: Bool, a: &Body, b: &Body) -> Option<Body> {
boolean_result(op, a, b).ok()
}
/// Combine two solids while retaining the kernel's exact refusal reason.
pub fn boolean_result(op: Bool, a: &Body, b: &Body) -> Result<Body, brep::Snag> {
let how = match op {
Bool::Union => brep::Operation::Union,
Bool::Subtract => brep::Operation::Difference,
Bool::Intersect => brep::Operation::Intersection,
};
let tolerance = brep::operation_tolerance(&[a, b]);
brep::combine(a.clone(), b.clone(), how, tolerance).ok()
brep::combine(a.clone(), b.clone(), how, tolerance)
}
// ── Tessellation ────────────────────────────────────────────────────────────