Getting started and a bit lost with polylines

33 views
Skip to first unread message

Natalie Baker

unread,
Sep 30, 2025, 7:02:05 AMSep 30
to CadQuery
Hi all,

I've been developing an interlocking tabletop terrain system for a little while in OpenSCAD due to my experience with it, but I'm looking at moving over to CADQuery because I has hitting some limitations with pure functional languages and implementing some randomized procedural elements. 

I ran into some issues when porting the code over, specifically with creating a 4-symmetry shape with a cut. I've created an sample of the issue I encountered:
```
PROFILE_OUTER = [
    (10,  0),
    ( 8,  8),
    ( 0, 10),
]

PROFILE_INNER = [
    ( 1, 1),
    ( 9, 1),
    ( 9, 9),
    ( 1, 9),
]

# (1) Broken - Seems to connect back to first sketch
# show_object((
#     cq.Workplane("XY")
#             .polyline(PROFILE_OUTER)
#             .mirrorX()
#             .mirrorY()
#             .extrude(1)
#         .polyline(PROFILE_INNER)
#             .close()
#             .extrude(2)
# ))

# (2) Works
show_object((
    cq.Workplane("XY")
        .polyline(PROFILE_OUTER)
            .mirrorX()
            .mirrorY()
            .extrude(1)
        .polyline(PROFILE_INNER)
            .polyline([PROFILE_INNER[-1],PROFILE_INNER[0]])
            .mirrorX()
            .mirrorY()
            .extrude(2)
))

# (3) Works but not the intended Output
# show_object((
#     cq.Workplane("XY")
#             .polyline(PROFILE_OUTER)
#             .close()
#             .extrude(1)
#         .polyline(PROFILE_INNER)
#             .close()
#             .extrude(2)
# ))

# (4) Doesnt work: RuntimeError("Cannot convert object type '%s' to vector " % type(obj))
# show_object((
#     cq.Workplane("XY")
#             .polyline(PROFILE_OUTER)
#             .mirrorY()
#             .mirrorX()
#             .close()
#             .extrude(1)
#         .polyline(PROFILE_INNER)
#             .close()
#             .extrude(2)
# ))

# (5) Doesnt work: ValueError("No pending wires present")
# show_object((
#     cq.Workplane("XY")
#         .polyline(PROFILE_OUTER)
#             .mirrorX()
#             .mirrorY()
#             .extrude(1)
#         .polyline(PROFILE_INNER)
#             .polyline([PROFILE_INNER[-1],PROFILE_INNER[0]])
#             .extrude(2)
# ))
```

It seems like the close function picks up the last point of the first polyline (1), which requires me to manually complete the shape (2). The first shape is constructed using mirroring, so I can't close the polyline first, though does allow me to use close for the second shape (3), and attempting to call close after the mirrors in the first object results in an exception (4). 

I also noted that if I manually close the second shape but don't mirror then that results in another error (5).

I feel like I must be missing some rules about the interactions of somethings? I can't seem to find a way to clear that point from the previous sketch. I've got something that works for my project for now, but I want to make sure I'm not operating with some fundamental misunderstanding.

Thanks for your time,
Natalie

Attached is the image in cq-editor for (1)example_1.png

Natalie Baker

unread,
Sep 30, 2025, 7:03:20 AMSep 30
to CadQuery
The example doesn't contain a cut because it's a little harder to see what's going on. In my actual use case it's a `.cutThuAll` call instead of extrude.

Jeremy Wright

unread,
Sep 30, 2025, 9:00:19 AMSep 30
to Natalie Baker, CadQuery
There is an annoying bug in mirrorY that needs to be fixed (I need to open a PR). It is described here: https://github.com/CadQuery/cadquery/issues/1015

For now, a work-around would be the one shown below. Also notice that I used a face selector and established a new workplane on the face before drawing the next polyline. That is generally the workflow. You apply an operation to a 2D object to get a 3D object, you select a face and establish a workplane, then draw more 2D on that, then extrude/cut/whatever that. Chamfers and fillets work a little differently because you select a face or edge(s) but don't establish a workplane, you just do the fillet/chamfer operation.

PROFILE_OUTER = [
    (10,  0),
    ( 8,  8),
    ( 0, 10),
]

PROFILE_INNER = [
    ( 1, 1),
    ( 9, 1),
    ( 9, 9),
    ( 1, 9),
]

# Do the mirroring, but stop after the bugged mirrorY call
terrain = (cq.Workplane("XY")
        .polyline(PROFILE_OUTER)
        .mirrorX()
        .mirrorY())

# Compensates for bug in mirrorY
terrain.ctx.firstPoint = None

# Continue with construction
terrain = (terrain
           .extrude(1)
           .faces(">Z")
           .workplane()
           .polyline(PROFILE_INNER)
           .close()
           .cutThruAll())

show_object(terrain)

You can also call ".toPending()" rather than calling "close()" on a profile that doesn't need to be closed, but "close()" works best with polylines. I bring this up because I could see you needing to use "toPending()" sometimes with the work you are doing. When you get the error 'ValueError("No pending wires present")', maybe try calling "toPending()".

--
cadquery home: https://github.com/CadQuery/cadquery
post issues at https://github.com/CadQuery/cadquery/issues
run it at home at : https://github.com/CadQuery/CQ-editor
---
You received this message because you are subscribed to the Google Groups "CadQuery" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cadquery+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/cadquery/20aa1468-74f5-4ad9-aa8a-b18873a8bdbdn%40googlegroups.com.
Screenshot from 2025-09-30 08-56-15.png

Natalie Baker

unread,
Sep 30, 2025, 9:13:41 PMSep 30
to CadQuery
Ahhh, I thought I was missing something because I ran into this when I first jumped in, makes a lot more sense now thankyou! 
Also thankyou for putting up that PR too, and the tips about the ctx variable and .toPending call! :)

I think I should be able to make an extension that patches it in my case, until that PR merges.

Thanks again,
Natalie

Jeremy Wright

unread,
Oct 1, 2025, 8:34:44 PMOct 1
to Natalie Baker, CadQuery
Since it was a simple fix, that PR has already been merged. There should be a new CadQuery release within the next week or so.


Reply all
Reply to author
Forward
0 new messages