diff --git a/src/bonsai/bonsai/bim/module/profile/operator.py b/src/bonsai/bonsai/bim/module/profile/operator.py index 9306efc7ef..ef62d8b604 100644 --- a/src/bonsai/bonsai/bim/module/profile/operator.py +++ b/src/bonsai/bonsai/bim/module/profile/operator.py @@ -26,6 +26,7 @@ import bonsai.core.profile as core from bonsai.bim.module.model.decorator import ProfileDecorator from bonsai.bim.module.profile.prop import generate_thumbnail_for_active_profile from bonsai.bim.module.profile.data import refresh +from bonsai.bim.module.geometry.helper import Helper class LoadProfiles(bpy.types.Operator): @@ -151,35 +152,36 @@ class AddProfileDef(bpy.types.Operator, tool.Ifc.Operator): bl_options = {"REGISTER", "UNDO"} def _execute(self, context): - obj_points = [] - obj = context.scene.BIMProfileProperties.object_to_profile - if obj: - if len(obj.data.polygons) != 1: - self.report( - {"WARNING"}, - "This mesh is invalid to create a profile. Select a flat mesh with no more then one face.", - ) - return - for v in obj.data.polygons[0].vertices: - vert = obj.data.vertices[v] - if vert.co.z > 0: - self.report( - {"WARNING"}, - "This mesh is invalid to create a profile. Select a flat mesh with all its vertices at z=0", - ) - return - obj_points.append((vert.co.x, vert.co.y)) - if obj_points: - obj_points.append(obj_points[0]) - obj_points = [ - (v[0] - obj_points[0][0], v[1] - obj_points[0][1]) for v in obj_points - ] # Make sure the first point is (0, 0) - props = context.scene.BIMProfileProperties profile_class = props.profile_classes if profile_class == "IfcArbitraryClosedProfileDef": - points = [(0, 0), (0.1, 0), (0.1, 0.1), (0, 0.1), (0, 0)] if not obj_points else obj_points - profile = ifcopenshell.api.run("profile.add_arbitrary_profile", tool.Ifc.get(), profile=points) + obj = props.object_to_profile + if obj: + if len(obj.data.polygons) == 0: + self.report({"WARNING"}, "This mesh is invalid to create a profile. Select a flat mesh with at least one face.") + props.object_to_profile = None + return + helper = Helper(tool.Ifc.get()) + indices = helper.auto_detect_arbitrary_profile_with_voids_extruded_area_solid(obj.data) + if not indices["inner_curves"]: + indices = helper.auto_detect_arbitrary_closed_profile_extruded_area_solid(obj.data) + props.object_to_profile = None + if not indices: + points = [(0, 0), (0.1, 0), (0.1, 0.1), (0, 0.1), (0, 0)] + profile = ifcopenshell.api.run("profile.add_arbitrary_profile", tool.Ifc.get(), profile=points) + else: + if "inner_curves" not in indices: + points = [(obj.data.vertices[i].co.x,obj.data.vertices[i].co.y) for i in indices["profile"]] + points.append(points[0]) + profile = ifcopenshell.api.run("profile.add_arbitrary_profile", tool.Ifc.get(), profile=points) + else: + outer_points = [(obj.data.vertices[i].co.x,obj.data.vertices[i].co.y) for i in indices["profile"]] + outer_points.append(outer_points[0]) + inner_points = [[(obj.data.vertices[i].co.x,obj.data.vertices[i].co.y) for i in curve] for curve in indices["inner_curves"]] + for curve in inner_points: + curve.append(curve[0]) + profile = ifcopenshell.api.run("profile.add_arbitrary_profile_with_voids", tool.Ifc.get(), outer_profile=outer_points, inner_profiles=inner_points) + else: profile = ifcopenshell.api.run("profile.add_parameterized_profile", tool.Ifc.get(), ifc_class=profile_class) tool.Profile.set_default_profile_attrs(profile)