Skip to content

Modeling Data - GProp_SelGProps and GProp_VelGProps compute the properties of a gp_Cone wrongly - #1599

Open
gsdali wants to merge 1 commit into
Open-Cascade-SAS:IRfrom
SecondMouseAU:fix/gprop-cone-properties
Open

gsdali wants to merge 1 commit into
Open-Cascade-SAS:IRfrom
SecondMouseAU:fix/gprop-cone-properties

Conversation

@gsdali

@gsdali gsdali commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

GProp_SelGProps::Perform(const gp_Cone&, ...) and GProp_VelGProps::Perform(const
gp_Cone&, ...) return a wrong mass, a wrong matrix of inertia and, for the
solid, a wrong centre of mass. Neither class has a caller in the tree, so
nothing has exercised them. With P(u, v) = Loc + (R + v sin a)(cos u X + sin u Y)

  • v cos a Z, r = R + v sin a and z = v cos a, the surface element is r dv du and
    the solid is the volume swept between the axis and the patch, dV = rho drho du dz
    (the convention the gp_Cylinder and gp_Sphere overloads of GProp_VelGProps use).

GProp_SelGProps, area:

dim = (Alpha2 - Alpha1) * Cnt * (Z2 - Z1) * Auxi1;

|dP/du ^ dP/dv| is r, so Auxi1 = R + (Z2 + Z1) sin a / 2 already is the area per
unit of (Alpha2 - Alpha1)(Z2 - Z1) and the Cnt factor has no term to come from.
The gp_Cylinder overload beside it has no such factor, which is why the cone
reads cos(a) times the area and the two disagree as a goes to 0.

GProp_VelGProps, volume:

dim = ZZ * (Alpha2 - Alpha1) * Auxi1 / 2.; // ZZ carries sin a

goes to zero as the cone becomes the cylinder, where the gp_Cylinder overload
gives (Alpha2 - Alpha1) R^2 (Z2 - Z1) / 2. The frustum is
(Alpha2 - Alpha1) cos a (Z2 - Z1)(R1^2 + R1 R2 + R2^2) / 6 with R1 = R + Z1 sin a
and R2 = R + Z2 sin a, which is pi H (R1^2 + R1 R2 + R2^2) / 3 over a full turn
and the cylinder overload at a = 0.

Both, matrix of inertia and centre of mass. Dm, the matrix of inertia about the
location of the cone, is built from closed forms that do not integrate to the
moments. For the surface Dm(3,3) is cos a sin a times the second moment about
the axis, ISn2 repeats ICn2 with a plus where the sine integral has a minus, and
IZ2, ICnSn, ICnz and ISnz are other polynomials. For the solid IR2 is a four
term cubic over 4 with a spurious sin a where the moment is a five term quartic
over 20, with the same defects in the other entries. The x and y coordinate of
the surface centre of mass uses sin a Auxi2 where the quadratic term is
sin^2 a Auxi2 (a full turn hides it), and the solid takes the centre of mass of
the lateral surface in all three coordinates. inertia is then assembled from the
Jacobi decomposition as gp_Mat(rows of lambda_i * v_i), which is diag(lambda) V^T
and not V diag(lambda) V^T, and Dm is added to the Huyghens term of the centre of
mass as if it were already about it.

  • Drop the cos a factor from the GProp_SelGProps cone area
  • Replace the GProp_VelGProps cone volume by the frustum
  • Compute every entry of Dm, and the solid centre of mass, from the integrals
  • Assemble inertia = P Dm P^T - H(g, Location) + H(g, loc), with P the columns of
    the axes of the cone and H the GProp::HOperator term. The mass is the one above
  • Add GProp_SelGPropsTest and GProp_VelGPropsTest. The reference is an independent
    Gauss-Legendre integral over the parameter space of the cone (math::OrderedGaussPointsAndWeights,
    16 nodes, a triple integral for the solid) plus the closed form of the area and
    the frustum, and the cylinder limit for the volume. Mass, centre of mass, matrix
    of inertia about the centre of mass and a moment about an axis through a
    non-origin location are compared for six cones (semi-angles pi/3, pi/6, pi/12,
    -pi/6 and -pi/4, full and partial turns) in an untilted frame and in a tilted,
    translated one

The cylinder, sphere and torus overloads are not touched. The same integral
probe fails them too: for the full gp_Cylinder surface of radius 5 and height 10
Dm(3,3) reads 314.159, which is 2 pi R H, where the second moment about the axis
is 2 pi R^3 H. That is a separate defect cluster and is left for another change.

Measured on a local build of IR (0089343), gp_Cone(gp::XOY(), pi/6, 5) over
u in [0, 2 pi], v in [0, 10]:

quantity before after closed form or integral
surface mass 408.10485695269909 471.23889803846896 471.23889803846896
solid mass 2040.524284763495 1587.0744437049409 1587.0744437049404
surface Dm(3,3) 12753.276779771842 29452.43112740431 29452.431127404328
solid centre of mass, z 4.81125224325 5.25801138012 5.25801138012

The solid at semi-angles 1e-3, 1e-6 and 1e-9 reads 3.14473214923, 0.00314159580
and 0.00000314159 before and 786.96961317468, 785.39973419443 and
785.39816496824 after, against the cylinder's 785.39816339744823. A probe over eight
cones in the two frames (64 checks: mass, centre of mass, matrix of inertia and the
oblique axis moment) fails 64 before and 0 after, the largest relative deviation
4e-14.

Verified against a local build of IR:

  • Without the source change the five new tests fail: surface and solid mass,
    the cylinder limit of the volume, and both quadrature comparisons. With it
    they pass, and the GProp and BRepGProp suites pass (33 tests)
  • The full GTest suite reports 8364 tests, 8357 passed, 7 skipped by the tests
    themselves, none failed, in a build with FoundationClasses, ModelingData and
    ModelingAlgorithms
  • Both changed files compile without warnings under g++ -Wall -Wextra -Werror
  • clang-format 18.1.8 with the repository .clang-format reports no violation on any
    of the four files, and none contains a non-ASCII character
  • Nothing else in the tree calls either class

…rties of a gp_Cone wrongly

The cone overloads of GProp_SelGProps and GProp_VelGProps return a wrong mass,
a wrong matrix of inertia and, for the solid, a wrong centre of mass.

- Drop the cos(a) factor from the GProp_SelGProps cone area
- Replace the GProp_VelGProps cone volume by the frustum, which reduces to the
  gp_Cylinder volume at a = 0
- Compute every entry of Dm and the solid centre of mass from the integrals
- Assemble inertia as P Dm P^T - H(g, Location) + H(g, loc)
- Add GProp_SelGPropsTest and GProp_VelGPropsTest, checked against an independent
  Gauss-Legendre integral over the parameter space of the cone
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant