mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-29 11:46:33 +00:00
Add tests for new element add feature
This commit is contained in:
@@ -189,8 +189,7 @@ Scenario: Update representation - updating a layered extrusion
|
|||||||
And I press "bim.edit_material_set_item(material_set_item={layer})"
|
And I press "bim.edit_material_set_item(material_set_item={layer})"
|
||||||
And I press "bim.edit_assigned_material(material_set={layer_set})"
|
And I press "bim.edit_assigned_material(material_set={layer_set})"
|
||||||
And the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
And the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
||||||
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
When I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
||||||
When I press "bim.update_representation(obj='IfcWall/Cube')"
|
|
||||||
Then the object "IfcWall/Cube" has a "SweptSolid" representation of "Model/Body/MODEL_VIEW"
|
Then the object "IfcWall/Cube" has a "SweptSolid" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|
||||||
Scenario: Update representation - updating a profiled extrusion
|
Scenario: Update representation - updating a profiled extrusion
|
||||||
|
|||||||
@@ -1,6 +1,70 @@
|
|||||||
@root
|
@root
|
||||||
Feature: Root
|
Feature: Root
|
||||||
|
|
||||||
|
Scenario: Add element - a type with no geometry
|
||||||
|
Given an empty IFC project
|
||||||
|
And I trigger "Add Element"
|
||||||
|
And I set the "Name" property to "Foo"
|
||||||
|
And I set the "Description" property to "Bar"
|
||||||
|
And I set the "Definition" property to "IfcElementType"
|
||||||
|
And I set the "Class" property to "IfcFurnitureType"
|
||||||
|
And I set the "Predefined Type" property to "SOFA"
|
||||||
|
And I set the "Representation" property to "No Geometry"
|
||||||
|
When I click "OK"
|
||||||
|
Then the object "IfcFurnitureType/Foo" exists
|
||||||
|
And the object "IfcFurnitureType/Foo" has no data
|
||||||
|
|
||||||
|
Scenario: Add element - an element with no geometry
|
||||||
|
Given an empty IFC project
|
||||||
|
And I trigger "Add Element"
|
||||||
|
And I set the "Definition" property to "IfcElement"
|
||||||
|
And I set the "Class" property to "IfcFurniture"
|
||||||
|
And I set the "Predefined Type" property to "SOFA"
|
||||||
|
And I set the "Representation" property to "Custom Extruded Solid"
|
||||||
|
When I click "OK"
|
||||||
|
And I select the object "IfcFurniture/Unnamed"
|
||||||
|
And I toggle edit mode
|
||||||
|
Then the object "Item/IfcExtrudedAreaSolid/77" exists
|
||||||
|
|
||||||
|
Scenario: Add element - an element with extrusion geometry
|
||||||
|
Given an empty IFC project
|
||||||
|
And I trigger "Add Element"
|
||||||
|
And I set the "Definition" property to "IfcElement"
|
||||||
|
And I set the "Class" property to "IfcFurniture"
|
||||||
|
And I set the "Predefined Type" property to "SOFA"
|
||||||
|
And I set the "Representation" property to "Custom Extruded Solid"
|
||||||
|
When I click "OK"
|
||||||
|
And I select the object "IfcFurniture/Unnamed"
|
||||||
|
And I toggle edit mode
|
||||||
|
Then the object "Item/IfcExtrudedAreaSolid/77" exists
|
||||||
|
|
||||||
|
Scenario: Add element - an element with custom tessellation geometry
|
||||||
|
Given an empty IFC project
|
||||||
|
And I trigger "Add Element"
|
||||||
|
And I set the "Definition" property to "IfcElement"
|
||||||
|
And I set the "Class" property to "IfcFurniture"
|
||||||
|
And I set the "Predefined Type" property to "SOFA"
|
||||||
|
And I set the "Representation" property to "Custom Tessellation"
|
||||||
|
When I click "OK"
|
||||||
|
And I select the object "IfcFurniture/Unnamed"
|
||||||
|
And I toggle edit mode
|
||||||
|
Then the object "Item/IfcPolygonalFaceSet/76" exists
|
||||||
|
|
||||||
|
Scenario: Add element - an element with tessellation geometry from an object
|
||||||
|
Given an empty IFC project
|
||||||
|
And I add a cube
|
||||||
|
And I trigger "Add Element"
|
||||||
|
And I set the "Definition" property to "IfcElement"
|
||||||
|
And I set the "Class" property to "IfcFurniture"
|
||||||
|
And I set the "Predefined Type" property to "SOFA"
|
||||||
|
And I set the "Representation" property to "Tessellation From Object"
|
||||||
|
And I set the "Object" property to "Cube"
|
||||||
|
When I click "OK"
|
||||||
|
And I select the object "IfcFurniture/Unnamed"
|
||||||
|
And I toggle edit mode
|
||||||
|
Then the object "Item/IfcPolygonalFaceSet/76" exists
|
||||||
|
And the object "Item/IfcPolygonalFaceSet/76" dimensions are "2,2,2"
|
||||||
|
|
||||||
Scenario: Reassign class
|
Scenario: Reassign class
|
||||||
Given an empty IFC project
|
Given an empty IFC project
|
||||||
And I add a cube
|
And I add a cube
|
||||||
@@ -77,7 +141,7 @@ Scenario: Assign a spatial class to a cube already in a collection
|
|||||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcSpace"
|
And I set "scene.BIMRootProperties.ifc_class" to "IfcSpace"
|
||||||
And I press "bim.assign_class"
|
And I press "bim.assign_class"
|
||||||
Then the object "IfcSpace/Cube" is an "IfcSpace"
|
Then the object "IfcSpace/Cube" is an "IfcSpace"
|
||||||
And the object "IfcSpace/Cube" is in the collection "IfcSpace/Cube"
|
And the object "IfcSpace/Cube" is in the collection "IfcSpace"
|
||||||
And the object "IfcSpace/Cube" has a "Tessellation" representation of "Model/Body/MODEL_VIEW"
|
And the object "IfcSpace/Cube" has a "Tessellation" representation of "Model/Body/MODEL_VIEW"
|
||||||
|
|
||||||
Scenario: Assign a class to a cube in a collection
|
Scenario: Assign a class to a cube in a collection
|
||||||
@@ -103,7 +167,7 @@ Scenario: Copy a wall
|
|||||||
Scenario: Copy a storey - when locked
|
Scenario: Copy a storey - when locked
|
||||||
Given an empty IFC project
|
Given an empty IFC project
|
||||||
And the object "IfcBuildingStorey/My Storey" is selected
|
And the object "IfcBuildingStorey/My Storey" is selected
|
||||||
When I duplicate the selected objects
|
Then I expect an error "Error: 'IfcBuildingStorey/My Storey' is locked. Unlock it via the Spatial panel in the Project Overview tab." when "i_duplicate_the_selected_objects()"
|
||||||
Then the object "IfcBuildingStorey/My Storey.001" does not exist
|
Then the object "IfcBuildingStorey/My Storey.001" does not exist
|
||||||
|
|
||||||
Scenario: Copy a storey - when unlocked
|
Scenario: Copy a storey - when unlocked
|
||||||
|
|||||||
@@ -65,12 +65,14 @@ class PanelSpy:
|
|||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
self.spied_attr = attr
|
self.spied_attr = attr
|
||||||
|
if annotation := self.panel.__annotations__.get(attr, None):
|
||||||
|
return annotation.keywords.get("default", None) # An operator property
|
||||||
if attr == "layout":
|
if attr == "layout":
|
||||||
return self
|
return self
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
if self.spied_attr in ("row", "column", "box", "separator"):
|
if self.spied_attr in ("row", "column", "box", "separator", "menu", "operator_menu_enum"):
|
||||||
return self
|
return self
|
||||||
elif self.spied_attr == "template_list":
|
elif self.spied_attr == "template_list":
|
||||||
listtype_name, list_id, dataptr, propname, active_dataptr, active_propname = args
|
listtype_name, list_id, dataptr, propname, active_dataptr, active_propname = args
|
||||||
@@ -123,7 +125,10 @@ class PanelSpy:
|
|||||||
prefix, op_name = operator.split(".")
|
prefix, op_name = operator.split(".")
|
||||||
operator = getattr(getattr(bpy.ops, prefix), op_name)
|
operator = getattr(getattr(bpy.ops, prefix), op_name)
|
||||||
bl_idname = operator.idname()
|
bl_idname = operator.idname()
|
||||||
bl_label = getattr(bpy.types, bl_idname).bl_label
|
try:
|
||||||
|
bl_label = getattr(bpy.types, bl_idname).bl_label
|
||||||
|
except: # Doesn't work on built-ins, I don't know what to do
|
||||||
|
bl_label = bl_idname
|
||||||
text = kwargs.get("text", bl_label)
|
text = kwargs.get("text", bl_label)
|
||||||
icon = kwargs.get("icon", None)
|
icon = kwargs.get("icon", None)
|
||||||
if text:
|
if text:
|
||||||
@@ -152,10 +157,29 @@ class TemplateListSpy:
|
|||||||
self.spied_data = spied_data
|
self.spied_data = spied_data
|
||||||
|
|
||||||
|
|
||||||
panel_name_cache = {}
|
ui_name_cache = {}
|
||||||
panel_spy: PanelSpy = None
|
panel_spy: PanelSpy = None
|
||||||
|
|
||||||
|
|
||||||
|
def create_ui_name_cache():
|
||||||
|
global ui_name_cache
|
||||||
|
if ui_name_cache:
|
||||||
|
return
|
||||||
|
for bl_idname in dir(bpy.types):
|
||||||
|
try:
|
||||||
|
panel_type = getattr(bpy.types, bl_idname)
|
||||||
|
if panel_type.bl_rna.base.name == "Panel":
|
||||||
|
ui_name_cache[panel_type.bl_label] = panel_type.bl_idname
|
||||||
|
elif panel_type.bl_rna.base.name == "Operator":
|
||||||
|
ui_name_cache[panel_type.bl_label] = bl_idname
|
||||||
|
elif panel_type.bl_rna.base.name == "Menu":
|
||||||
|
if panel_type.bl_label == "Add" and bl_idname != "VIEW3D_MT_add":
|
||||||
|
continue # Non-unique, but "VIEW3D_MT_add" is the one we care about
|
||||||
|
ui_name_cache[panel_type.bl_label] = bl_idname
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def replace_variables(value):
|
def replace_variables(value):
|
||||||
for key, new_value in variables.items():
|
for key, new_value in variables.items():
|
||||||
value = value.replace("{" + key + "}", str(new_value))
|
value = value.replace("{" + key + "}", str(new_value))
|
||||||
@@ -218,22 +242,40 @@ def the_brickschema_is_stubbed():
|
|||||||
|
|
||||||
@given(parsers.parse('I look at the "{panel}" panel'))
|
@given(parsers.parse('I look at the "{panel}" panel'))
|
||||||
@when(parsers.parse('I look at the "{panel}" panel'))
|
@when(parsers.parse('I look at the "{panel}" panel'))
|
||||||
@when(parsers.parse('I look at the "{panel}" panel'))
|
@then(parsers.parse('I look at the "{panel}" panel'))
|
||||||
def i_look_at_the_panel_panel(panel):
|
def i_look_at_the_panel_panel(panel):
|
||||||
global panel_name_cache
|
global ui_name_cache
|
||||||
global panel_spy
|
global panel_spy
|
||||||
if not panel_name_cache:
|
create_ui_name_cache()
|
||||||
for bl_idname in dir(bpy.types):
|
if panel not in ui_name_cache:
|
||||||
try:
|
assert False, f"Panel {panel} not found in {ui_name_cache}"
|
||||||
panel_type = getattr(bpy.types, bl_idname)
|
panel_spy = PanelSpy(getattr(bpy.types, ui_name_cache[panel]))
|
||||||
if panel_type.bl_rna.base.name != "Panel":
|
panel_spy.refresh_spy()
|
||||||
continue
|
|
||||||
panel_name_cache[panel_type.bl_label] = panel_type.bl_idname
|
|
||||||
except:
|
@given(parsers.parse('I open the "{name}" menu'))
|
||||||
pass
|
@when(parsers.parse('I open the "{name}" menu'))
|
||||||
if panel not in panel_name_cache:
|
@then(parsers.parse('I open the "{name}" menu'))
|
||||||
assert False, f"Panel {panel} not found in {panel_name_cache}"
|
def i_open_the_name_menu(name):
|
||||||
panel_spy = PanelSpy(getattr(bpy.types, panel_name_cache[panel]))
|
global ui_name_cache
|
||||||
|
global panel_spy
|
||||||
|
create_ui_name_cache()
|
||||||
|
if name not in ui_name_cache:
|
||||||
|
assert False, f"Menu {name} not found in {ui_name_cache}"
|
||||||
|
panel_spy = PanelSpy(getattr(bpy.types, ui_name_cache[name]))
|
||||||
|
panel_spy.refresh_spy()
|
||||||
|
|
||||||
|
|
||||||
|
@given(parsers.parse('I trigger "{operator}"'))
|
||||||
|
@when(parsers.parse('I trigger "{operator}"'))
|
||||||
|
@then(parsers.parse('I trigger "{operator}"'))
|
||||||
|
def i_trigger_operator(operator):
|
||||||
|
global ui_name_cache
|
||||||
|
global panel_spy
|
||||||
|
create_ui_name_cache()
|
||||||
|
if operator not in ui_name_cache:
|
||||||
|
assert False, f"Operator {operator} not found in {ui_name_cache}"
|
||||||
|
panel_spy = PanelSpy(getattr(bpy.types, ui_name_cache[operator]))
|
||||||
panel_spy.refresh_spy()
|
panel_spy.refresh_spy()
|
||||||
|
|
||||||
|
|
||||||
@@ -301,27 +343,36 @@ def i_see_the_prop_property_is_value(prop, value):
|
|||||||
def i_set_the_prop_property_to_value(prop, value):
|
def i_set_the_prop_property_to_value(prop, value):
|
||||||
value = value.strip()
|
value = value.strip()
|
||||||
panel_spy.refresh_spy()
|
panel_spy.refresh_spy()
|
||||||
for spied_prop in panel_spy.spied_props:
|
is_nth = False
|
||||||
if prop in (spied_prop["name"], spied_prop["text"], spied_prop["icon"]):
|
if prop[0].isnumeric() and (prop.endswith("st") or prop.endswith("nd") or prop.endswith("th")):
|
||||||
if spied_prop["prop_type"] == "BOOLEAN":
|
is_nth = True
|
||||||
if value == "TRUE":
|
for nth, spied_prop in enumerate(panel_spy.spied_props):
|
||||||
setattr(spied_prop["props"], spied_prop["name"], True)
|
if is_nth and nth != int(prop[:-2]) - 1:
|
||||||
elif value == "FALSE":
|
continue
|
||||||
setattr(spied_prop["props"], spied_prop["name"], False)
|
if not is_nth and prop not in (spied_prop["name"], spied_prop["text"], spied_prop["icon"]):
|
||||||
elif spied_prop["prop_type"] == "FLOAT":
|
continue
|
||||||
setattr(spied_prop["props"], spied_prop["name"], float(value))
|
if spied_prop["prop_type"] == "BOOLEAN":
|
||||||
elif spied_prop["prop_type"] == "INT":
|
if value == "TRUE":
|
||||||
setattr(spied_prop["props"], spied_prop["name"], int(value))
|
setattr(spied_prop["props"], spied_prop["name"], True)
|
||||||
elif spied_prop["prop_type"] == "ENUM":
|
elif value == "FALSE":
|
||||||
enum_identifier = [i for i in spied_prop["enum_items"] if i is not None and i[1] == value]
|
setattr(spied_prop["props"], spied_prop["name"], False)
|
||||||
if not enum_identifier:
|
elif spied_prop["prop_type"] == "FLOAT":
|
||||||
assert False, f"Could not find value {value} in enum {spied_prop['enum_items']}"
|
setattr(spied_prop["props"], spied_prop["name"], float(value))
|
||||||
setattr(spied_prop["props"], spied_prop["name"], enum_identifier[0][0])
|
elif spied_prop["prop_type"] == "INT":
|
||||||
else:
|
setattr(spied_prop["props"], spied_prop["name"], int(value))
|
||||||
setattr(spied_prop["props"], spied_prop["name"], value)
|
elif spied_prop["prop_type"] == "ENUM":
|
||||||
panel_spy.is_spy_dirty = True
|
enum_identifier = [i for i in spied_prop["enum_items"] if i is not None and i[1] == value]
|
||||||
return
|
if not enum_identifier:
|
||||||
assert False, f"Property {prop} not found in {panel_spy.spied_props}"
|
assert False, f"Could not find value {value} in enum {spied_prop['enum_items']}"
|
||||||
|
setattr(spied_prop["props"], spied_prop["name"], enum_identifier[0][0])
|
||||||
|
elif spied_prop["prop_type"] == "POINTER":
|
||||||
|
setattr(spied_prop["props"], spied_prop["name"], bpy.data.objects.get(value))
|
||||||
|
else:
|
||||||
|
setattr(spied_prop["props"], spied_prop["name"], value)
|
||||||
|
panel_spy.is_spy_dirty = True
|
||||||
|
return
|
||||||
|
debug = "\n".join([f"{i} {v}" for i, v in enumerate(panel_spy.spied_props)])
|
||||||
|
assert False, f"Property {prop} not found in:\n{debug}"
|
||||||
|
|
||||||
|
|
||||||
@then(parsers.parse('The "{name}" list has {total} items'))
|
@then(parsers.parse('The "{name}" list has {total} items'))
|
||||||
@@ -443,6 +494,20 @@ def i_add_a_plane_of_size_size_at_location(size, location):
|
|||||||
bpy.ops.mesh.primitive_plane_add(size=float(size), location=[float(co) for co in location.split(",")])
|
bpy.ops.mesh.primitive_plane_add(size=float(size), location=[float(co) for co in location.split(",")])
|
||||||
|
|
||||||
|
|
||||||
|
@then(parsers.parse('I expect an error "{error_msg}" when "{function}"'))
|
||||||
|
def i_expect_an_error_msg_when_function(error_msg, function):
|
||||||
|
try:
|
||||||
|
exec(function)
|
||||||
|
except Exception as e:
|
||||||
|
actual_error_msg = str(e).strip()
|
||||||
|
if str(e).strip() != error_msg:
|
||||||
|
traceback.print_exc()
|
||||||
|
msg = f"Got different exception running {function} - '{actual_error_msg}' instead of '{error_msg}'"
|
||||||
|
assert False, msg
|
||||||
|
return
|
||||||
|
assert False, f"Function {function} ran without exception '{error_msg}'"
|
||||||
|
|
||||||
|
|
||||||
@then(parsers.parse('I press "{operator}" and expect error "{error_msg}"'))
|
@then(parsers.parse('I press "{operator}" and expect error "{error_msg}"'))
|
||||||
def i_press_operator_and_expect_error(operator, error_msg):
|
def i_press_operator_and_expect_error(operator, error_msg):
|
||||||
operator = replace_variables(operator)
|
operator = replace_variables(operator)
|
||||||
@@ -451,13 +516,14 @@ def i_press_operator_and_expect_error(operator, error_msg):
|
|||||||
exec(f"bpy.ops.{operator}")
|
exec(f"bpy.ops.{operator}")
|
||||||
else:
|
else:
|
||||||
exec(f"bpy.ops.{operator}()")
|
exec(f"bpy.ops.{operator}()")
|
||||||
assert False, f"Operator bpy.ops.{operator} ran without exception '{error_msg}'"
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
actual_error_msg = str(e).strip()
|
actual_error_msg = str(e).strip()
|
||||||
if str(e).strip() != error_msg:
|
if str(e).strip() != error_msg:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
msg = f"Got different exception running bpy.ops.{operator} - '{actual_error_msg}' instead of '{error_msg}'"
|
msg = f"Got different exception running bpy.ops.{operator} - '{actual_error_msg}' instead of '{error_msg}'"
|
||||||
assert False, msg
|
assert False, msg
|
||||||
|
return
|
||||||
|
assert False, f"Operator bpy.ops.{operator} ran without exception '{error_msg}'"
|
||||||
|
|
||||||
|
|
||||||
@given(parsers.parse('I press "{operator}"'))
|
@given(parsers.parse('I press "{operator}"'))
|
||||||
@@ -489,7 +555,11 @@ def i_click_button(button):
|
|||||||
val = getattr(spied_prop["props"], spied_prop["name"])
|
val = getattr(spied_prop["props"], spied_prop["name"])
|
||||||
setattr(spied_prop["props"], spied_prop["name"], not bool(val))
|
setattr(spied_prop["props"], spied_prop["name"], not bool(val))
|
||||||
return
|
return
|
||||||
assert False, f"Could not find {button} in {panel_spy.spied_operators}"
|
if button == "OK" and panel_spy.panel.bl_rna.base.name == "Operator":
|
||||||
|
# Clicked confirm on an operator's draw dialog
|
||||||
|
return i_press_operator(panel_spy.panel.bl_idname)
|
||||||
|
debug = "\n".join([f"{i} {v}" for i, v in enumerate(panel_spy.spied_operators)])
|
||||||
|
assert False, f"Could not find {button}:\n{debug}"
|
||||||
|
|
||||||
|
|
||||||
@given(parsers.parse('I click "{button}" and expect error "{error_msg}"'))
|
@given(parsers.parse('I click "{button}" and expect error "{error_msg}"'))
|
||||||
@@ -541,6 +611,8 @@ def i_deselect_all_objects():
|
|||||||
|
|
||||||
@given(parsers.parse('the object "{name}" is selected'))
|
@given(parsers.parse('the object "{name}" is selected'))
|
||||||
@when(parsers.parse('the object "{name}" is selected'))
|
@when(parsers.parse('the object "{name}" is selected'))
|
||||||
|
@given(parsers.parse('I select the object "{name}"'))
|
||||||
|
@when(parsers.parse('I select the object "{name}"'))
|
||||||
def the_object_name_is_selected(name):
|
def the_object_name_is_selected(name):
|
||||||
i_deselect_all_objects()
|
i_deselect_all_objects()
|
||||||
additionally_the_object_name_is_selected(name)
|
additionally_the_object_name_is_selected(name)
|
||||||
@@ -666,7 +738,8 @@ def the_object_name_exists(name: str) -> bpy.types.Object:
|
|||||||
else:
|
else:
|
||||||
obj = bpy.data.objects.get(name)
|
obj = bpy.data.objects.get(name)
|
||||||
if not obj:
|
if not obj:
|
||||||
assert False, f'The object "{name}" does not exist'
|
debug = "\n".join([o.name for o in bpy.data.objects])
|
||||||
|
assert False, f'The object "{name}" does not exist:\n{debug}'
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
@@ -1258,6 +1331,16 @@ def construction_type(relating_type_name):
|
|||||||
assert relating_type == relating_type_name, f"Construction Type is a {relating_type}, not a {relating_type_name}"
|
assert relating_type == relating_type_name, f"Construction Type is a {relating_type}, not a {relating_type_name}"
|
||||||
|
|
||||||
|
|
||||||
|
@given("I toggle edit mode")
|
||||||
|
@when("I toggle edit mode")
|
||||||
|
@then("I toggle edit mode")
|
||||||
|
def i_toggle_edit_mode():
|
||||||
|
if bpy.context.mode == "OBJECT":
|
||||||
|
bpy.ops.bim.override_mode_set_edit()
|
||||||
|
else:
|
||||||
|
bpy.ops.bim.override_mode_set_object()
|
||||||
|
|
||||||
|
|
||||||
@when("I move the cursor to the bottom left corner")
|
@when("I move the cursor to the bottom left corner")
|
||||||
def move_cursor_bottom_left():
|
def move_cursor_bottom_left():
|
||||||
bpy.context.window.cursor_warp(10, 10)
|
bpy.context.window.cursor_warp(10, 10)
|
||||||
@@ -1330,7 +1413,7 @@ def the_obj1_and_obj2_belong_the_same_linked_aggregate_group(obj_name1, obj_name
|
|||||||
def the_obj_layer_lenght_is_set_to(value):
|
def the_obj_layer_lenght_is_set_to(value):
|
||||||
value = float(value)
|
value = float(value)
|
||||||
try:
|
try:
|
||||||
eval(f"bpy.context.scene.BIMModelProperties.length")
|
eval("bpy.context.scene.BIMModelProperties.length")
|
||||||
except:
|
except:
|
||||||
assert False, f"Property BIMModelProperties.length does not exist when trying to set to value {value}"
|
assert False, f"Property BIMModelProperties.length does not exist when trying to set to value {value}"
|
||||||
|
|
||||||
@@ -1356,6 +1439,7 @@ def run_test_code():
|
|||||||
@then(parsers.parse("I save sample test files"))
|
@then(parsers.parse("I save sample test files"))
|
||||||
def saving_sample_test_files(and_open_in_blender=None):
|
def saving_sample_test_files(and_open_in_blender=None):
|
||||||
filepath = f"{variables['cwd']}/test/files/temp/sample_test_file"
|
filepath = f"{variables['cwd']}/test/files/temp/sample_test_file"
|
||||||
|
print(f"Saved to {filepath}")
|
||||||
bpy.ops.bim.save_project(filepath=f"{filepath}.ifc", should_save_as=True)
|
bpy.ops.bim.save_project(filepath=f"{filepath}.ifc", should_save_as=True)
|
||||||
bpy.ops.wm.save_as_mainfile(filepath=f"{filepath}.blend")
|
bpy.ops.wm.save_as_mainfile(filepath=f"{filepath}.blend")
|
||||||
|
|
||||||
|
|||||||
@@ -235,12 +235,12 @@ def guess_type(items: Sequence[ifcopenshell.entity_instance]) -> Union[str, None
|
|||||||
]
|
]
|
||||||
):
|
):
|
||||||
return "SurfaceModel"
|
return "SurfaceModel"
|
||||||
elif all([True if i.is_a("IfcSolidModel") else False for i in items]):
|
|
||||||
return "SolidModel"
|
|
||||||
elif all(
|
elif all(
|
||||||
[True if i.is_a() == "IfcExtrudedAreaSolid" or i.is_a() == "IfcRevolvedAreaSolid" else False for i in items]
|
[True if i.is_a() == "IfcExtrudedAreaSolid" or i.is_a() == "IfcRevolvedAreaSolid" else False for i in items]
|
||||||
):
|
):
|
||||||
return "SweptSolid"
|
return "SweptSolid"
|
||||||
|
elif all([True if i.is_a("IfcSolidModel") else False for i in items]):
|
||||||
|
return "SolidModel"
|
||||||
elif all(
|
elif all(
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
|
|||||||
Reference in New Issue
Block a user