Пример #1
0
 def _build_extrude(self, partName):
     """Build an extrude part."""
     partDict = self.model.modelDict['3DParts'][partName]
     assert partDict['directive'] == 'extrude'
     z0 = self._fetch_geo_param(partDict['z0'])
     deltaz = self._fetch_geo_param(partDict['thickness'])
     sketch = self.doc.getObject(partDict['fcName'])
     splitSketches = splitSketch(sketch)
     extParts = []
     for mySplitSketch in splitSketches:
         extPart = extrudeBetween(mySplitSketch, z0, z0 + deltaz)
         extPart.Label = partName
         extParts.append(extPart)
         delete(mySplitSketch)
     return extParts
Пример #2
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(rectPartTemp, moveVec=(0., 0., zBot - offset))
        delete(rectPartTemp)
        # make the cap of the wire:
        topSketchTemp = copy(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(capPartTemp, moveVec=(0., 0., zMid - offset))
        delete(capPartTemp)
        delete(topSketchTemp)
        delete(topSketch)
        delete(midSketch)
        delete(botSketch)
        returnParts += [capPart, rectPart]
    returnPart = genUnion(returnParts, consumeInputs=True)
    return returnPart
Пример #3
0
 def _initialize_lithography(self, fillShells=True):
     self.fillShells = fillShells
     # The lithography step requires some infrastructure to track things
     # throughout.
     self.lithoDict = {
     }  # dictionary containing objects for the lithography step
     self.lithoDict['layers'] = {}
     # Dictionary for containing the substrate. () indicates un-offset objects,
     # and subsequent tuples are offset by t_i for each index in the tuple.
     self.lithoDict['substrate'] = {(): []}
     # To start, we need to collect up all the lithography directives, and
     # organize them by layerNum and objectIDs within layers.
     baseSubstratePartNames = []
     for partName in self.model.modelDict['3DParts'].keys():
         partDict = self.model.modelDict['3DParts'][partName]
         # If this part is a litho step
         if 'lithography' == partDict['directive']:
             layerNum = partDict['layerNum']  # layerNum of this part
             # Add the layerNum to the layer dictionary:
             if layerNum not in self.lithoDict['layers']:
                 self.lithoDict['layers'][layerNum] = {'objIDs': {}}
             layerDict = self.lithoDict['layers'][layerNum]
             # Gennerate the base and thickness of the layer:
             layerBase = self._fetch_geo_param(partDict['z0'])
             layerThickness = self._fetch_geo_param(partDict['thickness'])
             # All parts within a given layer number are required to have
             # identical thickness and base, so check that:
             if 'base' in layerDict:
                 assert layerBase == layerDict['base']
             else:
                 layerDict['base'] = layerBase
             if 'thickness' in layerDict:
                 assert layerThickness == layerDict['thickness']
             else:
                 layerDict['thickness'] = layerThickness
             # A given part references a base sketch. However, we need to split
             # the sketch here into possibly disjoint sub-sketches to work
             # with them:
             sketch = self.doc.getObject(partDict['fcName'])
             splitSketches = splitSketch(sketch)
             for mySplitSketch in splitSketches:
                 objID = len(layerDict['objIDs'])
                 objDict = {}
                 objDict['partName'] = partName
                 objDict['sketch'] = mySplitSketch
                 self.trash.append(mySplitSketch)
                 self.lithoDict['layers'][layerNum]['objIDs'][
                     objID] = objDict
             # Add the base substrate to the appropriate dictionary
             baseSubstratePartNames += partDict['lithoBase']
     # Get rid of any duplicates:
     baseSubstratePartNames = list(set(baseSubstratePartNames))
     # Now convert the part names for the substrate into 3D freeCAD objects, which
     # should have already been rendered.
     for baseSubstratePartName in baseSubstratePartNames:
         for baseSubstrateObjName in self.model.modelDict['3DParts'][
                 baseSubstratePartName]['fileNames'].keys():
             self.lithoDict['substrate'][()] += [
                 self.doc.getObject(baseSubstrateObjName)
             ]
     # Now that we have ordered the primitives, we need to compute a few
     # aux quantities that we will need. First, we compute the total bounding
     # box of the lithography procedure:
     thicknesses = []
     bases = []
     for layerNum in self.lithoDict['layers'].keys():
         thicknesses.append(self.lithoDict['layers'][layerNum]['thickness'])
         bases.append(self.lithoDict['layers'][layerNum]['base'])
     bottom = min(bases)
     totalThickness = sum(thicknesses)
     assert len(self.lithoDict['substrate'][
         ()]) > 0  # Otherwise, we don't have a reference for the lateral BB
     substrateUnion = genUnion(self.lithoDict['substrate'][()],
                               consumeInputs=False)  # total substrate
     BB = list(getBB(substrateUnion))  # bounding box
     BB[4] = min([bottom, BB[4]])
     BB[5] = max([BB[5] + totalThickness, bottom + totalThickness])
     BB = tuple(BB)
     constructionZone = makeBB(BB)  # box that encompases the whole domain.
     self.lithoDict['boundingBox'] = [BB, constructionZone]
     delete(substrateUnion)  # not needed for next steps
     delete(constructionZone)  # not needed for next steps
     # Next, we add two prisms for each sketch. The first, which we denote "B",
     # is bounded by the base from the bottom and the layer thickness on the top.
     # These serve as "stencils" that would be the deposited shape if no other.
     # objects got in the way. The second set of prisms, denoted "C", covers the
     # base of the layer to the top of the entire domain box. This is used for
     # forming the volumes occupied when substrate objects are offset and
     # checking for overlaps.
     for layerNum in self.lithoDict['layers'].keys():
         base = self.lithoDict['layers'][layerNum]['base']
         thickness = self.lithoDict['layers'][layerNum]['thickness']
         for objID in self.lithoDict['layers'][layerNum]['objIDs']:
             sketch = self.lithoDict['layers'][layerNum]['objIDs'][objID][
                 'sketch']
             B = extrudeBetween(sketch, base, base + thickness)
             C = extrudeBetween(sketch, base, BB[5])
             self.lithoDict['layers'][layerNum]['objIDs'][objID]['B'] = B
             self.lithoDict['layers'][layerNum]['objIDs'][objID]['C'] = C
             self.trash.append(B)
             self.trash.append(C)
             # In addition, add a hook for the HDict, which will contain the "H"
             # constructions for this object, but offset to thicknesses of various
             # layers, according to the keys.
             self.lithoDict['layers'][layerNum]['objIDs'][objID][
                 'HDict'] = {}