From a0f7a704199ef6f86a3f7f2658c5c2c635d27f8a Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 10 Aug 2021 22:16:45 +1000 Subject: [PATCH] Parametric types can how define a default layer set direction. --- .../blenderbim/bim/module/model/product.py | 18 ++++++++- .../blenderbim/bim/module/model/slab.py | 40 ++++++++++--------- .../blenderbim/bim/module/model/wall.py | 36 +++++++++-------- src/blenderbim/generate_demo_library.py | 12 +++++- 4 files changed, 69 insertions(+), 37 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/model/product.py b/src/blenderbim/blenderbim/bim/module/model/product.py index 0c0fb24f47..d3faa0e2ed 100644 --- a/src/blenderbim/blenderbim/bim/module/model/product.py +++ b/src/blenderbim/blenderbim/bim/module/model/product.py @@ -35,10 +35,24 @@ class AddTypeInstance(bpy.types.Operator): if obj: return {"FINISHED"} elif material.is_a("IfcMaterialLayerSet"): - if ifc_class in ["IfcSlabType", "IfcRoofType", "IfcRampType", "IfcPlateType"]: + layer_set_direction = None + + parametric = ifcopenshell.util.element.get_psets(relating_type).get("EPset_Parametric") + if parametric: + layer_set_direction = parametric.get("LayerSetDirection", layer_set_direction) + if layer_set_direction is None: + if ifc_class in ["IfcSlabType", "IfcRoofType", "IfcRampType", "IfcPlateType"]: + layer_set_direction = "AXIS3" + else: + layer_set_direction = "AXIS2" + + if layer_set_direction == "AXIS3": obj = slab.DumbSlabGenerator(relating_type).generate() - else: + elif layer_set_direction == "AXIS2": obj = wall.DumbWallGenerator(relating_type).generate() + else: + obj = None # Dumb block generator? Eh? :) + if obj: return {"FINISHED"} # A cube diff --git a/src/blenderbim/blenderbim/bim/module/model/slab.py b/src/blenderbim/blenderbim/bim/module/model/slab.py index b16b0b847b..6c1a341f5d 100644 --- a/src/blenderbim/blenderbim/bim/module/model/slab.py +++ b/src/blenderbim/blenderbim/bim/module/model/slab.py @@ -31,7 +31,7 @@ def mode_callback(obj, data): return product = IfcStore.get_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.DumbSlab": + if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer3": return IfcStore.edited_objs.add(obj) modifier = [m for m in obj.modifiers if m.type == "SOLIDIFY"] @@ -59,7 +59,7 @@ def mode_callback(obj, data): def ensure_solid(usecase_path, ifc_file, settings): product = ifc_file.by_id(settings["blender_object"].BIMObjectProperties.ifc_definition_id) parametric = ifcopenshell.util.element.get_psets(product).get("EPset_Parametric") - if not parametric or parametric["Engine"] != "BlenderBIM.DumbSlab": + if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer3": return settings["ifc_representation_class"] = "IfcExtrudedAreaSolid/IfcArbitraryProfileDefWithVoids" @@ -71,7 +71,7 @@ def generate_footprint(usecase_path, ifc_file, settings): 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.DumbSlab": + 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": @@ -89,7 +89,7 @@ def generate_footprint(usecase_path, ifc_file, settings): profile_edges = [] def append_profile_edges(profile_edges, indices): - indices.append(indices[0]) # Close the loop + indices.append(indices[0]) # Close the loop edge_vert_pairs = list(zip(indices, indices[1:])) for p in edge_vert_pairs: profile_edges.append( @@ -127,7 +127,7 @@ def calculate_quantities(usecase_path, ifc_file, settings): 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.DumbSlab": + 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" @@ -145,7 +145,7 @@ def calculate_quantities(usecase_path, ifc_file, settings): bm.verts.ensure_lookup_table() def calculate_profile_length(indices): - indices.append(indices[0]) # Close the loop + 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]) @@ -171,7 +171,7 @@ def calculate_quantities(usecase_path, ifc_file, settings): net_volume = gross_volume bm.free() - properties={ + properties = { "Depth": round(depth, 2), "Perimeter": round(perimeter, 2), "GrossArea": round(gross_area, 2), @@ -181,17 +181,21 @@ def calculate_quantities(usecase_path, ifc_file, settings): } 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), - }) + properties.update( + { + "Length": round(length, 2), + "Width": round(width, 2), + } + ) else: - properties.update({ - "Length": None, - "Width": None, - }) + properties.update( + { + "Length": None, + "Width": None, + } + ) - ifcopenshell.api.run( "pset.edit_qto", ifc_file, should_run_listeners=False, qto=qto, properties=properties) + 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) @@ -298,7 +302,7 @@ class DumbSlabGenerator: bpy.ops.bim.assign_type(relating_type=self.relating_type.id(), related_object=obj.name) element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="EPset_Parametric") - ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Engine": "BlenderBIM.DumbSlab"}) + ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Engine": "BlenderBIM.DumbLayer3"}) MaterialData.load(self.file) obj.select_set(True) return obj @@ -339,7 +343,7 @@ class DumbSlabPlaner: def change_thickness(self, element, thickness): parametric = ifcopenshell.util.element.get_psets(element).get("EPset_Parametric") - if not parametric or parametric["Engine"] != "BlenderBIM.DumbSlab": + if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer3": return obj = IfcStore.get_element(element.id()) diff --git a/src/blenderbim/blenderbim/bim/module/model/wall.py b/src/blenderbim/blenderbim/bim/module/model/wall.py index 340ecf7612..f00d67db52 100644 --- a/src/blenderbim/blenderbim/bim/module/model/wall.py +++ b/src/blenderbim/blenderbim/bim/module/model/wall.py @@ -31,7 +31,7 @@ def mode_callback(obj, data): return product = IfcStore.get_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.DumbWall": + if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer2": return bpy.ops.bim.dynamically_void_product(obj=obj.name) IfcStore.edited_objs.add(obj) @@ -400,16 +400,20 @@ class DumbWallJoiner: # plane denoted by the target coordinate. def extend(self): wall1_min_faces, wall1_max_faces = self.get_wall_end_faces(self.wall1) - ef1_distance = abs(mathutils.geometry.distance_point_to_plane( - self.wall1_matrix @ self.wall1.data.vertices[wall1_min_faces[0].vertices[0]].co, - self.target_coordinate, - self.pos_x, - )) - ef2_distance = abs(mathutils.geometry.distance_point_to_plane( - self.wall1_matrix @ self.wall1.data.vertices[wall1_max_faces[0].vertices[0]].co, - self.target_coordinate, - self.neg_x, - )) + ef1_distance = abs( + mathutils.geometry.distance_point_to_plane( + self.wall1_matrix @ self.wall1.data.vertices[wall1_min_faces[0].vertices[0]].co, + self.target_coordinate, + self.pos_x, + ) + ) + ef2_distance = abs( + mathutils.geometry.distance_point_to_plane( + self.wall1_matrix @ self.wall1.data.vertices[wall1_max_faces[0].vertices[0]].co, + self.target_coordinate, + self.neg_x, + ) + ) if ef1_distance < ef2_distance: self.project_end_faces_to_target(wall1_min_faces) else: @@ -792,7 +796,7 @@ class DumbWallGenerator: bpy.ops.bim.assign_type(relating_type=self.relating_type.id(), related_object=obj.name) element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) pset = ifcopenshell.api.run("pset.add_pset", self.file, product=element, name="EPset_Parametric") - ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Engine": "BlenderBIM.DumbWall"}) + ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"Engine": "BlenderBIM.DumbLayer2"}) MaterialData.load(self.file) obj.select_set(True) return obj @@ -801,7 +805,7 @@ class DumbWallGenerator: def ensure_solid(usecase_path, ifc_file, settings): product = ifc_file.by_id(settings["blender_object"].BIMObjectProperties.ifc_definition_id) parametric = ifcopenshell.util.element.get_psets(product).get("EPset_Parametric") - if not parametric or parametric["Engine"] != "BlenderBIM.DumbWall": + if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer2": return settings["ifc_representation_class"] = "IfcExtrudedAreaSolid/IfcArbitraryClosedProfileDef" @@ -813,7 +817,7 @@ def generate_axis(usecase_path, ifc_file, settings): 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.DumbWall": + if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer2": return old_axis = ifcopenshell.util.representation.get_representation(product, "Model", "Axis", "GRAPH_VIEW") if settings["context"].ContextType == "Model" and getattr(settings["context"], "ContextIdentifier") == "Body": @@ -846,7 +850,7 @@ def calculate_quantities(usecase_path, ifc_file, settings): 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.DumbWall": + if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer2": return qto = ifcopenshell.api.run( "pset.add_qto", ifc_file, should_run_listeners=False, product=product, name="Qto_WallBaseQuantities" @@ -930,7 +934,7 @@ class DumbWallPlaner: def change_thickness(self, element, thickness): parametric = ifcopenshell.util.element.get_psets(element).get("EPset_Parametric") - if not parametric or parametric["Engine"] != "BlenderBIM.DumbWall": + if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer2": return obj = IfcStore.get_element(element.id()) diff --git a/src/blenderbim/generate_demo_library.py b/src/blenderbim/generate_demo_library.py index c76f4afcc4..0904fd8c84 100644 --- a/src/blenderbim/generate_demo_library.py +++ b/src/blenderbim/generate_demo_library.py @@ -17,7 +17,16 @@ class LibraryGenerator: self.create_layer_type("IfcWallType", "DEMO200", 0.2) self.create_layer_type("IfcWallType", "DEMO300", 0.3) - self.create_layer_type("IfcCoveringType", "DEMO20", 0.02) + self.create_layer_type("IfcCoveringType", "DEMO10", 0.01) + + product = self.create_layer_type("IfcCoveringType", "DEMO20", 0.02) + pset = ifcopenshell.api.run("pset.add_pset", self.file, product=product, name="EPset_Parametric") + ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"LayerSetDirection": "AXIS2"}) + + product = self.create_layer_type("IfcCoveringType", "DEMO30", 0.03) + pset = ifcopenshell.api.run("pset.add_pset", self.file, product=product, name="EPset_Parametric") + ifcopenshell.api.run("pset.edit_pset", self.file, pset=pset, properties={"LayerSetDirection": "AXIS3"}) + self.create_layer_type("IfcRampType", "DEMO200", 0.2) profile = self.file.create_entity( @@ -78,6 +87,7 @@ class LibraryGenerator: layer = ifcopenshell.api.run("material.add_layer", self.file, layer_set=layer_set, material=self.material) layer.LayerThickness = thickness ifcopenshell.api.run("project.assign_declaration", self.file, definition=element, relating_context=self.project) + return element def create_profile_type(self, ifc_class, name, profile): element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class=ifc_class, name=name)