Selecting edges of swept object and filleting

60 views
Skip to first unread message

Ssw

unread,
Oct 30, 2024, 10:07:49 PM10/30/24
to CadQuery
I'm trying to select faces on Z axis and then fillet edges, but |Z filter returns no faces despite >Z and <Z called separate return one face (one returns top and second bottom). Any advice on how to do it properly? 

Second thing is I want to perform multisection sweep to have different thickness where ellipse is wider. How can I do such sweep? I tried to supply rectangles with different heights but ended up with errors only.

Thanks in advance.

import cadquery as cq
import ocp_vscode as ov


radius = 23

result = cq.Workplane("XY").ellipse(radius, radius + 3)

result = (
cq.Workplane("YZ")
.center(-radius, 0)
.rect(2, 10)
.sweep(result)
)

# result = result.faces("|Z")

ov.show(result)

Lorenz

unread,
Oct 31, 2024, 9:15:59 PM10/31/24
to CadQuery
>  |Z filter returns no faces

Yes, although the result appears to contain planar faces, all of the faces are of type BSPLINE.  The "|Z" ParallelDirSelector does not work with this type of face currently.

You might workaround it by using LengthNthSelector or other selector:
# to select the inner edges on both top and bottom for fillet:
e_inner = result.edges(cq.selectors.LengthNthSelector(2))
# outer edges
e_outer = result.edges(cq.selectors.LengthNthSelector(3))
# outer top edge
e_outer_top = e_outer.edges(">>Z")

Lorenz

unread,
Oct 31, 2024, 9:39:45 PM10/31/24
to CadQuery
Try something like this for the sweep (CQ master):

import cadquery as cq
from cadquery.occ_impl.shapes import sweep

radius = 23
path = cq.Workplane("XY").ellipse(radius, radius + 3)

# create profiles
prof1 = cq.Workplane("YZ").center(-radius, 0).rect(2, 10)
prof2 = cq.Workplane("YZ").center(radius, 0).rect(5, 10)

result = sweep([prof1.val(), prof2.val()], path.val(), True)


or with CQ2.4 :
result = (
    cq.Workplane()
    .add([prof1.val(), prof2.val()])
    .toPending()
    .sweep(path, multisection=True)
)

Ssw

unread,
Oct 31, 2024, 10:32:30 PM10/31/24
to CadQuery
Hi Lorenz,

thank you for your help. I checked your tips and came out with the results below. Unfortunately, fillet throws a mysterious error (to me of course ;)), looks like it does not work when thickness is different - in your example it works but only when swept rect has the same size. I spent some time today and was able to get the same shape as below script produces (my implementation was far more messy). How can I make the result symmetric in both X and Y axes?


import cadquery as cq
import ocp_vscode as ov
import cqkit as ck

radius = 23
radius2 = radius + 3
path = cq.Workplane("XY").ellipse(radius, radius2)

# create profiles
prof1 = cq.Workplane("YZ").center(-radius2, 0).rect(2, 10)
prof2 = cq.Workplane("XZ").center(-radius, 0).rect(1, 10)
prof3 = cq.Workplane("YZ").center(radius2, 0).rect(2, 10)
prof4 = cq.Workplane("XZ").center(radius, 0).rect(1, 10)

profs = [
prof1.val(),
prof2.val(),
prof3.val(),
prof4.val(),
]

result = (
cq.Workplane().add(profs)
.toPending()
.sweep(path, multisection=True)
)

# result = result.edges(cq.selectors.LengthNthSelector(2)).fillet(0.1)

ck.pprint_obj(result)
ov.show(result)

Lorenz

unread,
Nov 1, 2024, 7:04:52 PM11/1/24
to CadQuery
> How can I make the result symmetric in both X and Y axes?

Here is one method by creating an arc then mirroring the result.

import cadquery as cq


radius = 23
radius2 = radius + 3

# create ellipse arc path
path = cq.Workplane("XY").ellipseArc(radius, radius2, 0, 90).translate((radius, 0, 0))

# postions on path - where to create profiles
# 0 is start, 1 is end of path; add other pos as needed
ds = [0, 0.5, 1]
# width of profile at position index (height fixed at 10 below)
w_prof = [5, 2, 5]

# list of position and tangent vectors to define profile plane
positions = path.val().positions(ds)
tangents = [path.val().tangentAt(d) for d in ds]

# create the profiles
profs = []
for p, t, w in zip(positions, tangents, w_prof):
    plane1 = cq.Plane(origin=p, normal=t)
    wire1 = cq.Workplane(plane1).rect(w, 10)
    profs.append(wire1.val())

# for visualization of all profiles only
vis_profs = cq.Workplane().add(profs)

# create ring shape with multisection sweep
result_sweep = (
    cq.Workplane()
    .add(profs)
    .toPending()
    .sweep(path.val(), multisection=True)
    .mirror("XZ", union=True)
    .mirror("YZ", union=True)
)

# example fillet inside edges
result_sweep2 = (
    result_sweep.faces("|Z").edges(cq.selectors.LengthNthSelector(0)).fillet(0.2)
)

# example fillet top both edges
result_sweep3 = result_sweep.faces(">>Z").edges().fillet(0.2)

# compare with loft
result_loft = (
    cq.Workplane()
    .add(profs)
    .toPending()
    .loft()
    # .loft(True)  # also compare with ruled
    .mirror("XZ", union=True)
    .mirror("YZ", union=True)
)



Another example with Sketch:

import cadquery as cq


radius = 23
radius2 = radius + 3
th = 4  # thickness of ring

# ellipse ring
sk1 = cq.Sketch().ellipse(radius, radius2)
sk2 = cq.Sketch().ellipse(radius + th, radius2 + th)

# example: distribute shape along edge; replace mode
sk3 = sk1.copy().edges().distribute(8, 0, 1).circle(4, mode="r").reset()
# call reset when done with sketch selection

# combine sketches, extrude
result = cq.Workplane().placeSketch(sk2 - sk1 + sk3).extrude(10)
result = result.faces(">>Z").edges().fillet(0.2)

Ssw

unread,
Nov 2, 2024, 5:22:17 PM11/2/24
to CadQuery
I managed to get the required shape on my own; however, I have one more question. Which version of CadQuery are you using? I have 2.4.0, and I'm unable to run the second example. There are no addition and subtraction operators for sketches, and there is no "r" mode for Sketch.circle() method.

Lorenz

unread,
Nov 2, 2024, 7:22:08 PM11/2/24
to CadQuery
Sorry, I was using the master branch.  The example used several new Sketch features.
Reply all
Reply to author
Forward
0 new messages