def buildWire(sketch, zBottom, width, faceOverride=None, offset=0.0): """Given a line segment, build a nanowire of given cross-sectional width with a bottom location at zBottom. Offset produces an offset with a specified offset. """ doc = FreeCAD.ActiveDocument if faceOverride is None: face = makeHexFace(sketch, zBottom - offset, width + 2 * offset) else: face = faceOverride sketchForSweep = extendSketch(sketch, offset) mySweepTemp = doc.addObject("Part::Sweep", sketch.Name + "_wire") mySweepTemp.Sections = [face] mySweepTemp.Spine = sketchForSweep mySweepTemp.Solid = True doc.recompute() mySweep = copy_move(mySweepTemp) deepRemove(mySweepTemp) return mySweep
def buildAlShell(sketch, zBottom, width, verts, thickness, depoZone=None, etchZone=None, offset=0.0): """Builds a shell on a nanowire parameterized by sketch, zBottom, and width. Here, verts describes the vertices that are covered, and thickness describes the thickness of the shell. depoZone, if given, is extruded and intersected with the shell (for an etch). Note that offset here *is not* a real offset - for simplicity we keep this a thin shell that lies cleanly on top of the bigger wire offset. There's no need to include the bottom portion since that's already taken up by the wire. Parameters ---------- sketch : zBottom : width : verts : thickness : depoZone : (Default value = None) etchZone : (Default value = None) offset : (Default value = 0.0) Returns ------- """ lineSegments = findSegments(sketch)[0] x0, y0, z0 = lineSegments[0] x1, y1, z1 = lineSegments[1] dx = x1 - x0 dy = y1 - y0 rAxis = np.array([-dy, dx, 0]) # axis perpendicular to the wire in the xy plane rAxis /= np.sqrt(np.sum(rAxis**2)) zAxis = np.array([0, 0, 1.0]) doc = FreeCAD.ActiveDocument shellList = [] for vert in verts: # Make the original wire (including an offset if applicable) originalWire = buildWire(sketch, zBottom, width, offset=offset) # Now make the shifted wire: angle = vert * np.pi / 3.0 dirVec = rAxis * np.cos(angle) + zAxis * np.sin(angle) shiftVec = (thickness) * dirVec transVec = FreeCAD.Vector(tuple(shiftVec)) face = makeHexFace(sketch, zBottom - offset, width + 2 * offset) # make the bigger face shiftedFace = Draft.move(face, transVec, copy=False) extendedSketch = extendSketch(sketch, offset) # The shell offset is handled manually since we are using faceOverride to # input a shifted starting face: shiftedWire = buildWire(extendedSketch, zBottom, width, faceOverride=shiftedFace) delete(extendedSketch) shellCut = doc.addObject("Part::Cut", f"{sketch.Name}_cut_{vert}") shellCut.Base = shiftedWire shellCut.Tool = originalWire doc.recompute() shell = Draft.move(shellCut, FreeCAD.Vector(0.0, 0.0, 0.0), copy=True) doc.recompute() delete(shellCut) delete(originalWire) delete(shiftedWire) shellList.append(shell) if len(shellList) > 1: coatingUnion = doc.addObject("Part::MultiFuse", f"{sketch.Name}_coating") coatingUnion.Shapes = shellList doc.recompute() coatingUnionClone = copy_move(coatingUnion) doc.removeObject(coatingUnion.Name) for shell in shellList: doc.removeObject(shell.Name) elif len(shellList) == 1: coatingUnionClone = shellList[0] else: raise NameError( "Trying to build an empty Al shell. If no shell is desired, omit the AlVerts key from " "the json.") if (depoZone is None) and (etchZone is None): return coatingUnionClone elif depoZone is not None: coatingBB = getBB(coatingUnionClone) zMin = coatingBB[4] zMax = coatingBB[5] depoVol = extrudeBetween(depoZone, zMin, zMax) etchedCoatingUnionClone = intersect( [depoVol, coatingUnionClone], consumeInputs=True if not DBG_OUT else False) return etchedCoatingUnionClone else: # etchZone instead coatingBB = getBB(coatingUnionClone) zMin = coatingBB[4] zMax = coatingBB[5] etchVol = extrudeBetween(etchZone, zMin, zMax) etchedCoatingUnionClone = subtract( coatingUnionClone, etchVol, consumeInputs=True if not DBG_OUT else False) return etchedCoatingUnionClone