CadQuery / cadquery

A python parametric CAD scripting framework based on OCCT
https://cadquery.readthedocs.io
Other
3.2k stars 290 forks source link

allow face selectors to be relative to workplane ? #1644

Open MarcWeber opened 2 months ago

MarcWeber commented 2 months ago
# testcase
    wp = cq.Workplane("XY")

    degree = 89

    x = wp.transformed(rotate=(degree,0,0)) \
        .circle(3, forConstruction = True).toPending() \
        .workplane(offset=10) \
        .circle(3, forConstruction = True).toPending() \
        .loft() \
        .faces(">Z") \
        .workplane() \
        .circle(2, forConstruction = True).toPending() \
        .workplane(offset=10) \
        .circle(2, forConstruction = True).toPending() \
        .loft() \

    from typing import Callable, Tuple
    def waterfall(wp: cq.Workplane, fs: list[Callable[[cq.Workplane], Tuple[cq.Workplane, cq.Workplane]]]) -> cq.Workplane:
        w1, w2 = wp, wp;
        for f in fs:
            w1, w2 = f(w2)
        return w1

    def trapez_cone(height, d1, d2 = None):
        """ nur nach oben in Z Richtung wegen > Z"""
        if d2 == None:
            d2 = d1
        def f(wp: cq.Workplane):
            wp = wp.circle(d1, forConstruction = True).toPending() \
                .workplane(offset=height) \
                .circle(d2, forConstruction = True).toPending() \
                .loft()
            return (wp, wp.faces(">Z").workplane())

        return f

    b = waterfall(cq.Workplane("XY").transformed(rotate=(0,degree,0)),[
        trapez_cone(10, 2, 2),
        trapez_cone(10, 4, 4),
        ])

If you change degree to > 90 the hole in the middle is closed. So it would be nice if >Z would be relative to workplane Z direction not global Z direction or if z (lower case or such) would have this different behavior to not break code. or >wz (w meaning workplane) or whatever. The waterfall implementation basically is the same but allowing pyright to type the abstraction which it can't if you extend workplane

nobkd commented 2 months ago

There's a cq plugin for local selectors: https://github.com/CadQuery/cadquery-plugins/tree/main/plugins/localselectors I haven't used it, so I don't know how good it is, but maybe it works for your use case

Discord comment Possible pip link fix for plugin

lorenzncode commented 2 months ago

The plane normal can be accessed with <the workplane>.plane.zDir. You might also try one of the Direction* selectors as another solution.

import cadquery as cq

cyl = cq.Workplane("ZX").cylinder(20, 5)
cyl = cyl.faces(cq.selectors.DirectionNthSelector(cyl.plane.zDir, 0))
# cyl = cyl.faces(cq.selectors.DirectionMinMaxSelector(-cyl.plane.zDir))