Merge pull request #1447 from brett19/port/api-brep-material-census

port: SmApiBrepMaterialCensus (fixes #1436)
This commit is contained in:
bherbruck
2026-10-29 01:30:19 +00:00
committed by GitHub
6 changed files with 229 additions and 7 deletions
+42 -3
View File
@@ -76,11 +76,11 @@ fn output(op: i32, r: Result<Vec<f64>>) -> Output {
}
}
/// The case ops are `1..=25`; the FFI's `0` and `26` are the graph exports
/// The case ops are `1..=25` and `27` (`SmApiBrepMaterialCensus`); the FFI's `0` and `26` are the graph exports
/// [`imported`] reads the native B-rep through, which have no Rust counterpart to
/// compare.
fn compared_op(op: i32) -> std::result::Result<(), HarnessError> {
if (1..=25).contains(&op) {
if (1..=25).contains(&op) || op == 27 {
Ok(())
} else {
Err(HarnessError::new(format!("op {op} is not a compared query (1..=25)")))
@@ -94,7 +94,7 @@ fn decode(op: i32, values: Vec<f64>) -> Output {
let mut floats = Vec::new();
for (i, value) in values.into_iter().enumerate() {
let integer = i == 0
|| matches!(op, 9 | 10 | 11 | 13 | 14 | 18 | 23)
|| matches!(op, 9 | 10 | 11 | 13 | 14 | 18 | 23 | 27)
|| matches!(op, 2 | 6 | 12) && i == 1
|| op == 3 && i == 5
|| op == 7 && i == 2;
@@ -369,6 +369,29 @@ fn own_brep(
a[6],
a[6],
)
} else if (14..=16).contains(&kind) {
use solidcore::boolean::api_brep as bo;
let origin = v([a[0], a[1], a[2]]);
let first = solidcore::primitive::api_primitives::create_box(k, origin, a[6], a[6], a[6]);
let (at, size) = if kind == 15 {
(v([a[0] + 2. * a[6], a[1], a[2]]), a[6])
} else {
(
v([a[0] + 0.25 * a[6], a[1] + 0.25 * a[6], a[2] + 0.25 * a[6]]),
0.5 * a[6],
)
};
match first {
Ok(outer) => solidcore::primitive::api_primitives::create_box(k, at, size, size, size)
.and_then(|inner| {
if kind == 14 {
bo::boolean_difference(k, outer, inner)
} else {
bo::boolean_merge(k, outer, inner)
}
}),
Err(e) => Err(e),
}
} else if kind == 12 {
// two real closed curve loops: an outer square and a square hole
const XY: [[f64; 2]; 8] = [
@@ -881,6 +904,22 @@ fn topology(k: &mut Kernel, i: &Inputs, b: &mut Brep, second: &mut Brep) -> Resu
api::edge_classify_parameter(k, b, e.ok_or_else(missing)?, a[14])?.code(),
)),
24 => vec(&mut o, api::edge_tangent(k, b, e.ok_or_else(missing)?, a[14])?),
27 => {
if a[18] != 0. {
// the shim's rewrite of the void flags along the region list
let ids = solidcore::topology::brep::p1::regions(b, None)?;
for (n, id) in ids.into_iter().enumerate() {
let flag = match (n + index) % 3 {
0 => 0,
1 => 1,
_ => solidcore::topology::brep_data::UNSURE,
};
b.region_mut(id)?.set_is_void(flag);
}
}
let (solids, voids) = api::brep_material_census(b)?;
o.extend([solids as f64, voids as f64]);
}
25 => vec(&mut o, api::vertex_get_point(b, vert.ok_or_else(missing)?)?),
_ => return Err(missing()),
}
@@ -35,7 +35,7 @@ mod sys {
pub fn eval(op: i32, input: &[f64]) -> Result<Vec<f64>, FfiError> {
let bad = || FfiError::InvalidArgument("query.api_queries layout or construction range".into());
if (input.len() != 22 && !(input.len() == 26 && matches!(op, 7 | 8)))
|| !(0..=26).contains(&op)
|| !(0..=27).contains(&op)
|| input.iter().any(|x| !x.is_finite() || x.abs() > 1e12)
{
return Err(bad());
@@ -45,7 +45,7 @@ pub fn eval(op: i32, input: &[f64]) -> Result<Vec<f64>, FfiError> {
.ok_or_else(bad)?
.try_into()
.map_err(|_| bad())?;
if !(0.0..=13.0).contains(&a[21])
if !(0.0..=16.0).contains(&a[21])
|| a[21].fract() != 0.0
|| a[6] <= 1e-10
|| a[6] > 1e6
@@ -86,6 +86,7 @@ pub fn eval(op: i32, input: &[f64]) -> Result<Vec<f64>, FfiError> {
if (op == 1 || op == 2) && !is_curve
|| op == 3 && !matches!(kind, 4 | 5 | 8 | 9 | 13)
|| kind == 13 && op != 3
|| (14..=16).contains(&kind) && op != 27
{
return Err(bad());
}
+43
View File
@@ -13,6 +13,7 @@
//! | [`get_edges`], [`get_faces`], [`find_edge`], [`find_faces`] | `SmApiGetEdges`, `SmApiGetFaces`, `SmApiFindEdge`, `SmApiFindFaces` |
//! | [`face_get_boundary_loops`] | `SmApiFaceGetBoundaryLoops` |
//! | [`brep_is_manifold_solid`], [`brep_bounding_box`] | `SmApiBrepIsManifoldSolid`, `SmApiBrepBoundingBox` |
//! | [`brep_material_census`] | `SmApiBrepMaterialCensus` |
//! | [`face_bounding_box`], [`face_internal_point`], [`face_classify_uv`], [`face_closest_point`], [`face_closest_point_in_shape`] | `SmApiFaceBoundingBox`, `SmApiFaceInternalPoint`, `SmApiFaceClassifyUV`, `SmApiFaceClosestPoint` |
//! | [`edge_bounding_box`], [`edge_closest_point`], [`edge_parameter_range`], [`edge_classify_parameter`], [`edge_tangent`] | `SmApiEdgeBoundingBox`, `SmApiEdgeClosestPoint`, `SmApiEdgeParameterRange`, `SmApiEdgeClassifyParameter`, `SmApiEdgeTangent` |
//! | [`vertex_get_point`] | `SmApiVertexGetPoint` |
@@ -785,6 +786,32 @@ pub fn brep_is_manifold_solid(brep: &Brep) -> Result<bool> {
crate::topology::brep::p2::is_manifold_solid(brep)
}
/// Counts a B-rep's material regions and enclosed void cavities
/// (`SmApiBrepMaterialCensus`), returned as `(solids, voids)`.
///
/// One walk of `SmBrep::GetRegions`: a region whose `IsVoid()` is nonzero (`TRUE` or
/// `UNSURE`) counts as a void unless it is the infinite region; any other region counts
/// as a solid. A null B-rep (`SM_ERR_INVALID_INPUT`) has no typed equivalent.
///
/// # Errors
///
/// A dangling region on the region list.
pub fn brep_material_census(brep: &Brep) -> Result<(usize, usize)> {
let mut solids = 0usize;
let mut voids = 0usize;
for id in crate::topology::brep::p1::regions(brep, None)? {
let region = brep.region(id)?;
if region.is_void() != 0 {
if !region.is_infinite_region(brep, id) {
voids += 1;
}
} else {
solids += 1;
}
}
Ok((solids, voids))
}
/// Loose or tight B-rep box (`SmApiBrepBoundingBox`); missing queries are `Unported`.
pub fn brep_bounding_box(k: &Kernel, brep: &Brep, tight: bool) -> Result<Extent3d> {
if tight {
@@ -987,6 +1014,22 @@ mod tests {
use crate::nurbs::math::CPoint;
use crate::nurbs::srf_basic::Surface as NlSurface;
#[test]
fn material_census_of_a_box_and_an_empty_brep() {
// the repro of issue 1436: one material region, the infinite region is no void
let mut k = Kernel::default();
let b = crate::primitive::api_primitives::create_box(
&mut k,
Vec3::new(1.0, -2.0, 3.0),
10.0,
20.0,
30.0,
)
.unwrap();
assert_eq!(brep_material_census(&b).unwrap(), (1, 0));
assert_eq!(brep_material_census(&Brep::new()).unwrap(), (0, 0));
}
#[derive(Clone, Copy, PartialEq)]
struct Object(ObjectKind);
impl SolutionObject for Object {
@@ -0,0 +1,92 @@
{
"cases": [
{"name":"census_line_wire_scale1_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,1.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,0.0]}},
{"name":"census_line_wire_scale1_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,1.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,0.0]}},
{"name":"census_line_wire_scale1_voidflip1","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,1.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,1.0,0.0]}},
{"name":"census_line_wire_scale1_voidflip2","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,1.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,2.0,0.0]}},
{"name":"census_line_wire_scale25_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,25.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,0.0]}},
{"name":"census_line_wire_scale25_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,25.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,0.0]}},
{"name":"census_line_wire_scale0.01_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,0.01,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,0.0]}},
{"name":"census_line_wire_scale0.01_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,0.01,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,0.0]}},
{"name":"census_wire_scale1_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,1.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,1.0]}},
{"name":"census_wire_scale1_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,1.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,1.0]}},
{"name":"census_wire_scale1_voidflip1","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,1.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,1.0,1.0]}},
{"name":"census_wire_scale1_voidflip2","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,1.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,2.0,1.0]}},
{"name":"census_wire_scale25_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,25.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,1.0]}},
{"name":"census_wire_scale25_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,25.0,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,1.0]}},
{"name":"census_wire_scale0.01_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,0.01,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,1.0]}},
{"name":"census_wire_scale0.01_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,1,0,0,0.01,0,1,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,1.0]}},
{"name":"census_plane_face_scale1_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,4.0]}},
{"name":"census_plane_face_scale1_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,4.0]}},
{"name":"census_plane_face_scale1_voidflip1","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,1.0,4.0]}},
{"name":"census_plane_face_scale1_voidflip2","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,2.0,4.0]}},
{"name":"census_plane_face_scale25_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,4.0]}},
{"name":"census_plane_face_scale25_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,4.0]}},
{"name":"census_plane_face_scale0.01_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,4.0]}},
{"name":"census_plane_face_scale0.01_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,4.0]}},
{"name":"census_patch_sheet_scale1_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,5.0]}},
{"name":"census_patch_sheet_scale1_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,5.0]}},
{"name":"census_patch_sheet_scale1_voidflip1","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,1.0,5.0]}},
{"name":"census_patch_sheet_scale1_voidflip2","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,2.0,5.0]}},
{"name":"census_patch_sheet_scale25_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,5.0]}},
{"name":"census_patch_sheet_scale25_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,5.0]}},
{"name":"census_patch_sheet_scale0.01_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,5.0]}},
{"name":"census_patch_sheet_scale0.01_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,5.0]}},
{"name":"census_box_scale1_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,6.0]}},
{"name":"census_box_scale1_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,6.0]}},
{"name":"census_box_scale1_voidflip1","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,1.0,6.0]}},
{"name":"census_box_scale1_voidflip2","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,2.0,6.0]}},
{"name":"census_box_scale25_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,6.0]}},
{"name":"census_box_scale25_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,6.0]}},
{"name":"census_box_scale0.01_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,6.0]}},
{"name":"census_box_scale0.01_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,6.0]}},
{"name":"census_empty_scale1_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,7.0]}},
{"name":"census_empty_scale1_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,7.0]}},
{"name":"census_empty_scale1_voidflip1","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,1.0,7.0]}},
{"name":"census_empty_scale1_voidflip2","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,2.0,7.0]}},
{"name":"census_empty_scale25_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,7.0]}},
{"name":"census_empty_scale25_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,7.0]}},
{"name":"census_empty_scale0.01_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,7.0]}},
{"name":"census_empty_scale0.01_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,7.0]}},
{"name":"census_face_with_vertex_loops_scale1_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,11.0]}},
{"name":"census_face_with_vertex_loops_scale1_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,11.0]}},
{"name":"census_face_with_vertex_loops_scale1_voidflip1","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,1.0,11.0]}},
{"name":"census_face_with_vertex_loops_scale1_voidflip2","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,2.0,11.0]}},
{"name":"census_face_with_vertex_loops_scale25_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,11.0]}},
{"name":"census_face_with_vertex_loops_scale25_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,11.0]}},
{"name":"census_face_with_vertex_loops_scale0.01_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,11.0]}},
{"name":"census_face_with_vertex_loops_scale0.01_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,1,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,11.0]}},
{"name":"census_face_with_hole_scale1_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,12.0]}},
{"name":"census_face_with_hole_scale1_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,12.0]}},
{"name":"census_face_with_hole_scale1_voidflip1","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,1.0,12.0]}},
{"name":"census_face_with_hole_scale1_voidflip2","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,2.0,12.0]}},
{"name":"census_face_with_hole_scale25_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,12.0]}},
{"name":"census_face_with_hole_scale25_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,12.0]}},
{"name":"census_face_with_hole_scale0.01_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,12.0]}},
{"name":"census_face_with_hole_scale0.01_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,12.0]}},
{"name":"census_box_minus_inner_box_scale1_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,14.0]}},
{"name":"census_box_minus_inner_box_scale1_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,14.0]}},
{"name":"census_box_minus_inner_box_scale1_voidflip1","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,1.0,14.0]}},
{"name":"census_box_minus_inner_box_scale1_voidflip2","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,2.0,14.0]}},
{"name":"census_box_minus_inner_box_scale25_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,14.0]}},
{"name":"census_box_minus_inner_box_scale25_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,14.0]}},
{"name":"census_box_minus_inner_box_scale0.01_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,14.0]}},
{"name":"census_box_minus_inner_box_scale0.01_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,14.0]}},
{"name":"census_two_disjoint_boxes_scale1_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,15.0]}},
{"name":"census_two_disjoint_boxes_scale1_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,15.0]}},
{"name":"census_two_disjoint_boxes_scale1_voidflip1","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,1.0,15.0]}},
{"name":"census_two_disjoint_boxes_scale1_voidflip2","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,2.0,15.0]}},
{"name":"census_two_disjoint_boxes_scale25_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,15.0]}},
{"name":"census_two_disjoint_boxes_scale25_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,15.0]}},
{"name":"census_two_disjoint_boxes_scale0.01_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,15.0]}},
{"name":"census_two_disjoint_boxes_scale0.01_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,15.0]}},
{"name":"census_nested_boxes_merged_scale1_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,16.0]}},
{"name":"census_nested_boxes_merged_scale1_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,16.0]}},
{"name":"census_nested_boxes_merged_scale1_voidflip1","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,1.0,16.0]}},
{"name":"census_nested_boxes_merged_scale1_voidflip2","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,1.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,2.0,16.0]}},
{"name":"census_nested_boxes_merged_scale25_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,16.0]}},
{"name":"census_nested_boxes_merged_scale25_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,25.0,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,16.0]}},
{"name":"census_nested_boxes_merged_scale0.01_voidkeep0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,0.0,1e-05,0.0,16.0]}},
{"name":"census_nested_boxes_merged_scale0.01_voidflip0","inputs":{"op":27,"data":[0.5,-0.25,1.0,0,0,0,0.01,0,0,1,1,0.3,0.4,0.5,0.5,0,0,0,1.0,1e-05,0.0,16.0]}}
]
}
+48 -1
View File
@@ -7,6 +7,7 @@
#include "sc_edgeuse_graph.h"
#include <SmApiQueries.h>
#include <SmApiPrimitives.h>
#include <SmApiBrep.h>
#include <SmCircle.h>
#include <SmEllipse.h>
#include <SmSurfOfRevolution.h>
@@ -129,7 +130,7 @@ namespace
}
SC_EXPORT int32_t sc_query_api_queries_eval(int32_t op, const double* a, int64_t n, double* out, int64_t cap, int64_t* len)
{
if (!a || (n != 22 && !(n == 26 && (op == 7 || op == 8))) || op<0 || op>26)return SC_ERR_ARG;
if (!a || (n != 22 && !(n == 26 && (op == 7 || op == 8))) || op<0 || op>27)return SC_ERR_ARG;
SC_TRY
const auto& ctx = the_context();
std::vector<double> o;
@@ -238,6 +239,30 @@ SC_EXPORT int32_t sc_query_api_queries_eval(int32_t op, const double* a, int64_t
for (ULONG i = 0; i < curves.GetSize(); ++i)
if (!curves[i]->GetOwner())delete curves[i];
}
else if (kind >= 14 && kind <= 16)
{
// Nested and disjoint boxes for the material census: 14 a box minus an inner
// box (a void cavity), 15 two disjoint boxes merged, 16 an inner box merged
// into an outer one.
delete b.brep;
b.brep = nullptr;
SmBrep* second = nullptr;
status = SmApiCreateBox(SmPoint3d(a[0], a[1], a[2]), a[6], a[6], a[6], b.brep);
if (status == SM_SUCCESS)
{
const SmPoint3d at = kind == 15?SmPoint3d(a[0]+2*a[6], a[1], a[2])
:SmPoint3d(a[0]+0.25*a[6], a[1]+0.25*a[6], a[2]+0.25*a[6]);
const double size = kind == 15?a[6]:0.5*a[6];
status = SmApiCreateBox(at, size, size, size, second);
}
if (status == SM_SUCCESS)
{
SmBrep* result = nullptr;
status = kind == 14?SmApiBooleanDifference(b.brep, second, result)
:SmApiBooleanMerge(b.brep, second, result);
if (status == SM_SUCCESS)b.brep = result;
}
}
if (status != SM_SUCCESS || !b.brep)return SC_ERR_ARG;
Graph g;
walk(b.brep, g);
@@ -418,6 +443,28 @@ SC_EXPORT int32_t sc_query_api_queries_eval(int32_t op, const double* a, int64_t
if (status == SM_SUCCESS)o.push_back(yes?1:0);
break;
}
case 27:
{
// a[18] != 0 rewrites the void flags (FALSE, TRUE, UNSURE in turn,
// starting at a[20]) along the region list before the census
if (a[18] != 0)
{
SmTArray<SmRegion*> rs;
bp->GetRegions(rs);
const SmBoolean flags[3] = {FALSE, TRUE, UNSURE};
for (ULONG i = 0;i<rs.GetSize();++i)
rs[i]->SetIsVoid(flags[(i+(size_t)a[20])%3]);
}
long solids = -1, voids = -1;
status = SmApiBrepMaterialCensus(bp, solids, voids);
o.push_back(st(status));
if (status == SM_SUCCESS)
{
o.push_back((double)solids);
o.push_back((double)voids);
}
break;
}
case 15:case 16:case 20:status = op == 15?SmApiBrepBoundingBox(bp, a[15]?TRUE:FALSE, lo, hi):op == 16?SmApiFaceBoundingBox(f, a[15]?TRUE:FALSE, lo, hi):SmApiEdgeBoundingBox(e, a[15]?TRUE:FALSE, lo, hi);
o.push_back(st(status));
if (status == SM_SUCCESS)
File diff suppressed because one or more lines are too long