star-cad

Geometric operators for computer-aided design
git clone git://git.meso-star.fr/star-cad.git
Log | Files | Refs | README | LICENSE

commit 632e64b00f456d80a36c384f6334d6a49d5be1a4
parent db7bfdf1058db9ac8b05308281a218fdd679ac20
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Tue, 29 Jul 2025 13:47:24 +0200

Change the way get_centerofmass works

Now returns the true center of mass as a single point. Used to return a
list of centers, one by geometry's component.
The signature was changed accordingly.

Diffstat:
Msrc/scad.h | 6++----
Msrc/scad_geometry.c | 41++++++++++++++++++++++++++++++++---------
2 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/src/scad.h b/src/scad.h @@ -386,13 +386,11 @@ scad_geometry_get_mass (struct scad_geometry* geometry, double* mass); -/* Get the center of mass of the various components of geometry `geometry'. - * Note that `center' must be allocated by the caller with enough room for (at - * least) 3 times the count of geom (scad_geometry_get_count) doubles. */ +/* Get the center of mass of geometry `geometry' in `center'. */ SCAD_API res_T scad_geometry_get_centerofmass (struct scad_geometry* geometry, - double* center); + double center[3]); /* Get the `closest' point on geometry `geometry' from point `from'. * Return the `closest' point and its `distance'. diff --git a/src/scad_geometry.c b/src/scad_geometry.c @@ -807,10 +807,13 @@ error: res_T scad_geometry_get_centerofmass (struct scad_geometry* geom, - double* center) + double center[3]) { res_T res = RES_OK; - size_t i = 0; + double *centers = NULL, *masses = NULL; + size_t i = 0, count; + struct mem_allocator* allocator; + int ierr; if(!geom || !center) { res = RES_BAD_ARG; @@ -819,19 +822,39 @@ scad_geometry_get_centerofmass ERR(check_device(FUNC_NAME)); - for(i = 0; i < geom->gmsh_dimTags_n; i += 2) { - double x, y, z; - int ierr = 0; + ASSERT(geom->gmsh_dimTags_n % 2 == 0); + count = geom->gmsh_dimTags_n / 2; + if(count == 1) { int dim = geom->gmsh_dimTags[i]; int tag = geom->gmsh_dimTags[i + 1]; - gmshModelOccGetCenterOfMass(dim, tag, &x, &y, &z, &ierr); + gmshModelOccGetCenterOfMass(dim, tag, center, center+1, center+2, &ierr); ERR(gmsh_err_to_res_T(ierr)); - center[3*i] = x; - center[3*i + 1] = y; - center[3*i + 2] = z; + } else { + double c[3] = { 0, 0, 0 }, tmp[3], m = 0; + allocator = get_device()->allocator; + centers = MEM_ALLOC(allocator, count * 3 * sizeof(*centers)); + masses = MEM_ALLOC(allocator, count * sizeof(*masses)); + if(!centers || !masses) { + res = RES_MEM_ERR; + goto error; + } + for(i = 0; i < count; i++) { + int dim = geom->gmsh_dimTags[2*i]; + int tag = geom->gmsh_dimTags[2*i + 1]; + gmshModelOccGetCenterOfMass(dim, tag, + centers+3*i, centers+3*i+1, centers+3*i+2, &ierr); + ERR(gmsh_err_to_res_T(ierr)); + gmshModelOccGetMass(dim, tag, masses+i, &ierr); + ERR(gmsh_err_to_res_T(ierr)); + d3_add(c, c, d3_muld(tmp, centers+3*i, masses[i])); + m += masses[i]; + } + d3_muld(center, c, 1/m); } exit: + if(centers) MEM_RM(allocator, centers); + if(masses) MEM_RM(allocator, masses); return res; error: goto exit;