Exemple #1
0
 def create_arbitrary_extrusion_representation(self):
     helper = Helper(self.file)
     indices = helper.auto_detect_arbitrary_closed_profile_extruded_area_solid(
         self.settings["geometry"])
     profile_def = helper.create_arbitrary_closed_profile_def(
         self.settings["geometry"], indices["profile"])
     item = helper.create_extruded_area_solid(self.settings["geometry"],
                                              indices["extrusion"],
                                              profile_def)
     return self.file.createIfcShapeRepresentation(
         self.settings["context"],
         self.settings["context"].ContextIdentifier,
         "SweptSolid",
         [item],
     )
Exemple #2
0
    def get_assign_connection_geometry_settings(cls, obj):
        ifc = tool.Ifc.get()
        helper = Helper(ifc)
        mesh = obj.data
        curves = helper.auto_detect_curve_bounded_plane(mesh)
        outer_boundary = cls.polyline_from_indexes(mesh, curves["outer_curve"])
        inner_boundaries = tuple(
            cls.polyline_from_indexes(mesh, boundary)
            for boundary in curves["inner_curves"])

        # Create placement matrix
        location = outer_boundary[0]
        i = (outer_boundary[1] - outer_boundary[0]).normalized()
        k = mesh.polygons[0].normal
        j = k.cross(i)
        matrix = mathutils.Matrix()
        matrix[0].xyz = i
        matrix[1].xyz = j
        matrix[2].xyz = k
        matrix.transpose()
        matrix.translation = location

        return {
            "rel_space_boundary":
            tool.Ifc.get_entity(obj),
            "outer_boundary":
            cls.polyline_to_2d(outer_boundary, matrix),
            "inner_boundaries":
            tuple(
                cls.polyline_to_2d(boundary, matrix)
                for boundary in inner_boundaries),
            "location":
            location,
            "axis":
            k,
            "ref_direction":
            i,
        }
Exemple #3
0
def calculate_quantities(usecase_path, ifc_file, settings):
    unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
    obj = settings["blender_object"]
    product = ifc_file.by_id(obj.BIMObjectProperties.ifc_definition_id)
    parametric = ifcopenshell.util.element.get_psets(product).get(
        "EPset_Parametric")
    if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer3":
        return
    qto = ifcopenshell.api.run("pset.add_qto",
                               ifc_file,
                               should_run_listeners=False,
                               product=product,
                               name="Qto_SlabBaseQuantities")
    length = obj.dimensions[0] / unit_scale
    width = obj.dimensions[1] / unit_scale
    depth = obj.dimensions[2] / unit_scale

    perimeter = 0
    helper = Helper(ifc_file)
    indices = helper.auto_detect_arbitrary_profile_with_voids_extruded_area_solid(
        settings["geometry"])

    bm = bmesh.new()
    bm.from_mesh(settings["geometry"])
    bm.verts.ensure_lookup_table()

    def calculate_profile_length(indices):
        indices.append(indices[0])  # Close the loop
        edge_vert_pairs = list(zip(indices, indices[1:]))
        return sum([(bm.verts[p[1]].co - bm.verts[p[0]].co).length
                    for p in edge_vert_pairs])

    perimeter += calculate_profile_length(indices["profile"])
    for inner_indices in indices["inner_curves"]:
        perimeter += calculate_profile_length(inner_indices)

    bm.free()

    if product.HasOpenings:
        # TODO: calculate gross / net
        gross_area = 0
        net_area = 0
        gross_volume = 0
        net_volume = 0
    else:
        bm = bmesh.new()
        bm.from_object(obj, bpy.context.evaluated_depsgraph_get())
        bm.faces.ensure_lookup_table()
        gross_area = sum([f.calc_area() for f in bm.faces if f.normal.z > 0.9])
        net_area = gross_area
        gross_volume = bm.calc_volume()
        net_volume = gross_volume
        bm.free()

    properties = {
        "Depth": round(depth, 2),
        "Perimeter": round(perimeter, 2),
        "GrossArea": round(gross_area, 2),
        "NetArea": round(net_area, 2),
        "GrossVolume": round(gross_volume, 2),
        "NetVolume": round(net_volume, 2),
    }

    if round(obj.dimensions[0] * obj.dimensions[1] * obj.dimensions[2],
             2) == round(gross_volume, 2):
        properties.update({
            "Length": round(length, 2),
            "Width": round(width, 2),
        })
    else:
        properties.update({
            "Length": None,
            "Width": None,
        })

    ifcopenshell.api.run("pset.edit_qto",
                         ifc_file,
                         should_run_listeners=False,
                         qto=qto,
                         properties=properties)
    PsetData.load(ifc_file, obj.BIMObjectProperties.ifc_definition_id)
Exemple #4
0
def generate_footprint(usecase_path, ifc_file, settings):
    footprint_context = ifcopenshell.util.representation.get_context(
        ifc_file, "Plan", "FootPrint", "SKETCH_VIEW")
    if not footprint_context:
        return
    obj = settings["blender_object"]
    product = ifc_file.by_id(obj.BIMObjectProperties.ifc_definition_id)
    parametric = ifcopenshell.util.element.get_psets(product).get(
        "EPset_Parametric")
    if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer3":
        return
    old_footprint = ifcopenshell.util.representation.get_representation(
        product, "Plan", "FootPrint", "SKETCH_VIEW")
    if settings["context"].ContextType == "Model" and getattr(
            settings["context"], "ContextIdentifier") == "Body":
        if old_footprint:
            blenderbim.core.geometry.remove_representation(
                tool.Ifc, tool.Geometry, obj=obj, representation=old_footprint)

        helper = Helper(ifc_file)
        indices = helper.auto_detect_arbitrary_profile_with_voids_extruded_area_solid(
            settings["geometry"])

        bm = bmesh.new()
        bm.from_mesh(settings["geometry"])
        bm.verts.ensure_lookup_table()
        bm.edges.ensure_lookup_table()

        profile_edges = []

        def append_profile_edges(profile_edges, indices):
            indices.append(indices[0])  # Close the loop
            edge_vert_pairs = list(zip(indices, indices[1:]))
            for p in edge_vert_pairs:
                profile_edges.append([
                    e for e in bm.verts[p[0]].link_edges
                    if e.other_vert(bm.verts[p[0]]).index == p[1]
                ][0])

        append_profile_edges(profile_edges, indices["profile"])
        for inner_indices in indices["inner_curves"]:
            append_profile_edges(profile_edges, inner_indices)

        irrelevant_edges = [e for e in bm.edges if e not in profile_edges]
        bmesh.ops.delete(bm, geom=irrelevant_edges, context="EDGES")
        mesh = bpy.data.meshes.new("Temporary Footprint")
        bm.to_mesh(mesh)
        bm.free()

        new_settings = settings.copy()
        new_settings["context"] = footprint_context
        new_settings["geometry"] = mesh
        new_footprint = ifcopenshell.api.run("geometry.add_representation",
                                             ifc_file,
                                             should_run_listeners=False,
                                             **new_settings)

        ifcopenshell.api.run("geometry.assign_representation",
                             ifc_file,
                             should_run_listeners=False,
                             **{
                                 "product": product,
                                 "representation": new_footprint
                             })
        bpy.data.meshes.remove(mesh)