示例#1
0
def test_exportCAD(datadir, fix_FCDoc):
    """Test step export/import."""
    filePath = os.path.join(datadir, "tmp_testExport.stp")
    from qmt.geometry.freecad.geomUtils import makeBB

    testBB = (-1.0, 1.5, -2.0, 2.5, -3.0, 3.5)
    testShape = makeBB(testBB)
    exportCAD([testShape], filePath)

    Part.insert(filePath, fix_FCDoc.Name)
    CADImport = fix_FCDoc.getObject("tmp_testExport")

    import FreeCAD

    transBB = testBB[0:][::2] + testBB[
        1:][::2]  # reformat to FreeCAD representation
    refBB = FreeCAD.Base.BoundBox(*transBB)
    assert repr(CADImport.Shape.BoundBox) == repr(refBB)

    with pytest.raises(TypeError) as err:
        exportCAD(testShape, "dummy.stp")
    assert "must be a list" in str(err.value)

    with pytest.raises(ValueError) as err:
        exportCAD([testShape], "not_a_step_file")
    assert "not a supported extension" in str(err.value)
示例#2
0
def test_exportCAD(fix_testDir, fix_FCDoc):
    '''Test step export/import.'''
    filePath = os.path.join(fix_testDir, 'tmp_testExport.stp')
    from qmt.geometry.freecad.geomUtils import makeBB
    testBB = (-1., 1.5, -2., 2.5, -3., 3.5)
    testShape = makeBB(testBB)
    exportCAD([testShape], filePath)

    Part.insert(filePath, fix_FCDoc.Name)
    CADImport = fix_FCDoc.getObject("tmp_testExport")

    import FreeCAD
    transBB = testBB[0:][::2] + testBB[
        1:][::2]  # reformat to FreeCAD representation
    refBB = FreeCAD.Base.BoundBox(*transBB)
    assert repr(CADImport.Shape.BoundBox) == repr(refBB)

    os.remove(filePath)

    with pytest.raises(TypeError) as err:
        exportCAD(testShape, 'dummy.stp')
    assert 'must be a list' in str(err.value)

    with pytest.raises(ValueError) as err:
        exportCAD([testShape], 'not_a_step_file')
    assert 'not a supported extension' in str(err.value)
示例#3
0
def test_exportMeshed(datadir, fix_FCDoc):
    """Test mesh export/import."""
    filePath = os.path.join(datadir, "testExport.stl")
    from qmt.geometry.freecad.geomUtils import makeBB

    testBB = (-1.0, 1.0, -2.0, 2.0, -3.0, 3.0)
    testShape = makeBB(testBB)
    exportMeshed([testShape], filePath)
    Mesh.insert(filePath, "testDoc")
    meshImport = fix_FCDoc.getObject("testExport")
    xMin = meshImport.Mesh.BoundBox.XMin
    xMax = meshImport.Mesh.BoundBox.XMax
    yMin = meshImport.Mesh.BoundBox.YMin
    yMax = meshImport.Mesh.BoundBox.YMax
    zMin = meshImport.Mesh.BoundBox.ZMin
    zMax = meshImport.Mesh.BoundBox.ZMax
    assert testBB == (xMin, xMax, yMin, yMax, zMin, zMax)
示例#4
0
def test_exportMeshed(fix_testDir, fix_FCDoc):
    '''Test mesh export/import.'''
    filePath = os.path.join(fix_testDir, 'testExport.stl')
    from qmt.geometry.freecad.geomUtils import makeBB
    testBB = (-1., 1., -2., 2., -3., 3.)
    testShape = makeBB(testBB)
    exportMeshed(testShape, filePath)
    Mesh.insert(filePath, 'testDoc')
    meshImport = fix_FCDoc.getObject("testExport")
    xMin = meshImport.Mesh.BoundBox.XMin
    xMax = meshImport.Mesh.BoundBox.XMax
    yMin = meshImport.Mesh.BoundBox.YMin
    yMax = meshImport.Mesh.BoundBox.YMax
    zMin = meshImport.Mesh.BoundBox.ZMin
    zMax = meshImport.Mesh.BoundBox.ZMax
    assert testBB == (xMin, xMax, yMin, yMax, zMin, zMax)
    os.remove(filePath)
示例#5
0
def initialize_lithography(info, opts, fillShells=True):
    doc = FreeCAD.ActiveDocument
    info.fillShells = fillShells
    # The lithography step requires some infrastructure to track things
    # throughout.
    info.lithoDict = {
    }  # dictionary containing objects for the lithography step
    layers = info.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.
    info.lithoDict["substrate"] = {(): []}

    # To start, we need to collect up all the lithography directives, and
    # organize them by layer_num and objectIDs within layers.
    base_substrate_parts = []
    for part in opts["input_parts"]:
        # If this part is a litho step
        if isinstance(part, part_3d.LithographyPart):
            layer_num = part.layer_num  # layer_num of this part
            # Add the layer_num to the layer dictionary:
            if layer_num not in layers:
                layers[layer_num] = {"objIDs": {}}
            layer = layers[layer_num]
            # Generate the base and thickness of the layer:
            layer_base = float(part.z0)
            layer_thickness = float(part.thickness)
            # All parts within a given layer number are required to have
            # identical thickness and base, so check that:
            if "base" in layer:
                assert layer_base == layer["base"]
            else:
                layer["base"] = layer_base
            if "thickness" in layer:
                assert layer_thickness == layer["thickness"]
            else:
                layer["thickness"] = layer_thickness
            # 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 = get_freecad_object(doc, part.fc_name)
            splitSketches = splitSketch(sketch)
            for mySplitSketch in splitSketches:
                objID = len(layer["objIDs"])
                objDict = {}
                objDict["partName"] = part.fc_name
                objDict["sketch"] = mySplitSketch
                info.trash.append(mySplitSketch)
                layers[layer_num]["objIDs"][objID] = objDict
            # Add the base substrate to the appropriate dictionary
            base_substrate_parts += part.litho_base

    # Get rid of any duplicates:
    base_substrate_parts = list(set(base_substrate_parts))

    # Now convert the part names for the substrate into 3D freeCAD objects, which
    # should have already been rendered.
    for base_substrate in base_substrate_parts:
        try:
            built_part_name = opts["built_part_names"][base_substrate.label]
        except:
            raise KeyError(f"No substrate built for '{base_substrate.label}'")
        info.lithoDict["substrate"][()] += [
            get_freecad_object(doc, built_part_name)
        ]
    # ~ import sys
    # ~ sys.stderr.write(">>> litdic " + str(info.lithoDict) + "\n")

    # 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:

    bottom = min(layer["base"] for layer in layers.values())
    totalThickness = sum(layer["thickness"] for layer in layers.values())

    assert (len(info.lithoDict["substrate"][()]) > 0
            )  # Otherwise, we don't have a reference for the lateral BB
    substrateUnion = genUnion(info.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.
    info.lithoDict["boundingBox"] = [BB, constructionZone]
    delete(substrateUnion)  # not needed for next steps
    delete(constructionZone)  # not needed for next steps  ... WHY?

    # 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 layer_num in layers.keys():
        base = layers[layer_num]["base"]
        thickness = layers[layer_num]["thickness"]
        for objID in layers[layer_num]["objIDs"]:
            sketch = layers[layer_num]["objIDs"][objID]["sketch"]
            B = extrudeBetween(sketch, base, base + thickness)
            C = extrudeBetween(sketch, base, BB[5])
            layers[layer_num]["objIDs"][objID]["B"] = B
            layers[layer_num]["objIDs"][objID]["C"] = C
            info.trash.append(B)
            info.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.
            layers[layer_num]["objIDs"][objID]["HDict"] = {}