fix: correct OCP API usage for mesh, bounding box, and volume

- Fix BRep_Tool.Triangulation_s to use TopoDS.Face_s for face casting
- Fix BRepBndLib.AddClose_s import and usage
- Fix BRepGProp.VolumeProperties_s and SurfaceProperties_s imports
- Fix _get_shape to handle Workplane objects stored in shape attribute
- Fix OCCSketchEntity to properly inherit from SketchEntity
- Update pyproject.toml dependency versions
This commit is contained in:
bklronin
2026-03-14 08:52:45 +01:00
parent fe23ca610c
commit 8c6a413137
3 changed files with 81 additions and 109 deletions
+50 -30
View File
@@ -47,6 +47,8 @@ class OCGeometryKernel(GeometryKernel):
def _get_shape(self, obj: GeometryObject) -> Any:
"""Extract the underlying OCC shape from a GeometryObject."""
import cadquery as cq
if isinstance(obj, OCCGeometryObject):
if obj._cadquery_obj is not None:
shape = obj._cadquery_obj.val()
@@ -54,6 +56,11 @@ class OCGeometryKernel(GeometryKernel):
return shape.wrapped
return shape
if obj.shape is not None:
if isinstance(obj.shape, cq.Workplane):
shape = obj.shape.val()
if hasattr(shape, "wrapped"):
return shape.wrapped
return shape
if hasattr(obj.shape, "wrapped"):
return obj.shape.wrapped
return obj.shape
@@ -76,15 +83,19 @@ class OCGeometryKernel(GeometryKernel):
"""Create a 2D line segment."""
import cadquery as cq
wire = cq.Workplane("XY").moveTo(start.x, start.y).lineTo(end.x, end.y)
return OCCGeometryObject(wire.val(), {"type": "line"})
wp = cq.Workplane("XY").moveTo(start.x, start.y).lineTo(end.x, end.y)
obj = OCCGeometryObject(wp.val(), {"type": "line"})
obj._cadquery_obj = wp
return obj
def create_circle(self, center: Point2D, radius: float) -> GeometryObject:
"""Create a 2D circle."""
import cadquery as cq
wire = cq.Workplane("XY").center(center.x, center.y).circle(radius)
return OCCGeometryObject(wire.val(), {"type": "circle"})
wp = cq.Workplane("XY").center(center.x, center.y).circle(radius)
obj = OCCGeometryObject(wp.val(), {"type": "circle"})
obj._cadquery_obj = wp
return obj
def create_arc(
self, center: Point2D, radius: float, start_angle: float, end_angle: float
@@ -121,7 +132,9 @@ class OCGeometryKernel(GeometryKernel):
wp = wp.lineTo(pt.x, pt.y)
wp = wp.close()
return OCCGeometryObject(wp.val(), {"type": "polygon"})
obj = OCCGeometryObject(wp.val(), {"type": "polygon"})
obj._cadquery_obj = wp
return obj
def create_rectangle(
self, width: float, height: float, center: Optional[Point2D] = None
@@ -132,8 +145,10 @@ class OCGeometryKernel(GeometryKernel):
cx = center.x if center else 0
cy = center.y if center else 0
wire = cq.Workplane("XY").center(cx, cy).rect(width, height)
return OCCGeometryObject(wire.val(), {"type": "rectangle"})
wp = cq.Workplane("XY").center(cx, cy).rect(width, height)
obj = OCCGeometryObject(wp.val(), {"type": "rectangle"})
obj._cadquery_obj = wp
return obj
def extrude(
self,
@@ -147,20 +162,17 @@ class OCGeometryKernel(GeometryKernel):
cq_obj = self._get_cq_obj(sketch)
if symmetric:
half_height = height / 2
if isinstance(cq_obj, cq.Workplane):
solid = cq_obj.extrude(half_height, both=True)
if isinstance(cq_obj, cq.Workplane):
if symmetric:
solid = cq_obj.extrude(height / 2, both=True)
else:
face = cq.Face.makeFromWires(cq_obj)
solid = face.extrude(cq.Vector(0, 0, half_height) * 2)
else:
if isinstance(cq_obj, cq.Workplane):
solid = cq_obj.extrude(height)
else:
wp = cq.Workplane("XY").add(cq_obj)
if symmetric:
solid = wp.extrude(height / 2, both=True)
else:
face = cq.Face.makeFromWires(cq_obj)
dir_vec = cq.Vector(*direction).normalized() * height
solid = face.extrude(dir_vec)
solid = wp.extrude(height)
return OCCGeometryObject(solid, {"type": "extrusion"})
@@ -562,7 +574,14 @@ class OCGeometryKernel(GeometryKernel):
"""Get triangulated mesh for rendering."""
import cadquery as cq
shape = self._get_shape(body)
cq_obj = self._get_cq_obj(body)
if isinstance(cq_obj, cq.Workplane):
shape = cq_obj.val()
if hasattr(shape, "wrapped"):
shape = shape.wrapped
else:
shape = self._get_shape(body)
if hasattr(shape, "tessellate"):
vertices, faces = shape.tessellate(tolerance)
@@ -572,19 +591,20 @@ class OCGeometryKernel(GeometryKernel):
from OCP.TopExp import TopExp_Explorer
from OCP.TopAbs import TopAbs_FACE
from OCP.BRep import BRep_Tool
from OCP.Poly import Poly_Triangulation
from OCP.TopLoc import TopLoc_Location
mesh = BRepMesh_IncrementalMesh(shape, tolerance)
mesh = BRepMesh_IncrementalMesh(shape, tolerance, False, 0.5, False)
mesh.Perform()
vertices_list: List[List[float]] = []
faces_list: List[List[int]] = []
vertex_offset = 0
from OCP.TopoDS import TopoDS
explorer = TopExp_Explorer(shape, TopAbs_FACE)
while explorer.More():
face = explorer.Current()
face = TopoDS.Face_s(explorer.Current())
location = TopLoc_Location()
triangulation = BRep_Tool.Triangulation_s(face, location)
@@ -673,10 +693,10 @@ class OCGeometryKernel(GeometryKernel):
shape = self._get_shape(body)
from OCP.Bnd import Bnd_Box
from OCP.BRepBndLib import BRepBndLib_AddClose
from OCP.BRepBndLib import BRepBndLib
bbox = Bnd_Box()
BRepBndLib_AddClose(shape, bbox)
BRepBndLib.AddClose_s(shape, bbox)
xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get()
@@ -689,10 +709,10 @@ class OCGeometryKernel(GeometryKernel):
shape = self._get_shape(body)
from OCP.GProp import GProp_GProps
from OCP.BRepGProp import BRepGProp_VolumeProperties
from OCP.BRepGProp import BRepGProp
props = GProp_GProps()
BRepGProp_VolumeProperties(shape, props)
BRepGProp.VolumeProperties_s(shape, props)
return props.Mass()
@@ -703,10 +723,10 @@ class OCGeometryKernel(GeometryKernel):
shape = self._get_shape(body)
from OCP.GProp import GProp_GProps
from OCP.BRepGProp import BRepGProp_SurfaceProperties
from OCP.BRepGProp import BRepGProp
props = GProp_GProps()
BRepGProp_SurfaceProperties(shape, props)
BRepGProp.SurfaceProperties_s(shape, props)
return props.Mass()
@@ -717,10 +737,10 @@ class OCGeometryKernel(GeometryKernel):
shape = self._get_shape(body)
from OCP.GProp import GProp_GProps
from OCP.BRepGProp import BRepGProp_VolumeProperties
from OCP.BRepGProp import BRepGProp
props = GProp_GProps()
BRepGProp_VolumeProperties(shape, props)
BRepGProp.VolumeProperties_s(shape, props)
cg = props.CentreOfMass()
return Point3D(cg.X(), cg.Y(), cg.Z())