mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 03:14:23 +00:00
Merge branch 'v0.8.0' into ifcmax/initial-refresh
This commit is contained in:
@@ -83,6 +83,7 @@ class BIM_PT_bsdd(Panel):
|
||||
row = self.layout.row()
|
||||
row.operator("bim.load_bsdd_dictionaries")
|
||||
|
||||
|
||||
class BIM_UL_bsdd_dictionaries(UIList):
|
||||
def draw_item(
|
||||
self,
|
||||
|
||||
@@ -37,6 +37,7 @@ messages = {
|
||||
class CadTrimExtend(bpy.types.Operator):
|
||||
bl_idname = "bim.cad_trim_extend"
|
||||
bl_label = "CAD Trim / Extend"
|
||||
bl_description = "Extends/reduces element to 3D cursor"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -82,6 +83,7 @@ class CadTrimExtend(bpy.types.Operator):
|
||||
class CadMitre(bpy.types.Operator):
|
||||
bl_idname = "bim.cad_mitre"
|
||||
bl_label = "CAD Mitre"
|
||||
bl_description = "Joins two non-parallel paths at their intersection"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
||||
@@ -106,23 +106,37 @@ class CadTool(WorkSpaceTool):
|
||||
)
|
||||
|
||||
row = layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Extend", "S_E", "Extends/reduces element to 3D cursor", ui_context)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", "Joins two non-parallel paths at their intersection", ui_context
|
||||
row, "Extend", "S_E", bpy.ops.bim.cad_trim_extend.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Fillet", "S_F", bpy.ops.bim.add_ifcarcindex_fillet.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", bpy.ops.bim.cad_mitre.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Fillet", "S_F", bpy.ops.bim.add_ifcarcindex_fillet.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Rectangle", "S_R", bpy.ops.bim.add_rectangle.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Circle", "S_C", bpy.ops.bim.add_ifccircle.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Rectangle", "S_R", bpy.ops.bim.add_rectangle.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "3-Point Arc", "S_V", bpy.ops.bim.set_arc_index.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Circle", "S_C", bpy.ops.bim.add_ifccircle.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Reset Vertex", "S_X", bpy.ops.bim.reset_vertex.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "3-Point Arc", "S_V", bpy.ops.bim.set_arc_index.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Reset Vertex", "S_X", bpy.ops.bim.reset_vertex.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
|
||||
elif (
|
||||
isinstance(data, tool.Geometry.TYPES_WITH_MESH_PROPERTIES)
|
||||
@@ -132,15 +146,21 @@ class CadTool(WorkSpaceTool):
|
||||
layout, "Edit Axis", "bim.edit_extrusion_axis", "bim.disable_editing_extrusion_axis", ui_context
|
||||
)
|
||||
row = layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Extend", "S_E", "Extends/reduces element to 3D cursor", ui_context)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", "Joins two non-parallel paths at their intersection", ui_context
|
||||
row, "Extend", "S_E", bpy.ops.bim.cad_trim_extend.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Fillet", "S_F", bpy.ops.bim.cad_fillet.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", bpy.ops.bim.cad_mitre.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Fillet", "S_F", bpy.ops.bim.cad_fillet.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
|
||||
else:
|
||||
if (
|
||||
@@ -168,19 +188,37 @@ class CadTool(WorkSpaceTool):
|
||||
add_layout_hotkey_operator(row, "Set Gable Roof Angle", "S_R", "Set Gable Roof Angle", ui_context)
|
||||
|
||||
row = layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Extend", "S_E", "Extends/reduces element to 3D cursor", ui_context)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", "Joins two non-parallel paths at their intersection", ui_context
|
||||
row, "Extend", "S_E", bpy.ops.bim.cad_trim_extend.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Fillet", "S_F", bpy.ops.bim.add_ifcarcindex_fillet.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Join", "S_T", bpy.ops.bim.cad_mitre.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Fillet", "S_F", bpy.ops.bim.add_ifcarcindex_fillet.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "2-Point Arc", "S_C", bpy.ops.bim.cad_arc_from_2_points.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row, "Offset", "S_O", bpy.ops.bim.cad_offset.__doc__.split("\n", 1)[1].strip(), ui_context
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(row, "3-Point Arc", "S_V", bpy.ops.bim.cad_arc_from_3_points.__doc__, ui_context)
|
||||
add_layout_hotkey_operator(
|
||||
row,
|
||||
"2-Point Arc",
|
||||
"S_C",
|
||||
bpy.ops.bim.cad_arc_from_2_points.__doc__.split("\n", 1)[1].strip(),
|
||||
ui_context,
|
||||
)
|
||||
row = row if ui_context == "TOOL_HEADER" else layout.row(align=True)
|
||||
add_layout_hotkey_operator(
|
||||
row,
|
||||
"3-Point Arc",
|
||||
"S_V",
|
||||
bpy.ops.bim.cad_arc_from_3_points.__doc__.split("\n", 1)[1].strip(),
|
||||
ui_context,
|
||||
)
|
||||
|
||||
|
||||
class CadHotkey(bpy.types.Operator):
|
||||
|
||||
@@ -3364,57 +3364,55 @@ class OrderTextLiteralDown(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
# Ifc Operator is unnecessary, because suboperator is handling IFC changes.
|
||||
class AssignSelectedObjectAsProduct(bpy.types.Operator):
|
||||
class AssignSelectedObjectAsProduct(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.assign_selected_as_product"
|
||||
bl_label = "Assign Selected Object As Product"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
if len(context.selected_objects) != 2:
|
||||
cls.poll_message_set("2 objects need to be selected")
|
||||
if len(context.selected_objects) < 2:
|
||||
cls.poll_message_set("At least 2 objects need to be selected")
|
||||
return False
|
||||
return True
|
||||
|
||||
def execute(self, context):
|
||||
assert bpy.context.view_layer
|
||||
def _execute(self, context):
|
||||
objs = context.selected_objects[:]
|
||||
obj1, obj2 = objs
|
||||
element1 = tool.Ifc.get_entity(obj1)
|
||||
element2 = tool.Ifc.get_entity(obj2)
|
||||
assert element1 and element2
|
||||
ifc_objs = [(o, tool.Ifc.get_entity(o)) for o in objs if tool.Ifc.get_entity(o)]
|
||||
|
||||
# Check if at least one object is an IfcAnnotation
|
||||
is_annotation1 = element1.is_a("IfcAnnotation")
|
||||
is_annotation2 = element2.is_a("IfcAnnotation")
|
||||
annotations = [(o, e) for o, e in ifc_objs if e.is_a("IfcAnnotation")]
|
||||
non_annotations = [(o, e) for o, e in ifc_objs if not e.is_a("IfcAnnotation")]
|
||||
|
||||
if not (is_annotation1 or is_annotation2):
|
||||
self.report({"ERROR"}, "At least one of the selected objects must be IfcAnnotation.")
|
||||
if not annotations:
|
||||
self.report({"ERROR"}, "At least one selected object must be an IfcAnnotation.")
|
||||
return {"CANCELLED"}
|
||||
|
||||
# If both are annotations, use the currently active object as relating product
|
||||
if is_annotation1 and is_annotation2:
|
||||
if len(non_annotations) == 1:
|
||||
# One product, one or more annotations — assign all annotations to the product.
|
||||
product = non_annotations[0][1]
|
||||
elif len(non_annotations) == 0 and len(annotations) == 2:
|
||||
# Both objects are annotations — use the non-active one as the relating product.
|
||||
active_obj = context.active_object
|
||||
if active_obj == obj1:
|
||||
other_selected_object = obj1
|
||||
bpy.context.view_layer.objects.active = obj2
|
||||
if annotations[0][0] == active_obj:
|
||||
annotation_obj, annotation = annotations[0]
|
||||
product = annotations[1][1]
|
||||
else:
|
||||
other_selected_object = obj2
|
||||
bpy.context.view_layer.objects.active = obj1
|
||||
# If only one is an annotation, make it the active object
|
||||
elif is_annotation1:
|
||||
other_selected_object = obj2
|
||||
bpy.context.view_layer.objects.active = obj1
|
||||
annotation_obj, annotation = annotations[1]
|
||||
product = annotations[0][1]
|
||||
core.edit_assigned_product(tool.Ifc, tool.Drawing, obj=annotation_obj, product=product)
|
||||
tool.Blender.update_viewport()
|
||||
return
|
||||
else:
|
||||
other_selected_object = obj1
|
||||
bpy.context.view_layer.objects.active = obj2
|
||||
self.report(
|
||||
{"ERROR"},
|
||||
"Select exactly one product object and one or more IfcAnnotation objects.",
|
||||
)
|
||||
return {"CANCELLED"}
|
||||
|
||||
assert (active_obj := context.active_object)
|
||||
props = tool.Drawing.get_object_assigned_product_props(active_obj)
|
||||
props.relating_product = other_selected_object
|
||||
bpy.ops.bim.edit_assigned_product()
|
||||
return {"FINISHED"}
|
||||
for annotation_obj, _ in annotations:
|
||||
core.edit_assigned_product(tool.Ifc, tool.Drawing, obj=annotation_obj, product=product)
|
||||
|
||||
tool.Blender.update_viewport()
|
||||
|
||||
|
||||
class EditAssignedProduct(bpy.types.Operator, tool.Ifc.Operator):
|
||||
@@ -3886,8 +3884,7 @@ class AddReferenceImage(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
||||
image_filepath = Path(tool.Ifc.get_uri(self.filepath, use_relative_path=self.use_relative_path))
|
||||
ifc_file = tool.Ifc.get()
|
||||
|
||||
params = {"check_existing": False}
|
||||
image = load_image(abs_path.name, str(abs_path.parent), **params)
|
||||
image = load_image(abs_path.name, str(abs_path.parent), check_existing=False)
|
||||
|
||||
mesh = bpy.data.meshes.new(image_filepath.stem)
|
||||
obj = bpy.data.objects.new(image_filepath.stem, mesh)
|
||||
|
||||
@@ -82,7 +82,7 @@ def add_object(self: "BIM_OT_add_object", context: bpy.types.Context) -> None:
|
||||
|
||||
|
||||
class BIM_OT_add_object(Operator, tool.Ifc.Operator):
|
||||
bl_idname = "mesh.add_grid"
|
||||
bl_idname = "bim.add_grid"
|
||||
bl_label = "Grid"
|
||||
bl_description = "Add IfcGrid."
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@@ -76,6 +76,7 @@ classes = (
|
||||
operator.UnlinkIfc,
|
||||
operator.UnloadLink,
|
||||
workspace.ExploreHotkey,
|
||||
workspace.GenerateUVMap,
|
||||
prop.LibraryBreadcrumb,
|
||||
prop.LibraryElement,
|
||||
prop.FilterCategory,
|
||||
|
||||
@@ -87,6 +87,9 @@ class ExploreTool(bpy.types.WorkSpaceTool):
|
||||
op.hotkey = "S_S"
|
||||
op.description = "Scale Image Annotation. Allows to scale an IfcReferenceImage. Select image, select tool. Check lower left corner instructions to select two points and provide real distance between them"
|
||||
|
||||
op = row.operator("bim.generate_uv_map", text="Generate UV Map", icon="UV")
|
||||
op.description = "Generate UV map for selected mesh."
|
||||
|
||||
|
||||
class ExploreHotkey(bpy.types.Operator):
|
||||
bl_idname = "bim.explore_hotkey"
|
||||
@@ -153,3 +156,20 @@ class ExploreHotkey(bpy.types.Operator):
|
||||
|
||||
def hotkey_A_H(self) -> None:
|
||||
bpy.ops.bim.hide_queried_linked_element(unhide_all=True)
|
||||
|
||||
|
||||
class GenerateUVMap(bpy.types.Operator):
|
||||
bl_idname = "bim.generate_uv_map"
|
||||
bl_label = "Generate UV Map"
|
||||
bl_options = {"REGISTER", "UNDO", "INTERNAL"}
|
||||
|
||||
description: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
obj = context.active_object
|
||||
if not obj or not hasattr(obj, "data") or not hasattr(obj.data, "polygons"):
|
||||
self.report({"ERROR"}, "No valid mesh selected.")
|
||||
return {"CANCELLED"}
|
||||
tool.Loader.load_generated_uv_map(obj.data)
|
||||
self.report({"INFO"}, "Generated UV map for selected mesh.")
|
||||
return {"FINISHED"}
|
||||
@@ -251,7 +251,7 @@ class BIM_PT_grids(Panel):
|
||||
bl_options = {"HEADER_LAYOUT_EXPAND"}
|
||||
|
||||
def draw(self, context):
|
||||
self.layout.row().operator("mesh.add_grid", icon="ADD", text="Add Grids")
|
||||
self.layout.row().operator("bim.add_grid", icon="ADD", text="Add Grids")
|
||||
|
||||
def draw_header(self, context):
|
||||
props = tool.Spatial.get_grid_props()
|
||||
|
||||
@@ -143,7 +143,9 @@ def assign_material(
|
||||
material_tool.add_material_to_set(material_set=material, material=default_material)
|
||||
elif material_tool.is_a_material_set(assigned_material):
|
||||
material_tool.add_material_to_set(material_set=assigned_material, material=material)
|
||||
material_tool.ensure_material_assigned(elements=[element], material_type=element_material_type, material=material)
|
||||
material_tool.ensure_material_assigned(
|
||||
elements=[element], material_type=element_material_type, material=material
|
||||
)
|
||||
|
||||
|
||||
def unassign_material(ifc: type[tool.Ifc], material_tool: type[tool.Material], objects: list[bpy.types.Object]) -> None:
|
||||
|
||||
@@ -310,9 +310,84 @@ Scenario: Create sheet - with a drawing added to it
|
||||
When I click "OUTPUT"
|
||||
Then the file "{ifc_dir}/sheets/A01 - UNTITLED.svg" should contain "IfcWall"
|
||||
|
||||
Scenario: Enable editing text
|
||||
Given an empty IFC project
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I save IFC project
|
||||
And I look at the "Drawings" panel
|
||||
And I click "IMPORT"
|
||||
And I click "ADD"
|
||||
And I press "bim.toggle_target_view(option="EXPAND", target_view='PLAN_VIEW')"
|
||||
And I select the "PLAN_VIEW" item in the "BIM_UL_drawinglist" list
|
||||
And I click "VIEW_CAMERA_UNSELECTED" in the row where I see "PLAN_VIEW" in the "1st" list
|
||||
And I press "bim.add_annotation"
|
||||
And the object "IfcAnnotation/TEXT" is selected
|
||||
And I look at the "BIM_PT_text" panel
|
||||
When I click "Enable Editing Text"
|
||||
Then I see "Literals:"
|
||||
And I don't see "FontSize"
|
||||
|
||||
Scenario: Disable editing text
|
||||
Given an empty IFC project
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I save IFC project
|
||||
And I look at the "Drawings" panel
|
||||
And I click "IMPORT"
|
||||
And I click "ADD"
|
||||
And I press "bim.toggle_target_view(option="EXPAND", target_view='PLAN_VIEW')"
|
||||
And I select the "PLAN_VIEW" item in the "BIM_UL_drawinglist" list
|
||||
And I click "VIEW_CAMERA_UNSELECTED" in the row where I see "PLAN_VIEW" in the "1st" list
|
||||
And I press "bim.add_annotation"
|
||||
And the object "IfcAnnotation/TEXT" is selected
|
||||
And I look at the "BIM_PT_text" panel
|
||||
And I click "Enable Editing Text"
|
||||
When I click "CANCEL"
|
||||
Then I see "FontSize"
|
||||
And I don't see "Literals:"
|
||||
|
||||
Scenario: Edit text - no changes
|
||||
Given an empty IFC project
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I save IFC project
|
||||
And I look at the "Drawings" panel
|
||||
And I click "IMPORT"
|
||||
And I click "ADD"
|
||||
And I press "bim.toggle_target_view(option="EXPAND", target_view='PLAN_VIEW')"
|
||||
And I select the "PLAN_VIEW" item in the "BIM_UL_drawinglist" list
|
||||
And I click "VIEW_CAMERA_UNSELECTED" in the row where I see "PLAN_VIEW" in the "1st" list
|
||||
And I press "bim.add_annotation"
|
||||
And the object "IfcAnnotation/TEXT" is selected
|
||||
And I look at the "BIM_PT_text" panel
|
||||
And I click "Enable Editing Text"
|
||||
When I click "Edit Text"
|
||||
Then I see "FontSize"
|
||||
And I don't see "Literals:"
|
||||
|
||||
Scenario: Edit text - change literal
|
||||
Given an empty IFC project
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I save IFC project
|
||||
And I look at the "Drawings" panel
|
||||
And I click "IMPORT"
|
||||
And I click "ADD"
|
||||
And I press "bim.toggle_target_view(option="EXPAND", target_view='PLAN_VIEW')"
|
||||
And I select the "PLAN_VIEW" item in the "BIM_UL_drawinglist" list
|
||||
And I click "VIEW_CAMERA_UNSELECTED" in the row where I see "PLAN_VIEW" in the "1st" list
|
||||
And I press "bim.add_annotation"
|
||||
And the object "IfcAnnotation/TEXT" is selected
|
||||
And I look at the "BIM_PT_text" panel
|
||||
And I click "Enable Editing Text"
|
||||
And I set the "Literal" property to "Hello World"
|
||||
When I click "Edit Text"
|
||||
Then I see "Hello World"
|
||||
|
||||
Scenario: Add reference image
|
||||
Given an empty IFC project
|
||||
And I save IFC project
|
||||
When I press "bim.add_reference_image(filepath='{cwd}/test/files/image.jpg')"
|
||||
When I press "bim.add_reference_image(filepath='{cwd}/test/files/image.jpg', x_length=1, y_length=0.565)"
|
||||
Then the object "IfcAnnotation/image" exists
|
||||
And the object "IfcAnnotation/image" dimensions are "1.0,0.565,0."
|
||||
|
||||
@@ -57,7 +57,7 @@ Scenario: Add one type from the Construction Type Browser
|
||||
|
||||
Scenario: Add grid
|
||||
Given an empty IFC project
|
||||
When I press "mesh.add_grid"
|
||||
When I press "bim.add_grid"
|
||||
Then the object "IfcGrid/Grid" is an "IfcGrid"
|
||||
And the object "IfcGridAxis/A" is an "IfcGridAxis"
|
||||
And the object "IfcGridAxis/B" is an "IfcGridAxis"
|
||||
|
||||
@@ -914,7 +914,7 @@ Scenario: Export IFC - with moved object location synchronised
|
||||
|
||||
Scenario: Export IFC - with moved grid axis location synchronised
|
||||
Given an empty IFC project
|
||||
And I press "mesh.add_grid"
|
||||
And I press "bim.add_grid"
|
||||
When the object "IfcGridAxis/01" is moved to "1,0,0"
|
||||
And I save IFC project
|
||||
And I load previously saved IFC project
|
||||
|
||||
@@ -378,7 +378,7 @@ def i_look_at_the_panel_panel(panel: str) -> None:
|
||||
# Option to provide explicit panel name if panel names overlap.
|
||||
panel_class = getattr(bpy.types, panel, None)
|
||||
|
||||
if panel_class is None:
|
||||
if panel_class is None or panel_class.bl_rna.base.name not in ("Panel", "Operator", "Menu", "UIList"):
|
||||
global ui_name_cache
|
||||
create_ui_name_cache()
|
||||
if panel not in ui_name_cache:
|
||||
|
||||
Reference in New Issue
Block a user