cadquery
cadquery copied to clipboard
Weird "Fillets requires that edges be selected" exception
To Reproduce
I'm trying to build some gridfinity stuff, therefore I'm trying to to build the baseplate in CadQuery. However I'm getting some weird Fillets requires that edges be selected-exception.
(The following code are cells from a Jupyter-notebook, where each ##### marks a different cell)
rounding_diameter = 7_500
outer_width = 42_000
layer0_inner = 42_000 - ((2_150 + 700) * 2)
layer0_height = 700
layer0_rounding_diameter_inner = rounding_diameter - (outer_width - layer0_inner)
layer1_inner = 42_000 - (2_150 * 2)
layer1_height = 1_800
layer1_rounding_diameter_inner = rounding_diameter - (outer_width - layer1_inner)
layer2_inner = 42_000 - (2_150 * 2)
layer2_height = 1_900
layer2_rounding_diameter_inner = rounding_diameter - (outer_width - layer2_inner)
#####
from cadquery import Workplane
object = Workplane()\
.box(outer_width, outer_width, layer0_height, centered=[True, True, False])\
.faces(">Z")\
.workplane(invert=True)\
.box(layer0_inner, layer0_inner, layer0_height, centered=[True, True, False], combine="cut")\
.edges("|Z and (>X or <X)")\
.fillet(rounding_diameter / 2)\
.edges("|Z")\
.fillet(layer0_rounding_diameter_inner / 2)
display(object)
#####
object = object\
.faces(">Z")\
.workplane()\
.box(outer_width, outer_width, layer1_height, centered=[True, True, False])\
.faces(">Z")\
.workplane(invert=True)\
.box(layer1_inner, layer1_inner, layer1_height, centered=[True, True, False], combine="cut")\
.edges("|Z and (>X or <X)")\
.fillet(rounding_diameter / 2)\
.edges("|Z")\
.fillet(layer1_rounding_diameter_inner / 2)
display(object)
#####
object = object\
.faces(">Z")\
.workplane()\
.box(outer_width, outer_width, layer2_height, centered=[True, True, False])\
.faces(">Z")\
.workplane(invert=True)\
.box(layer2_inner, layer2_inner, layer2_height, centered=[True, True, False], combine="cut")\
.edges("|Z and (>X or <X)")\
.fillet(rounding_diameter / 2)\ # <--- THIS IS THE LINE TRIGGERING THE EXCEPTION
.edges("|Z")\
.fillet(layer2_rounding_diameter_inner / 2)
display(object)
The weird thing is: If I change the rounding_diameter / 2 to either rounding_diameter / 2.00001 OR rounding_diameter / 1.99999, it does not throw... for me this looks like some kind of floating point error; but then I'm a noob regarding CAD-kernels, and I'm pretty confused that it works with a deviation in both directions.
Also I'm a newby with CadQuery, so please bear with me if I'm completely misunderstanding some concepts here 🙈
Backtrace
{
"name": "StdFail_NotDone",
"message": "BRep_API: command not done",
"stack": "---------------------------------------------------------------------------
StdFail_NotDone Traceback (most recent call last)
Cell In[117], line 9
1 object = object\\
2 .faces(\">Z\")\\
3 .workplane()\\
4 .box(outer_width, outer_width, layer2_height, centered=[True, True, False])\\
5 .faces(\">Z\")\\
6 .workplane(invert=True)\\
7 .box(layer2_inner, layer2_inner, layer2_height, centered=[True, True, False], combine=\"cut\")\\
8 .edges(\"|Z and (>X or <X)\")\\
----> 9 .fillet(rounding_diameter / 2)\\
10 .edges(\"|Z\")\\
11 .fillet(layer2_rounding_diameter_inner / 2)
13 display(object)
File /usr/local/lib/python3.11/dist-packages/cadquery/cq.py:1304, in Workplane.fillet(self, radius)
1301 if len(edgeList) < 1:
1302 raise ValueError(\"Fillets requires that edges be selected\")
-> 1304 s = solid.fillet(radius, edgeList)
1305 return self.newObject([s.clean()])
File /usr/local/lib/python3.11/dist-packages/cadquery/occ_impl/shapes.py:2780, in Mixin3D.fillet(self, radius, edgeList)
2777 for e in nativeEdges:
2778 fillet_builder.Add(radius, e)
-> 2780 return self.__class__(fillet_builder.Shape())
StdFail_NotDone: BRep_API: command not done"
}
Environment
OS: VSCode dev container running Debian on M1Pro-MacBook Pro:
FROM mcr.microsoft.com/devcontainers/base:debian
ENV APT_PACKAGES libgl1 libnlopt0 libnlopt-cxx0 python3 python3-dev python3-nlopt python3-pip
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update \
&& apt-get upgrade --yes \
&& apt-get install --yes --no-install-recommends ${APT_PACKAGES} \
&& apt-get autoremove --yes \
&& apt-get clean
RUN pip install --break-system-packages \
ipykernel
# Manually install top-level dependencies of `cadquery` except `nlopt`
RUN pip install --break-system-packages \
casadi \
ezdxf \
multimethod==1.9.1 \
nptyping==2.0.1 \
path \
typish \
https://github.com/CadQuery/ocp-build-system/releases/download/7.7.2.0/cadquery_ocp-7.7.2-cp311-cp311-manylinux_2_35_aarch64.whl
# Install `cadquery` without automatic dependency resolution
RUN pip install --break-system-packages --no-deps \
cadquery
Also see my attached workspace if it is any use: Gridfinity.zip
It looks like you are creating rounded walls. In general, it's recommended to create this kind of shape in 2D. I don't know the root cause of the issue with your code, however, I'd suggest to try moving the fillet to 2D with something like this:
import cadquery as cq
def make_wall(w1, w2, d1, d2) -> cq.Sketch:
return (
cq.Sketch()
.rect(w1, w1, tag="outer")
.rect(w2, w2, mode="s", tag="inner")
.vertices(tag="outer")
.fillet(d1 / 2)
.vertices(tag="inner")
.fillet(d2 / 2)
)
res = (
cq.Workplane()
.placeSketch(make_wall(50, 40, 10, 5))
.extrude(10)
.faces(">Z")
.workplane()
.placeSketch(make_wall(50, 45, 10, 5))
.extrude(5)
)
Thanks, will try it like this instead. Please feel free to close this if it is out-of-scope or probably a problem with the underlying CAD-kernel 😊
Yes AFAICT it's a kernel issue. Here is a minimal example. It fails with same error as original code.:
import cadquery as cq
b0 = cq.Workplane().box(100, 100, 5).edges(">XY").fillet(10)
b1 = (
b0.faces(">Z")
.box(100, 100, 5, centered=[True, True, False])
.edges(">XY")
.fillet(10)
)
A workaround could be to set combine to False in b1, then union after the b1 fillet
b1 = (
b0.faces(">Z")
.box(100, 100, 5, centered=[True, True, False], combine=False)
.edges(">XY")
.fillet(10)
)
b1 = b1.union(b0)
... or move the fillet to 2D as in the previous example.