forked from 1b-agent/opencadstudio-upstream
feat(model): kernel a82f17d — MASSPROP from B-rep, curved OFFSET/FILLET
- Pins: codec 8189f83, kernel a82f17d, graph d3558bb (all manifests and the python plugin lock). - MASSPROP reports volume, centroid, inertia, products, radii of gyration and principal moments of 3D solids and bodies from their B-rep (exact where analytic, else from a fine mesh). - OFFSET of ellipses and splines through the kernel's curve offset. - FILLET between circles, ellipses and splines through the kernel's curve-curve fillet, trimming arcs and open splines to the tangents. The kernel bump brings the DWG ACIS audit fixes: slices, booleans and press/pull on cones, slanted cylinder sections, survey coordinates, spline walls and touching parts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d0e4f4097d
commit
aa0b87108c
31 files changed
+404
-109
No files matched your search
@@ -1114,6 +1114,63 @@ impl OpenCADStudio {
|
||||
for (handle, _) in &selected {
|
||||
if let Some(entity) = self.tabs[i].scene.document.get_entity(*handle) {
|
||||
use crate::entities::traits::EntityTypeOps;
|
||||
// A solid's properties come from its B-rep: exact
|
||||
// where the kernel knows the shape, a fine mesh
|
||||
// otherwise — not the display mesh.
|
||||
let acis = match entity {
|
||||
codec::EntityType::Solid3D(solid) => Some(&solid.acis_data),
|
||||
codec::EntityType::Body(body) => Some(&body.acis_data),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(acis) = acis {
|
||||
let properties = crate::scene::convert::solid3d_tess::kernel_acis_body(acis)
|
||||
.and_then(|body| kernel::brep::mass_properties(&body));
|
||||
let Some(p) = properties else {
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"MASSPROP: {} has no closed body to measure.",
|
||||
crate::entities::names::dxf_name(entity),
|
||||
).as_ref());
|
||||
continue;
|
||||
};
|
||||
let [x, y, z] = p.centroid;
|
||||
let [ix, iy, iz] = p.moment_of_inertia;
|
||||
let [pxy, pyz, pzx] = p.product_of_inertia;
|
||||
let [rx, ry, rz] = p.radii_of_gyration;
|
||||
let [i1, i2, i3] = p.principal_moments;
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{} Volume={:.4} Centroid=({:.4},{:.4},{:.4})",
|
||||
crate::entities::names::dxf_name(entity),
|
||||
p.volume,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Moments of inertia X={:.4} Y={:.4} Z={:.4}",
|
||||
ix,
|
||||
iy,
|
||||
iz,
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Products of inertia XY={:.4} YZ={:.4} ZX={:.4}",
|
||||
pxy,
|
||||
pyz,
|
||||
pzx,
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Radii of gyration X={:.4} Y={:.4} Z={:.4}",
|
||||
rx,
|
||||
ry,
|
||||
rz,
|
||||
).as_ref());
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"Principal moments about centroid I={:.4} J={:.4} K={:.4}",
|
||||
i1,
|
||||
i2,
|
||||
i3,
|
||||
).as_ref());
|
||||
continue;
|
||||
}
|
||||
if let Some(props) = entity.mass_props() {
|
||||
self.command_line.push_output(crate::tf!(
|
||||
"{} Area={:.4} Perimeter={:.4} Centroid=({:.4},{:.4})",
|
||||
|
||||
Reference in new issue
Block a user