gsohler / openscad

OpenSCAD - The Programmers Solid 3D CAD Modeller
https://www.openscad.org
Other
14 stars 6 forks source link

Wedge and Arc primitives for python #20

Closed gandrewstone closed 3 months ago

gandrewstone commented 4 months ago

Here is some code you might want to add to your python lib:

def opswedge(radius, angle, height=None, fn=None, fa=None):
    """Returns a 2d or 3d wedge (pizza slice).  It operates by creating a circle and then removing part of the circle, so fn and fa parameters apply to the entire circle not just the wedge.
    @param height: if height is None, a 2d object is generated.  Otherwise a 3d extrusion of the wedge is created.
    """    
    t = ops.circle(radius, fn=fn, fa=fa) if (fn and fa) else ops.circle(radius, fn=fn) if fn else ops.circle(radius, fa=fa) if fa else ops.circle(radius)
    if (angle >=0 and angle < 90):
        cutout = ops.polygon([[0,0],[radius*math.cos(math.radians(angle)), radius*math.sin(math.radians(angle))], [radius, radius], [-radius,radius],[-radius,-radius],[radius,-radius],[radius,0]])   
    elif (angle >=90 and angle < 180):
        cutout = ops.polygon([[0,0],[radius*math.cos(math.radians(angle)), radius*math.sin(math.radians(angle))], [-radius, radius], [-radius,-radius],[radius,-radius],[radius,0]])
    elif (angle >=180 and angle < 270):
        cutout = ops.polygon([[0,0],[radius*math.cos(math.radians(angle)), radius*math.sin(math.radians(angle))], [-radius,-radius],[radius,-radius],[radius,0]])
    elif (angle >=270 and angle < 360):
        cutout = ops.polygon([[0,0],[radius*math.cos(math.radians(angle)), radius*math.sin(math.radians(angle))], [radius,-radius],[radius,0]])
    else: # full circle
        if height is None:
            return t
        else: return ops.path_extrude(t,[[0,0,0],[0,0,height]])

    if height is None:
        return t - cutout
    return ops.path_extrude(t - cutout,[[0,0,0],[0,0,height]])

def opsarc(radius, angle, thickness, height=None, fn=None, fa=None):
    """Returns a 2d or 3d arc. It operates by creating a circle and then removing part of the circle, so fn and fa parameters apply to the entire circle not just the wedge.
    @param height: if height is None, a 2d object is generated.  Otherwise a 3d extrusion of the wedge is created.
    """
    if thickness >= radius:
        return opswedge(radius, angle, height=height)
    if thickness <= 0:
        return None
    else:
        outer = opswedge(radius, angle)
        inner = opswedge(radius-thickness, angle + 0.01)
        t = outer - inner
        if not height is None:
            return ops.path_extrude(t,[[0,0,0],[0,0,height]])
        else: return t

def TestWedgeArc():
    wedge = opswedge
    arc = opsarc
    a = ops.path_extrude(wedge(10,60, fn=16),[[0,0,0],[0,0,10]])
    b = opswedge(10,120, fn=30, fa=1, height=20).translate([30,0,0])
    c = ops.path_extrude(wedge(10,210, fa=45),[[0,0,0],[0,0,10]]).translate([60,0,0])
    d = ops.path_extrude(wedge(10,300),[[0,0,0],[0,0,10]]).translate([90,0,0])
    e = ops.path_extrude(wedge(10,360),[[0,0,0],[0,0,10]]).translate([120,0,0])

    CH = 0
    width = 3
    f = ops.path_extrude(arc(10,60 - CH,width),[[0,0,0],[0,0,10]]).translate([0,30,0])
    g = ops.path_extrude(arc(10,120 - CH,width),[[0,0,0],[0,0,10]]).translate([30,30,0])
    h = ops.path_extrude(arc(10,210 - CH,width),[[0,0,0],[0,0,10]]).translate([60,30,0])
    i = ops.path_extrude(arc(10,300 - CH,width),[[0,0,0],[0,0,10]]).translate([90,30,0])
    j = ops.path_extrude(arc(10,360 - CH,width),[[0,0,0],[0,0,10]]).translate([120,30,0])

    return a | b | c | d | e   | f | g | h | i | j
gsohler commented 4 months ago

the code works great and is definitely an enrichment to pythonscad. However you probably want to make it more fool-proof. dont relay on the import openscad as osc and make sure that math is imported.You could develop your library, publish it and i would link to it on the pythonscad homepage. what do you think ?

gandrewstone commented 3 months ago

I don't think its sufficient functionality to warrant a separate library.