diff --git a/src/blenderbim/blenderbim/bim/module/model/door.py b/src/blenderbim/blenderbim/bim/module/model/door.py index 8c5fb75e8d..ad5dc9750a 100644 --- a/src/blenderbim/blenderbim/bim/module/model/door.py +++ b/src/blenderbim/blenderbim/bim/module/model/door.py @@ -48,7 +48,7 @@ def update_door_modifier_representation(context): props = obj.BIMDoorProperties ifc_file = tool.Ifc.get() representation_data = { - "partition_type": props.door_type, + "operation_type": props.door_type, "overall_height": props.overall_height, "overall_width": props.overall_width, "lining_properties": { @@ -75,19 +75,30 @@ def update_door_modifier_representation(context): }, } - # ELEVATION_VIEW representation - ifc_context = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Profile", "ELEVATION_VIEW") - if not ifc_context: - model_context = ifcopenshell.util.representation.get_context(ifc_file, "Model") - ifc_context = ifcopenshell.api.run( - "context.add_context", - ifc_file, - context_type="Model", - context_identifier="Profile", - target_view="ELEVATION_VIEW", - parent=model_context, - ) + def get_context_or_create(context_type, context_identifier, target_view): + ifc_context = ifcopenshell.util.representation.get_context(ifc_file, context_type, context_identifier, target_view) + if not ifc_context: + parent_context = ifcopenshell.util.representation.get_context(ifc_file, context_type) + ifc_context = ifcopenshell.api.run( + "context.add_context", + ifc_file, + context_type=context_type, + context_identifier=context_identifier, + target_view=target_view, + parent=model_context, + ) + return ifc_context + # ELEVATION_VIEW representation + ifc_context = get_context_or_create("Model", "Profile", "ELEVATION_VIEW") + representation_data["context"] = ifc_context + elevation_representation = ifcopenshell.api.run( + "geometry.add_door_representation", ifc_file, **representation_data + ) + replace_representation_for_object(ifc_file, ifc_context, obj, elevation_representation) + + # PLAN_VIEW representation + ifc_context = get_context_or_create("Plan", "Annotation", "PLAN_VIEW") representation_data["context"] = ifc_context elevation_representation = ifcopenshell.api.run( "geometry.add_door_representation", ifc_file, **representation_data diff --git a/src/blenderbim/blenderbim/bim/module/model/prop.py b/src/blenderbim/blenderbim/bim/module/model/prop.py index 0b24f0b47c..563d915998 100644 --- a/src/blenderbim/blenderbim/bim/module/model/prop.py +++ b/src/blenderbim/blenderbim/bim/module/model/prop.py @@ -433,14 +433,14 @@ class BIMWindowProperties(PropertyGroup): class BIMDoorProperties(PropertyGroup): door_types = ( - ("DOUBLE_SWING_LEFT", "DOUBLE_SWING_LEFT", ""), - ("DOUBLE_SWING_RIGHT", "DOUBLE_SWING_RIGHT", ""), + ("SINGLE_SWING_LEFT", "SINGLE_SWING_LEFT", ""), + ("SINGLE_SWING_RIGHT", "SINGLE_SWING_RIGHT", ""), ) door_added_previously: bpy.props.BoolProperty(default=False) is_editing: bpy.props.IntProperty(default=-1) door_type: bpy.props.EnumProperty( - name="Door Operation Type", items=door_types, default="DOUBLE_SWING_LEFT" + name="Door Operation Type", items=door_types, default="SINGLE_SWING_LEFT" ) overall_height: bpy.props.FloatProperty(name="Overall Height", default=1.2) overall_width: bpy.props.FloatProperty(name="Overall Width", default=0.6) diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_door_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_door_representation.py index 7e12750fe4..c70a9a4dc9 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/geometry/add_door_representation.py +++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/add_door_representation.py @@ -126,22 +126,22 @@ class Usecase: }, } ) - for key, value in settings.items(): self.settings[key] = value - def execute(self): + def execute(self): builder = ShapeBuilder(self.file) overall_height = self.settings["overall_height"] overall_width = self.settings["overall_width"] + door_type = self.settings["operation_type"] + + if door_type not in ('SINGLE_SWING_LEFT', 'SINGLE_SWING_RIGHT'): + raise NotImplementedError(f'Door type "{door_type}" is not currently supported.') - # TODO: elevation view representation if self.settings["context"].TargetView == "ELEVATION_VIEW": rect = builder.rectangle(V(overall_width, 0, overall_height)) representation_evelevation = builder.get_representation(self.settings["context"], rect) return representation_evelevation - - # TODO: implement 2d representation panel_props = self.settings["panel_properties"] lining_props = self.settings["lining_properties"] @@ -191,14 +191,57 @@ class Usecase: lining_size = V(overall_width, lining_depth, lining_height) lining_thickness = [lining_thickness_default, top_lining_thickness] + def l_shape_check(lining_thickness): + return lining_to_panel_offset_y_full < lining_depth \ + and any(lining_to_panel_offset_x < th for th in lining_thickness) + + # create 2d representation + if self.settings["context"].TargetView == "PLAN_VIEW": + + items_2d = [] + + # create lining + if l_shape_check([lining_thickness_default]): + lining_points = [ + V(0, 0), + V(0, lining_depth), + V(lining_to_panel_offset_x, lining_depth), + V(lining_to_panel_offset_x, lining_to_panel_offset_y_full), + V(lining_thickness_default, lining_to_panel_offset_y_full), + V(lining_thickness_default, 0), + ] + lining = builder.polyline(lining_points, closed=True) + else: + lining = builder.rectangle(V(lining_thickness_default, lining_depth)) + + items_2d.append(lining) + items_2d.append(builder.mirror(lining, mirror_axes=V(1,0), mirror_point=V(overall_width/2, 0), create_copy=True)) + + # create semi-semi-circle + semicircle = builder.create_ellipse_curve(panel_width-panel_depth, + panel_width, + trim_points_mask=(0,1), + position=V(panel_depth, 0)) + items_2d.append(semicircle) + + # create door + door = builder.rectangle(V(panel_depth, panel_width)) + items_2d.append(door) + + builder.translate([semicircle, door], V(lining_to_panel_offset_x, lining_depth)) + + if door_type == 'SINGLE_SWING_RIGHT': + builder.mirror([semicircle, door], mirror_axes=V(1,0), mirror_point=V(overall_width/2, 0)) + + representation_2d = builder.get_representation(self.settings["context"], items_2d) + return representation_2d + lining_items = [] main_lining_size = lining_size + # need to check offsets to decide whether lining should be rectangle # or L shaped - l_shape_check = lining_to_panel_offset_y_full < lining_size.y \ - and any(lining_to_panel_offset_x < th for th in lining_thickness) - - if l_shape_check: + if l_shape_check(lining_thickness): main_lining_size = lining_size.copy() main_lining_size.y = lining_to_panel_offset_y_full @@ -289,7 +332,6 @@ class Usecase: builder.translate(lining_offset_items, V(0, lining_offset, 0)) ouput_items = lining_offset_items + threshold_items + casing_items - print(len(ouput_items), 'items ready') representation = builder.get_representation(self.settings["context"], ouput_items) return representation