CadQuery / OCP

Apache License 2.0
88 stars 27 forks source link

BRep_Tool().Surface_s(Face) does not return Geom_Surface #41

Closed bragostin closed 3 years ago

bragostin commented 3 years ago

OCP.BRep.BRep_Tool().Surface_s(Face) should return a Geom_Surface handle (https://old.opencascade.com/doc/occt-7.5.0/refman/html/class_b_rep___tool.html#a351a0fe4cd421318c7f2ac042269c0ff) but instead returns the basic underlying geometry like Geom_BSplineSurface for example (https://old.opencascade.com/doc/occt-7.5.0/refman/html/class_geom___surface.html), which prevents me from using OCP.GeomLProp.GeomLProp_SLProps() after.

Could this be due to the way OCP is generated?

adam-urbanczyk commented 3 years ago

Can you post a minimum example?

bragostin commented 3 years ago

Here is a minimal example,

import cadquery as cq
from math import sqrt

from OCP.GeomLProp import GeomLProp_SLProps
from OCP.BRep import BRep_Tool

Dth = 0.2 / sqrt(2)
length = 10
gap = 2.8
step =  (gap + Dth) / 2

sect1 = cq.Workplane('XZ').tag('ref').polyline(((-Dth,0),(Dth,0),(Dth,length),(-Dth,length))).close()
sect2 = 
(
sect1.workplaneFromTagged('ref')
.transformed(offset=cq.Vector(0,0,-step))
.polyline(((-Dth-step,0),(Dth-step,0),(Dth+step,length),(-Dth+step,length)))
.close()
)
path = cq.Workplane().polyline(((0,0),(0,step)))
he1 = sect2.sweep(path, multisection=True)

face = he1.faces('>X').val().wrapped
print("face = ", face)
h_srf = BRep_Tool().Surface_s(face)
print("h_srf = ", h_srf)
curvature = GeomLProp_SLProps(h_srf)
crv_min = curvature.MinCurvature()
crv_max = curvature.MaxCurvature()
print("crv_min, crv_max = ", crv_min, crv_max)

which is supposed to calculate the curvature of the surface below.

GeomLProp_SLProps

But it returns the following error:

face =  <OCP.TopoDS.TopoDS_Face object at 0x7fb7a1df6230>
h_srf =  <OCP.Geom.Geom_Plane object at 0x7fb7a23f6570>
Traceback (most recent call last):
  File "GeomLProp_SLProps.py", line 22, in <module>
    curvature = GeomLProp_SLProps(h_srf)
TypeError: __init__(): incompatible constructor arguments. The following argument types are supported:
    1. OCP.GeomLProp.GeomLProp_SLProps(S: OCP.Geom.Geom_Surface, U: float, V: float, N: int, Resolution: float)
    2. OCP.GeomLProp.GeomLProp_SLProps(S: OCP.Geom.Geom_Surface, N: int, Resolution: float)
    3. OCP.GeomLProp.GeomLProp_SLProps(N: int, Resolution: float)

Invoked with: <OCP.Geom.Geom_Plane object at 0x7fb7a23f6570>

It is also strange that BRep_Tool().Surface_s(face) returns a Geom_Plane object while it is a 3D surface.

bragostin commented 3 years ago

I just modified the function radius_at_uv(face, u, v) line 153 of https://github.com/tpaviot/pythonocc-demos/blob/master/examples/core_geometry_geomplate.py

Using class Face() in shapes.py yields the same error:

face = he1.val().Faces()[1].wrapped
h_srf = cq.Face(face)._geomAdaptor()

and he1.val().Faces()[1] actually selects a BSpline surface.

In the source code of shapes.py:

    def _geomAdaptor(self) -> Geom_Surface:
        """
        Return the underlying geometry
        """
        return BRep_Tool.Surface_s(self.wrapped)

also shows that a Geom_Surface should be returned.

Some interesting additional information here https://dev.opencascade.org/doc/overview/html/occt__tutorial.html It looks like there has been a Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aSurface); applied at some point.

adam-urbanczyk commented 3 years ago

You are misinterpreting the error: Geom_Plane is a Geom_Surface, but you did not provide all args. The following works curvature = GeomLProp_SLProps(h_srf, 0.5, 0.5, 1, 1e-6)

See also: https://pybind11.readthedocs.io/en/stable/classes.html#inheritance-and-automatic-downcasting

bragostin commented 3 years ago

(faceplam) ... for some reason I was convinced these arguments were optional... Sorry for making you wasting your time! Thank you