CadQuery / OCP

Apache License 2.0
102 stars 29 forks source link

Retrieving weights of a rational BSpline surface causes crashing #137

Open GabrielJMS opened 10 months ago

GabrielJMS commented 10 months ago

The code crashes when we try to access Weigths() method from Geom_BSplineSurface twice or more times.

Searching in the internet I found that they had the same behavior in pyOCCT.

see: https://github.com/trelau/pyOCCT/issues/80 https://github.com/trelau/pyOCCT/pull/84/files#diff-7206418f088df5bcafb72d1a2ef6c5c4773fdd0f0c7bb14be7f5dbfcd4d606e1

from OCP.Geom import Geom_BSplineSurface, Geom_RectangularTrimmedSurface, Geom_SphericalSurface
from OCP.GeomConvert import GeomConvert
from OCP.TColStd import TColStd_Array2OfReal
from OCP.gp import gp_Ax3

# Prepare some geometry to initialize a rational BSpline surface.
spherical_surface = Geom_SphericalSurface(gp_Ax3(), 1.)
surface = Geom_RectangularTrimmedSurface(spherical_surface, 0., 1., 0., 1.)

# Second loop won't be executed due to the crash.
reproduce = True
for k in range(2):
    bspline_surface = GeomConvert.SurfaceToBSplineSurface_s(surface)
    if reproduce:  # causes crashing
        weights = bspline_surface.Weights()
    else:  # workaround
        bspline_surface.Weights(weights := TColStd_Array2OfReal(1, bspline_surface.NbUPoles(), 1, bspline_surface.NbVPoles()))
    values = [[weights.Value(i, j) for j in range(1, 1 + weights.NbColumns())] for i in range(1, 1 + weights.NbRows())] # not essential
    print(k)

I don't know if it's a bug or it's an expected behavior.

whophil commented 10 months ago

I can reproduce, and I have encountered this before. Yet another workaround is to use bspline_surface.Weight(i, j) directly, e.g.

        values = [[bspline_surface.Weight(i, j) for j in range(1, 1 + bspline_surface.NbUPoles())] for i in range(1, 1 + bspline_surface.NbVPoles())]