Exemplo n.º 1
0
def makeSAG(sketch, zBot, zMid, zTop, tIn, tOut, offset=0.):
    doc = FreeCAD.ActiveDocument
    # First, compute the geometric quantities we will need:
    a = zTop - zMid  # height of the top part
    b = tOut + tIn  # width of one of the trianglular pieces of the top
    alpha = np.abs(np.arctan(a / np.float(b)))  # lower angle of the top part
    c = a + 2 * offset  # height of the top part including the offset
    # horizontal width of the trianglular part of the top after offset
    d = c / np.tan(alpha)
    # horizontal shift in the triangular part of the top after an offset
    f = offset / np.sin(alpha)

    sketchList = splitSketch(sketch)
    returnParts = []
    for tempSketch in sketchList:
        # TODO: right now, if we try to taper the top of the SAG wire to a point, this
        # breaks, since the offset of topSketch is empty. We should detect and handle this.
        # For now, just make sure that the wire has a small flat top.
        botSketch = draftOffset(tempSketch, offset)  # the base of the wire
        midSketch = draftOffset(tempSketch, f + d - tIn)  # the base of the cap
        topSketch = draftOffset(tempSketch, -tIn + f)  # the top of the cap
        delete(tempSketch)  # remove the copied sketch part
        # Make the bottom wire:
        rectPartTemp = extrude(botSketch, zMid - zBot)
        rectPart = copy_move(rectPartTemp, moveVec=(0., 0., zBot - offset))
        delete(rectPartTemp)
        # make the cap of the wire:
        topSketchTemp = copy_move(topSketch, moveVec=(
            0., 0., zTop - zMid + 2 * offset))
        capPartTemp = doc.addObject('Part::Loft', sketch.Name + '_cap')
        capPartTemp.Sections = [midSketch, topSketchTemp]
        capPartTemp.Solid = True
        doc.recompute()
        capPart = copy_move(capPartTemp, moveVec=(0., 0., zMid - offset))
        delete(capPartTemp)
        delete(topSketchTemp)
        delete(topSketch)
        delete(midSketch)
        delete(botSketch)
        returnParts += [capPart, rectPart]
        returnPart = genUnion(returnParts, consumeInputs=True
                                           if not DBG_OUT else False)
    return returnPart
Exemplo n.º 2
0
def makeSAG(sketch, zBot, zMid, zTop, tIn, tOut, offset=0.0):
    doc = FreeCAD.ActiveDocument
    assert zBot <= zMid
    assert zMid <= zTop

    # First, compute the geometric quantities we will need:
    a = zTop - zMid  # height of the top part
    b = tOut + tIn  # width of one of the triangular pieces of the top
    # if there is no slope to the roof, it's a different geometry which we don't handle:
    assert not np.isclose(
        b, 0
    ), "Either overshoot or inner displacement values need to be non-zero for SAG \
                                 (otherwise use extrude)"

    # This also means there would be no slope to the roof:
    assert not np.isclose(
        a, 0
    ), "Top and middle z values need to be different for SAG (otherwise use extrude)."
    alpha = np.arctan(a / b)  # lower angle of the top part
    c = a + 2 * offset  # height of the top part including the offset
    # horizontal width of the trianglular part of the top after offset
    d = c / np.tan(alpha)
    # horizontal shift in the triangular part of the top after an offset
    f = offset * (1 - np.cos(alpha)) / np.sin(alpha)

    sketchList = splitSketch(sketch)
    returnParts = []
    for tempSketch in sketchList:
        botSketch = draftOffset(tempSketch, offset)  # the base of the wire
        midSketch = draftOffset(tempSketch, f + d - tIn)  # the base of the cap
        top_offset = f - tIn
        topSketch = draftOffset(tempSketch, top_offset)  # the top of the cap
        # If topSketch has been shrunk exactly to a line or a point, relax the offset to 5E-5. Any closer and FreeCAD seems to suffer from numerical errors
        if topSketch.Shape.Area == 0:
            top_offset -= 5e-5
            delete(topSketch)
            topSketch = draftOffset(tempSketch, top_offset)

        delete(tempSketch)  # remove the copied sketch part
        # Make the bottom wire:
        if zMid - zBot != 0:
            rectPartTemp = extrude(botSketch, zMid - zBot)
            rectPart = copy_move(rectPartTemp,
                                 moveVec=(0.0, 0.0, zBot - offset))
            delete(rectPartTemp)
        else:
            rectPart = None

        # make the cap of the wire:
        topSketchTemp = copy_move(topSketch,
                                  moveVec=(0.0, 0.0, zTop - zMid + 2 * offset))
        capPartTemp = doc.addObject("Part::Loft", f"{sketch.Name}_cap")
        capPartTemp.Sections = [midSketch, topSketchTemp]
        capPartTemp.Solid = True
        doc.recompute()
        capPart = copy_move(capPartTemp, moveVec=(0.0, 0.0, zMid - offset))
        delete(capPartTemp)
        delete(topSketchTemp)

        delete(topSketch)
        delete(midSketch)
        delete(botSketch)
        returnPart = (genUnion([capPart, rectPart],
                               consumeInputs=True if not DBG_OUT else False)
                      if rectPart is not None else capPart)
        returnParts.append(returnPart)
    return returnParts