Extrude an existing face

1,365 views
Skip to first unread message

Jarshvor

unread,
Oct 13, 2021, 9:19:40 AM10/13/21
to CadQuery

Hello everyone,
Im fairly new to cadquery and just recently found out about this googlegroups page, so excuse me if this is a very basic question.

I'm trying to make a shell of a box, but have the bottom face be thicker than the rest of the shell.
For this I imagined I could do the inwards shell on a box, and then extrude the inner bottom face upwards by some amount.
Something like the following:

###############
import cadquery as cq

block=cq.Workplane("XY").box(4,4,4)

internalcut=block.faces(">Z").shell(-0.2)
extrudio=internalcut.faces(">Z[1]").extrude(1)

show_object(extrudio)
###############

But I am having trouble extruding faces in general. So there is probably something I am missing conceptually.
I know I can extrude basic 2D shapes like rectangles, circles, polylines (which are not "filled"), but I am not sure if these are in the same category as edges and wires, or how I can extrude these last two.
I have tried to extrude faces, edges, faces turned to wires, but to no avail.

Edges:
###############
extrudio=internalcut.faces(">Z[1]").edges().extrude(1)
###############

Wires:
###############
extrudio=internalcut.faces(">Z[1]").wires().extrude(1)
###############

The only thing that works is recreating another rectangle on top of that selected face and then extruding. Which kind of defeats the purpose of reusing the dimensions of said face.
As in here:
###############
extrudio=internalcut.faces(">Z[1]").rect(4,4).extrude(1)
###############


Is there something I am missing in order to be able to extrude an already existing face?
Also, if you think I'm going about this in the wrong way and there is a better more direct way of getting what I'm after do let me know.

I realize a pocket with the appropriate dimensions would perhaps be the simplest.
Like so:

###############
import cadquery as cq

block=cq.Workplane("XY").box(4,4,4)
pocket=block.faces(">Z").rect(4-(0.2*2),4-(0.2*2))\
                                    .cutBlind(-3)

show_object(pocket)
###############

But since the shell width and that extra bottom extruded height are the driving parameters conceptually, in my mind it seemed
like a better choice to employ those rather than use them arithmetically in some other variables.

In summary, I'd like to know how I can manipulate an existing face in order to extrude it further.

Thanks for your help and for this wonderful tool!

Lorenz

unread,
Oct 13, 2021, 7:02:13 PM10/13/21
to CadQuery
Hi,

Note that the following line: 
    extrudio=internalcut.faces(">Z[1]").extrude(1)

results in: 
    ValueError: No pending wires present

To fix the error, we can select the wires and add them to the pendingWires:
    extrudio=internalcut.faces(">Z[1]").wires().toPending().extrude(1)

>But I am having trouble extruding faces in general.
toPending() was added for the use case you mention discussed in GitHub issue 148 "Fluent API does not allow to easily extrude an existing face".

(for more on what is pendingWires see the documentation section "An Introspective Example")

Jarshvor

unread,
Oct 14, 2021, 5:24:45 PM10/14/21
to CadQuery
For the line:
    extrudio=internalcut.faces(">Z[1]").extrude(1)
I actually get the following error:
    IndexError: list index out of range

Not sure if that has something to do with my setup. Tested both with cq-editor 2.0 and plain ipython console, running cadquery 2.1
In any case the .toPending() method you mentioned pretty much solves this issue for me.

I did have a look at "An Introspective Example", but not being a programmer, I can't say I really understood that 100%.
The general gist I got was that it has to do with the stack and how operations use the PendingWires/PendingEdges attributes.
So when we simply select a face or wires/edges from a face, these are not stored in the PendingWires/Edges attribute; so we must move them there with the .toPending() metod in order to continue operating on them.
When we create a rectangle/polygon/polyline etc however these are stored already in the PendingWires/Edges attribute and are thus available to extrude and loft commands.?? Something like that?

In any case, thanks for the solution Lorenz and I'll try to come back to that Introspective Example as I use and learn more of CadQuery to see if it sinks in.

Lorenz

unread,
Oct 14, 2021, 7:03:25 PM10/14/21
to CadQuery
>When we create a rectangle/polygon/polyline etc however these are stored already in the PendingWires/Edges attribute and are thus available to extrude and loft commands.??

That's right!


import cadquery as cq
r = cq.Workplane()
print(f"pendingWires 1: {r.ctx.pendingWires}")
r = r.rect(1,1)
print(f"pendingWires 2: {r.ctx.pendingWires}")


results in:
    pendingWires 1: []
    pendingWires 2: [<cadquery.occ_impl.shapes.Wire object at 0x7f99fc1a03a0>]


The above is similar to the line of the docs introspective example: part = part.circle(0.2)

Jarshvor

unread,
Oct 15, 2021, 5:59:10 PM10/15/21
to CadQuery
Thanks Lorenz,

Re-reading the example after your explanations,  I think this paragraph made it click:

"The circle() method - like all 2D drawing methods - has placed the circle into both the objects attribute (where it will be cleared during the next modelling step), and the modelling context’s pending wires (where it will persist until used by another Workplane method)."

So all 2D operations store data in the object attribute as well as the modelling context as we might want to use them for modelling directly (extrude, loft, cut..) or as objects for referencing other features (e.g: rect(1,1).vertices().cylinder(1,3)).

3D operations like .box() store data as objects, as do selector methods like .faces() or .wires(), since it is not obvious that they will be used for direct modelling operations but rather for referencing such as setting up a workplane or such.

But in the event that we do want to model directly after data stored only as an object attribute, .toPending() will copy said data to the modelling context.

Sorry for the self-ramble, and thanks again!
Reply all
Reply to author
Forward
0 new messages