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], )
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, }
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)
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)