1

I come from the engineering CAD world and I'm creating some designs in CadQuery. What I want to do is this (pseudocode):

edges = part.edges()
edges[n].fillet(r)

Or ideally have the ability to do something like this (though I can't find any methods for edge properties). Pseudocode:

edges = part.edges()
for edge in edges:
    if edge.length() > x:
        edge.fillet(a)
    else:
        edge.fillet(b)

This would be very useful when a design contains non-orthogonal faces. I understand that I can select edges with selectors, but I find them unnecessarily complicated and work best with orthogonal faces. FreeCAD lets you treat edges as a list.

I believe there might be a method to select the closest edge to a point, but I can't seem to track it down.

If someone can provide guidance that would be great -- thank you!

Bonus question: Is there a way to return coordinates of geometry as a list or vector? e.g.:

origin = cq.workplane.center().val
>> [x,y,z]

(or something like the above)

  • What library are you using? Please tag your question appropriately. –  May 06 '22 at 15:59
  • Hi Richard, I'm using CadQuery (added a hyperlink). I couldn't find a tag and it wouldn't let me create one because my account is too new, so I'm not quite sure what I should do. – Tristan Antonsen May 06 '22 at 18:39
  • Ah, I see! Thank you for clarifying; I just created the tag for you. Your question is the first with it! :) –  May 06 '22 at 20:50

2 Answers2

2

For the posterity. To select multiple edges eg. for chamfering you can use newObject() on Workplane. The argument is a list of edges (they have to be cq.occ_impl.shapes.Edge instances, NOT cq.Workplane instances).

import cadquery as cq

model = cq.Workplane().box(10, 10, 5)
edges = model.edges()

# edges.all() returns worplanes, we have to get underlying geometry
selected = list(map(lambda x: x.objects[0], edges.all()))

model_with_chamfer = model.newObject(selected).chamfer(1)

To get edge length you can do something like this:

edge = model.edges().all()[0] # This select one 'random' edge
length = edge.objects[0].Length()

edge.Length() doesn't work since edge is Workplane instance, not geometry instance.

To get edges of certain length you can just create dict with edge geometry and length and filter it using builtin python's filter(). Here is a snippet of my implementation for chamfering short edges on topmost face:

top_edges = model.edges(">Z and #Z")

def get_length(edge):
    try:
        return edge.vals()[0].Length()
    except Exception:
        return 0.0

# Inside edges are shorter - filter only those
edge_len_list = list(map(
    lambda x: (x.objects[0], get_length(x)),
    top_edges.all()))
avg = mean([a for _, a in edge_len_list])
selected = filter(lambda x: x[1] < avg, edge_len_list)
selected = [e for e, _ in selected]

vertical_edges = model.edges("|Z").all()
selected.extend(vertical_edges)

model = model.newObject(selected)
model = model.chamfer(chamfer_size)
1

Take a look at this code, i hope this will be helpful.

import cadquery as cq

plane1 = cq.Workplane()

block = plane1.rect(10,12).extrude(10)

edges = block.edges("|Z")

filleted_block = edges.all()[0].fillet(0.5)

show(filleted_block)
NANDHA KUMAR
  • 465
  • 4
  • 11