mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 06:00:51 +00:00
Merge branch 'v0.7.0' into interface-to-interact-with-Brickschema
This commit is contained in:
@@ -226,7 +226,7 @@ Scenario: Add classification reference - cost
|
||||
And I press "bim.add_cost_schedule"
|
||||
And the variable "cost_schedule" is "{ifc}.by_type('IfcCostSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_cost_items(cost_schedule={cost_schedule})"
|
||||
And I press "bim.add_summary_cost_item(cost_schedule={cost_schedule})"
|
||||
And I press "bim.add_summary_cost_item()"
|
||||
And I press "bim.change_classification_level(parent_id={classification})"
|
||||
And the variable "reference" is "{classification_ifc}.by_type('IfcClassificationReference')[0].id()"
|
||||
When I press "bim.add_classification_reference(reference={reference}, obj='', obj_type='Cost')"
|
||||
@@ -241,7 +241,7 @@ Scenario: Remove classification reference - cost
|
||||
And I press "bim.add_cost_schedule"
|
||||
And the variable "cost_schedule" is "{ifc}.by_type('IfcCostSchedule')[0].id()"
|
||||
And I press "bim.enable_editing_cost_items(cost_schedule={cost_schedule})"
|
||||
And I press "bim.add_summary_cost_item(cost_schedule={cost_schedule})"
|
||||
And I press "bim.add_summary_cost_item()"
|
||||
And I press "bim.change_classification_level(parent_id={classification})"
|
||||
And the variable "reference" is "{classification_ifc}.by_type('IfcClassificationReference')[0].id()"
|
||||
And I press "bim.add_classification_reference(reference={reference}, obj='', obj_type='Cost')"
|
||||
|
||||
@@ -57,9 +57,9 @@ Scenario: Remove drawing
|
||||
And the variable "wall1" is "IfcStore.get_file().by_type('IfcWall')[-1].id()"
|
||||
And I press "bim.add_drawing"
|
||||
And the variable "drawing" is "IfcStore.get_file().by_type('IfcAnnotation')[0].id()"
|
||||
And the collection "IfcGroup/PLAN_VIEW" exists
|
||||
And the collection "IfcAnnotation/PLAN_VIEW" exists
|
||||
When I press "bim.remove_drawing(drawing={drawing})"
|
||||
Then the collection "IfcGroup/PLAN_VIEW" does not exist
|
||||
Then the collection "IfcAnnotation/PLAN_VIEW" does not exist
|
||||
|
||||
Scenario: Remove drawing - via object deletion
|
||||
Given an empty IFC project
|
||||
@@ -70,9 +70,10 @@ Scenario: Remove drawing - via object deletion
|
||||
And the variable "wall1" is "IfcStore.get_file().by_type('IfcWall')[-1].id()"
|
||||
And I press "bim.add_drawing"
|
||||
And the variable "drawing" is "IfcStore.get_file().by_type('IfcAnnotation')[0].id()"
|
||||
And the collection "IfcAnnotation/PLAN_VIEW" exists
|
||||
And the object "IfcAnnotation/PLAN_VIEW" is selected
|
||||
When I press "bim.override_object_delete"
|
||||
Then the collection "IfcGroup/PLAN_VIEW" does not exist
|
||||
Then the collection "IfcAnnotation/PLAN_VIEW" does not exist
|
||||
|
||||
Scenario: Remove drawing - deleting active drawing
|
||||
Given an empty IFC project
|
||||
@@ -83,9 +84,10 @@ Scenario: Remove drawing - deleting active drawing
|
||||
And the variable "wall1" is "IfcStore.get_file().by_type('IfcWall')[-1].id()"
|
||||
And I press "bim.add_drawing"
|
||||
And the variable "drawing" is "IfcStore.get_file().by_type('IfcAnnotation')[0].id()"
|
||||
And the collection "IfcAnnotation/PLAN_VIEW" exists
|
||||
And I set "scene.DocProperties.active_drawing_index" to "0"
|
||||
And I press "bim.activate_drawing(drawing={drawing})"
|
||||
And the object "IfcAnnotation/PLAN_VIEW" is selected
|
||||
When I press "bim.override_object_delete"
|
||||
Then the collection "IfcGroup/PLAN_VIEW" does not exist
|
||||
Then the collection "IfcAnnotation/PLAN_VIEW" does not exist
|
||||
|
||||
|
||||
@@ -156,26 +156,31 @@ Scenario: Unassign material - material layer set
|
||||
When I press "bim.unassign_material"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Unassign material - material layer set usages will not be removed
|
||||
Scenario: Unassign material - removing inherited material
|
||||
Given an empty IFC project
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||
And I press "bim.assign_class"
|
||||
|
||||
And I add an empty
|
||||
And the object "Empty" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_product" to "IfcElementType"
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
|
||||
And I press "bim.assign_class"
|
||||
|
||||
And I press "bim.add_material(obj='')"
|
||||
And I set "active_object.BIMObjectMaterialProperties.material_type" to "IfcMaterialLayerSet"
|
||||
And I press "bim.assign_material"
|
||||
|
||||
And the object "IfcWall/Cube" is selected
|
||||
When the variable "type" is "{ifc}.by_type('IfcWallType')[0].id()"
|
||||
And I press "bim.assign_type(relating_type={type}, related_object='IfcWall/Cube')"
|
||||
|
||||
Then the object "IfcWall/Cube" has a "100" thick layered material containing the material "Default"
|
||||
|
||||
When I press "bim.unassign_material"
|
||||
Then the object "IfcWall/Cube" has a "100" thick layered material containing the material "Default"
|
||||
Then the object "IfcWall/Cube" has no IFC materials
|
||||
|
||||
Scenario: Enable editing assigned material - material layer set
|
||||
Given an empty IFC project
|
||||
@@ -435,17 +440,20 @@ Scenario: Remove material set layer
|
||||
And the object "Cube" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||
And I press "bim.assign_class"
|
||||
|
||||
And I add an empty
|
||||
And the object "Empty" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_product" to "IfcElementType"
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
|
||||
And I press "bim.assign_class"
|
||||
|
||||
And I press "bim.add_material(obj='')"
|
||||
And I set "active_object.BIMObjectMaterialProperties.material_type" to "IfcMaterialLayerSet"
|
||||
And I press "bim.assign_material"
|
||||
|
||||
And I press "bim.enable_editing_assigned_material"
|
||||
And the variable "material_set" is "{ifc}.by_type('IfcMaterialLayerSet')[0].id()"
|
||||
And I press "bim.remove_layer(layer={ifc}.by_id({material_set}).MaterialLayers[0].id())"
|
||||
|
||||
And I press "bim.add_layer(layer_set={material_set})"
|
||||
When I press "bim.remove_layer(layer={ifc}.by_id({material_set}).MaterialLayers[0].id())"
|
||||
Then nothing happens
|
||||
And I press "bim.remove_layer(layer={ifc}.by_id({material_set}).MaterialLayers[0].id())"
|
||||
Then I press "bim.remove_layer(layer={ifc}.by_id({material_set}).MaterialLayers[0].id())" and expect error "Error: At least one layer must exist"
|
||||
|
||||
@@ -393,7 +393,7 @@ Scenario: Export IFC - with basic contents and saving as a relative path
|
||||
Given an empty Blender session
|
||||
And I press "bim.load_project(filepath='{cwd}/test/files/basic.ifc')"
|
||||
When I press "wm.save_mainfile(filepath='{cwd}/test/files/temp/export.blend')"
|
||||
And I press "export_ifc.bim(filepath='{cwd}/test/files/temp/export.ifc', use_relative_path=True)"
|
||||
And I press "export_ifc.bim(filepath='{cwd}/test/files/temp/export.ifc', use_relative_path=True, save_as_invoked=True)"
|
||||
Then "scene.BIMProperties.ifc_file" is "export.ifc"
|
||||
|
||||
Scenario: Export IFC - with deleted objects synchronised
|
||||
|
||||
@@ -81,20 +81,25 @@ Scenario: Add an opening to Element B with a void that already voids Element A
|
||||
And the object "Cube" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||
And I press "bim.assign_class"
|
||||
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I press "bim.assign_class"
|
||||
|
||||
And I press "bim.add_potential_opening"
|
||||
And the object "Opening" is selected
|
||||
And additionally the object "IfcWall/Cube" is selected
|
||||
And I press "bim.add_opening"
|
||||
|
||||
And the object "IfcWall/Cube" is selected
|
||||
And I press "bim.show_openings"
|
||||
|
||||
When the object "IfcOpeningElement/Opening" is selected
|
||||
And additionally the object "IfcWall/Cube.001" is selected
|
||||
And I press "bim.add_opening"
|
||||
Then the object "IfcWall/Cube" is voided by "Opening"
|
||||
And the object "IfcWall/Cube.001" is not voided by "Opening"
|
||||
|
||||
Then the object "IfcWall/Cube" is not voided by "Opening"
|
||||
And the object "IfcWall/Cube.001" is voided by "Opening"
|
||||
|
||||
Scenario: Remove opening
|
||||
Given an empty IFC project
|
||||
|
||||
@@ -65,33 +65,28 @@ def an_untestable_scenario():
|
||||
|
||||
@given("an empty Blender session")
|
||||
@when("an empty Blender session is started")
|
||||
def an_empty_ifc_project():
|
||||
def an_empty_blender_session():
|
||||
IfcStore.purge()
|
||||
bpy.ops.wm.read_homefile(app_template="")
|
||||
if len(bpy.data.objects) > 0:
|
||||
bpy.data.batch_remove(bpy.data.objects)
|
||||
bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True)
|
||||
|
||||
# default project settings
|
||||
bpy.context.scene.unit_settings.system = "METRIC"
|
||||
bpy.context.scene.unit_settings.length_unit = "MILLIMETERS"
|
||||
bpy.context.scene.BIMProjectProperties.template_file = '0'
|
||||
|
||||
|
||||
@given("an empty IFC project")
|
||||
def an_empty_ifc_project():
|
||||
IfcStore.purge()
|
||||
bpy.ops.wm.read_homefile(app_template="")
|
||||
if len(bpy.data.objects) > 0:
|
||||
bpy.data.batch_remove(bpy.data.objects)
|
||||
bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True)
|
||||
bpy.context.scene.unit_settings.system = "METRIC"
|
||||
bpy.context.scene.unit_settings.length_unit = "MILLIMETERS"
|
||||
an_empty_blender_session()
|
||||
bpy.ops.bim.create_project()
|
||||
|
||||
|
||||
@given("an empty IFC2X3 project")
|
||||
def an_empty_ifc_project():
|
||||
IfcStore.purge()
|
||||
bpy.ops.wm.read_homefile(app_template="")
|
||||
if len(bpy.data.objects) > 0:
|
||||
bpy.data.batch_remove(bpy.data.objects)
|
||||
bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True)
|
||||
def an_empty_ifc_2x3_project():
|
||||
an_empty_blender_session()
|
||||
bpy.context.scene.BIMProjectProperties.export_schema = "IFC2X3"
|
||||
bpy.ops.bim.create_project()
|
||||
|
||||
@@ -164,6 +159,21 @@ 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(",")])
|
||||
|
||||
|
||||
@then(parsers.parse('I press "{operator}" and expect error "{error_msg}"'))
|
||||
def i_press_operator_and_expect_error(operator, error_msg):
|
||||
operator = replace_variables(operator)
|
||||
try:
|
||||
if "(" in operator:
|
||||
exec(f"bpy.ops.{operator}")
|
||||
else:
|
||||
exec(f"bpy.ops.{operator}()")
|
||||
assert False, f"Operator bpy.ops.{operator} ran without exception '{error_msg}'"
|
||||
except Exception as e:
|
||||
actual_error_msg = str(e).strip()
|
||||
if str(e).strip() != error_msg:
|
||||
traceback.print_exc()
|
||||
assert False, f"Got different exception running bpy.ops.{operator} - '{actual_error_msg}' instead of '{error_msg}'"
|
||||
|
||||
@given(parsers.parse('I press "{operator}"'))
|
||||
@when(parsers.parse('I press "{operator}"'))
|
||||
def i_press_operator(operator):
|
||||
@@ -173,9 +183,9 @@ def i_press_operator(operator):
|
||||
exec(f"bpy.ops.{operator}")
|
||||
else:
|
||||
exec(f"bpy.ops.{operator}()")
|
||||
except:
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
assert False, f"Failed to run operator bpy.ops.{operator}"
|
||||
assert False, f"Failed to run operator bpy.ops.{operator} because of {e}"
|
||||
|
||||
|
||||
@given(parsers.parse('I evaluate expression "{expression}"'))
|
||||
@@ -590,6 +600,12 @@ def the_object_name_has_a_thickness_thick_layered_material_containing_the_materi
|
||||
assert is_x(total_thickness, float(thickness))
|
||||
assert material_name in material_names
|
||||
|
||||
@then(parsers.parse('the object "{name}" has no IFC materials'))
|
||||
def the_object_has_no_ifc_materials(name):
|
||||
element = tool.Ifc.get_entity(the_object_name_exists(name))
|
||||
material = ifcopenshell.util.element.get_material(element)
|
||||
assert material is None
|
||||
|
||||
|
||||
@then(
|
||||
parsers.parse(
|
||||
@@ -672,7 +688,7 @@ def the_object_name_dimensions_are_dimensions(name, dimensions):
|
||||
actual_dimensions = list(the_object_name_exists(name).dimensions)
|
||||
expected_dimensions = [float(co) for co in dimensions.split(",")]
|
||||
for i, number in enumerate(actual_dimensions):
|
||||
assert is_x(number, expected_dimensions[i]), f"Expected {actual_dimensions[i]} but got {number}"
|
||||
assert is_x(number, expected_dimensions[i]), f"Expected {expected_dimensions[i]} but got {number}"
|
||||
|
||||
|
||||
@then(parsers.parse('the object "{name}" top right corner is at "{location}"'))
|
||||
|
||||
@@ -442,7 +442,7 @@ class TestUpdateDrawingName:
|
||||
drawing.get_drawing_group("drawing").should_be_called().will_return("group")
|
||||
drawing.get_name("group").should_be_called().will_return("name")
|
||||
drawing.get_drawing_collection("drawing").should_be_called().will_return("collection")
|
||||
drawing.set_drawing_collection_name("group", "collection").should_be_called()
|
||||
drawing.set_drawing_collection_name("drawing", "collection").should_be_called()
|
||||
|
||||
drawing.get_drawing_document("drawing").should_be_called().will_return("reference")
|
||||
drawing.get_reference_document("reference").should_be_called().will_return("information")
|
||||
@@ -459,7 +459,7 @@ class TestUpdateDrawingName:
|
||||
drawing.get_name("group").should_be_called().will_return("oldname")
|
||||
ifc.run("attribute.edit_attributes", product="group", attributes={"Name": "name"}).should_be_called()
|
||||
drawing.get_drawing_collection("drawing").should_be_called().will_return("collection")
|
||||
drawing.set_drawing_collection_name("group", "collection").should_be_called()
|
||||
drawing.set_drawing_collection_name("drawing", "collection").should_be_called()
|
||||
|
||||
drawing.get_drawing_document("drawing").should_be_called().will_return("reference")
|
||||
drawing.get_reference_document("reference").should_be_called().will_return("information")
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import blenderbim.core.material as subject
|
||||
from test.core.bootstrap import ifc, material, style
|
||||
from test.core.bootstrap import ifc, material, style, spatial
|
||||
|
||||
|
||||
class TestUnlinkMaterial:
|
||||
@@ -158,7 +158,7 @@ class TestDisableEditingMaterials:
|
||||
|
||||
|
||||
class TestSelectByMaterial:
|
||||
def test_run(self, material):
|
||||
def test_run(self, material, spatial):
|
||||
material.get_elements_by_material("material").should_be_called().will_return("elements")
|
||||
material.select_elements("elements").should_be_called()
|
||||
subject.select_by_material(material, material="material")
|
||||
spatial.select_products("elements").should_be_called()
|
||||
subject.select_by_material(material, spatial, material="material")
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import blenderbim.core.style as subject
|
||||
from test.core.bootstrap import ifc, material, style
|
||||
from test.core.bootstrap import ifc, material, style, spatial
|
||||
|
||||
|
||||
class TestAddStyle:
|
||||
@@ -85,22 +85,39 @@ class TestUpdateStyleColours:
|
||||
def test_updating_rendering_style_if_available(self, ifc, style):
|
||||
style.get_style("obj").should_be_called().will_return("element")
|
||||
style.can_support_rendering_style("obj").should_be_called().will_return(True)
|
||||
style.get_surface_rendering_style("obj").should_be_called().will_return("style")
|
||||
style.get_surface_rendering_attributes("obj").should_be_called().will_return("attributes")
|
||||
ifc.run("style.edit_surface_style", style="style", attributes="attributes").should_be_called()
|
||||
|
||||
style.get_surface_rendering_style("obj").should_be_called().will_return("rendering_style")
|
||||
style.get_texture_style("obj").should_be_called().will_return("texture_style")
|
||||
style.get_surface_rendering_attributes("obj", "verbose").should_be_called().will_return("attributes")
|
||||
ifc.run("style.edit_surface_style", style="rendering_style", attributes="attributes").should_be_called()
|
||||
|
||||
ifc.run("style.add_surface_textures", material="obj").should_be_called().will_return("textures")
|
||||
ifc.run("style.edit_surface_style", style="texture_style", attributes={"Textures": "textures"}).should_be_called().will_return("textures")
|
||||
|
||||
style.record_shading("obj").should_be_called()
|
||||
subject.update_style_colours(ifc, style, obj="obj")
|
||||
subject.update_style_colours(ifc, style, obj="obj", verbose="verbose")
|
||||
|
||||
def test_adding_a_rendering_style_if_not_available(self, ifc, style):
|
||||
style.get_style("obj").should_be_called().will_return("element")
|
||||
style.can_support_rendering_style("obj").should_be_called().will_return(True)
|
||||
|
||||
style.get_surface_rendering_style("obj").should_be_called().will_return(None)
|
||||
style.get_surface_rendering_attributes("obj").should_be_called().will_return("attributes")
|
||||
style.get_texture_style("obj").should_be_called().will_return(None)
|
||||
style.get_surface_rendering_attributes("obj", "verbose").should_be_called().will_return("attributes")
|
||||
ifc.run(
|
||||
"style.add_surface_style", style="element", ifc_class="IfcSurfaceStyleRendering", attributes="attributes"
|
||||
).should_be_called()
|
||||
|
||||
ifc.run("style.add_surface_textures", material="obj").should_be_called().will_return("textures")
|
||||
ifc.run(
|
||||
"style.add_surface_style",
|
||||
style="element",
|
||||
ifc_class="IfcSurfaceStyleWithTextures",
|
||||
attributes={"Textures": "textures"},
|
||||
).should_be_called()
|
||||
|
||||
style.record_shading("obj").should_be_called()
|
||||
subject.update_style_colours(ifc, style, obj="obj")
|
||||
subject.update_style_colours(ifc, style, obj="obj", verbose="verbose")
|
||||
|
||||
def test_updating_shading_style_as_a_fallback_if_available(self, ifc, style):
|
||||
style.get_style("obj").should_be_called().will_return("element")
|
||||
@@ -212,3 +229,10 @@ class TestDisableEditingStyles:
|
||||
def test_run(self, style):
|
||||
style.disable_editing_styles().should_be_called()
|
||||
subject.disable_editing_styles(style)
|
||||
|
||||
|
||||
class TestSelectByStyle:
|
||||
def test_run(self, style, spatial):
|
||||
style.get_elements_by_style("style").should_be_called().will_return("elements")
|
||||
spatial.select_products("elements").should_be_called()
|
||||
subject.select_by_style(style, spatial, style="style")
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
|
||||
import blenderbim.core.system as subject
|
||||
from test.core.bootstrap import ifc, system
|
||||
from test.core.bootstrap import ifc, system, spatial
|
||||
|
||||
|
||||
class TestLoadSystems:
|
||||
@@ -91,24 +91,24 @@ class TestSelectSystemProducts:
|
||||
|
||||
|
||||
class TestShowPorts:
|
||||
def test_run(self, ifc, system):
|
||||
def test_run(self, ifc, system, spatial):
|
||||
ifc.get_object("element").should_be_called().will_return("obj")
|
||||
ifc.is_moved("obj").should_be_called().will_return(False)
|
||||
|
||||
system.get_ports("element").should_be_called().will_return(["port"])
|
||||
system.load_ports("element", ["port"]).should_be_called()
|
||||
system.select_elements(["port"]).should_be_called()
|
||||
subject.show_ports(ifc, system, element="element")
|
||||
spatial.select_products(["port"]).should_be_called()
|
||||
subject.show_ports(ifc, system, spatial, element="element")
|
||||
|
||||
def test_syncing_locations_if_objects_moved_prior_to_showing_ports(self, ifc, system):
|
||||
def test_syncing_locations_if_objects_moved_prior_to_showing_ports(self, ifc, system, spatial):
|
||||
ifc.get_object("element").should_be_called().will_return("obj")
|
||||
ifc.is_moved("obj").should_be_called().will_return(True)
|
||||
system.run_geometry_edit_object_placement(obj="obj").should_be_called()
|
||||
|
||||
system.get_ports("element").should_be_called().will_return(["port"])
|
||||
system.load_ports("element", ["port"]).should_be_called()
|
||||
system.select_elements(["port"]).should_be_called()
|
||||
subject.show_ports(ifc, system, element="element")
|
||||
spatial.select_products(["port"]).should_be_called()
|
||||
subject.show_ports(ifc, system, spatial, element="element")
|
||||
|
||||
|
||||
class TestHidePorts:
|
||||
|
||||
@@ -264,29 +264,32 @@ class TestAssign(NewFile):
|
||||
|
||||
def test_in_decomposition_mode_drawings_are_placed_in_a_group_in_a_views_collection(self):
|
||||
bpy.ops.bim.create_project()
|
||||
element_obj = bpy.data.objects.new("IfcAnnotation/Name", None)
|
||||
element_obj = bpy.data.objects.new("IfcAnnotation/DRAWING", None)
|
||||
element = tool.Ifc.get().createIfcAnnotation(ObjectType="DRAWING")
|
||||
tool.Ifc.link(element, element_obj)
|
||||
|
||||
group = ifcopenshell.api.run("group.add_group", tool.Ifc.get())
|
||||
group.ObjectType = "DRAWING"
|
||||
ifcopenshell.api.run("group.assign_group", tool.Ifc.get(), products=[element], group=group)
|
||||
|
||||
subject.assign(element_obj)
|
||||
assert element_obj.users_collection[0].name == "IfcGroup/Unnamed"
|
||||
assert bpy.data.collections.get("Views").children.get("IfcGroup/Unnamed")
|
||||
assert element_obj.users_collection[0].name == "IfcAnnotation/DRAWING"
|
||||
assert bpy.data.collections.get("Views").children.get("IfcAnnotation/DRAWING")
|
||||
assert bpy.data.collections.get("IfcProject/My Project").children.get("Views")
|
||||
|
||||
def test_in_decomposition_mode_annotations_are_placed_in_a_group_in_a_views_collection(self):
|
||||
bpy.ops.bim.create_project()
|
||||
self.test_in_decomposition_mode_drawings_are_placed_in_a_group_in_a_views_collection()
|
||||
ifc_file = tool.Ifc.get()
|
||||
|
||||
element_obj = bpy.data.objects.new("IfcAnnotation/Name", None)
|
||||
element = tool.Ifc.get().createIfcAnnotation()
|
||||
element = ifc_file.createIfcAnnotation()
|
||||
tool.Ifc.link(element, element_obj)
|
||||
group = ifcopenshell.api.run("group.add_group", tool.Ifc.get())
|
||||
group.ObjectType = "DRAWING"
|
||||
ifcopenshell.api.run("group.assign_group", tool.Ifc.get(), products=[element], group=group)
|
||||
|
||||
group = ifc_file.by_type("IfcGroup")[0]
|
||||
ifcopenshell.api.run("group.assign_group", ifc_file, products=[element], group=group)
|
||||
|
||||
subject.assign(element_obj)
|
||||
assert element_obj.users_collection[0].name == "IfcGroup/Unnamed"
|
||||
assert bpy.data.collections.get("Views").children.get("IfcGroup/Unnamed")
|
||||
assert bpy.data.collections.get("IfcProject/My Project").children.get("Views")
|
||||
assert element_obj.users_collection[0].name == "IfcAnnotation/DRAWING"
|
||||
|
||||
def test_in_decomposition_mode_structural_members_are_placed_in_a_members_collection(self):
|
||||
bpy.ops.bim.create_project()
|
||||
|
||||
@@ -305,6 +305,9 @@ class TestGetDrawingCollection(NewFile):
|
||||
collection = bpy.data.collections.new("Collection")
|
||||
bpy.context.scene.collection.children.link(collection)
|
||||
collection.objects.link(obj)
|
||||
obj.BIMObjectProperties.collection = collection
|
||||
collection.BIMCollectionProperties.obj = obj
|
||||
|
||||
element = ifc.createIfcAnnotation()
|
||||
tool.Ifc.link(element, obj)
|
||||
assert subject.get_drawing_collection(element) == collection
|
||||
|
||||
@@ -478,7 +478,7 @@ class TestShouldGenerateUVs(NewFile):
|
||||
obj.data.materials.append(material)
|
||||
material.use_nodes = True
|
||||
|
||||
bsdf = material.node_tree.nodes["Principled BSDF"]
|
||||
bsdf = tool.Blender.get_material_node(material, "BSDF_PRINCIPLED")
|
||||
node = material.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
material.node_tree.links.new(bsdf.inputs["Base Color"], node.outputs["Color"])
|
||||
|
||||
@@ -494,7 +494,7 @@ class TestShouldGenerateUVs(NewFile):
|
||||
obj.data.materials.append(material)
|
||||
material.use_nodes = True
|
||||
|
||||
bsdf = material.node_tree.nodes["Principled BSDF"]
|
||||
bsdf = tool.Blender.get_material_node(material, "BSDF_PRINCIPLED")
|
||||
node = material.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
material.node_tree.links.new(bsdf.inputs["Base Color"], node.outputs["Color"])
|
||||
|
||||
|
||||
@@ -170,14 +170,3 @@ class TestIsMaterialUsedInSets(NewFile):
|
||||
material_set_item.Material = material
|
||||
assert subject.is_material_used_in_sets(material) is True
|
||||
|
||||
|
||||
class TestSelectElements(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc().set(ifc)
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcPump")
|
||||
obj = bpy.data.objects.new("Object", None)
|
||||
bpy.context.scene.collection.objects.link(obj)
|
||||
tool.Ifc.link(element, obj)
|
||||
subject.select_elements([element])
|
||||
assert obj in bpy.context.selected_objects
|
||||
|
||||
@@ -44,7 +44,7 @@ class TestCreateEmpty(NewFile):
|
||||
|
||||
class TestLoadDefaultThumbnails(NewFile):
|
||||
def test_nothing(self):
|
||||
pass # Not possible to test this headlessly
|
||||
pass # Not possible to test this headlessly
|
||||
|
||||
|
||||
class TestRunAggregateAssignObject(NewFile):
|
||||
@@ -93,6 +93,9 @@ class TestSetActiveSpatialElement(NewFile):
|
||||
collection = bpy.data.collections.new("Foo")
|
||||
bpy.context.scene.collection.children.link(collection)
|
||||
collection.objects.link(obj)
|
||||
obj.BIMObjectProperties.collection = collection
|
||||
collection.BIMCollectionProperties.obj = obj
|
||||
|
||||
layer = bpy.context.view_layer.layer_collection.children["Foo"]
|
||||
assert bpy.context.view_layer.active_layer_collection != layer
|
||||
subject.set_active_spatial_element(obj)
|
||||
|
||||
@@ -257,3 +257,15 @@ class TestSetRelativeObjectMatrix(NewFile):
|
||||
matrix[0][3] = 1
|
||||
subject.set_relative_object_matrix(obj, relative_obj, matrix)
|
||||
assert obj.matrix_world[0][3] == 2
|
||||
|
||||
|
||||
class TestSelectProducts(NewFile):
|
||||
def test_select_products(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc.set(ifc)
|
||||
product = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
|
||||
obj = bpy.data.objects.new("Object", None)
|
||||
bpy.context.scene.collection.objects.link(obj)
|
||||
tool.Ifc.link(product, obj)
|
||||
subject.select_products([product])
|
||||
assert obj in bpy.context.selected_objects
|
||||
@@ -136,7 +136,7 @@ class TestGetSurfaceRenderingAttributes(NewFile):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.diffuse_color = [1, 1, 1, 1]
|
||||
obj.use_nodes = True
|
||||
node = obj.node_tree.nodes["Principled BSDF"]
|
||||
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
|
||||
node.inputs["Alpha"].default_value = 0.8
|
||||
node.inputs["Base Color"].default_value = [0.5, 0.5, 0.5, 0.5]
|
||||
node.inputs["Roughness"].default_value = 0.2
|
||||
@@ -163,11 +163,15 @@ class TestGetSurfaceRenderingAttributes(NewFile):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.diffuse_color = [1, 1, 1, 1]
|
||||
obj.use_nodes = True
|
||||
node = obj.node_tree.nodes["Principled BSDF"]
|
||||
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
|
||||
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
|
||||
obj.node_tree.nodes.remove(node)
|
||||
|
||||
node = obj.node_tree.nodes.new(type="ShaderNodeBsdfGlossy")
|
||||
node.inputs["Color"].default_value = [0.5, 0.5, 0.5, 0.5]
|
||||
node.inputs["Roughness"].default_value = 0.2
|
||||
obj.node_tree.links.new(node.outputs[0], output.inputs[0])
|
||||
|
||||
assert subject.get_surface_rendering_attributes(obj) == {
|
||||
"SurfaceColour": {
|
||||
"Name": None,
|
||||
@@ -190,11 +194,15 @@ class TestGetSurfaceRenderingAttributes(NewFile):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.diffuse_color = [1, 1, 1, 1]
|
||||
obj.use_nodes = True
|
||||
node = obj.node_tree.nodes["Principled BSDF"]
|
||||
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
|
||||
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
|
||||
obj.node_tree.nodes.remove(node)
|
||||
|
||||
node = obj.node_tree.nodes.new(type="ShaderNodeBsdfDiffuse")
|
||||
node.inputs["Color"].default_value = [0.5, 0.5, 0.5, 0.5]
|
||||
node.inputs["Roughness"].default_value = 0.2
|
||||
obj.node_tree.links.new(node.outputs[0], output.inputs[0])
|
||||
|
||||
assert subject.get_surface_rendering_attributes(obj) == {
|
||||
"SurfaceColour": {
|
||||
"Name": None,
|
||||
@@ -217,11 +225,15 @@ class TestGetSurfaceRenderingAttributes(NewFile):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.diffuse_color = [1, 1, 1, 1]
|
||||
obj.use_nodes = True
|
||||
node = obj.node_tree.nodes["Principled BSDF"]
|
||||
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
|
||||
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
|
||||
obj.node_tree.nodes.remove(node)
|
||||
|
||||
node = obj.node_tree.nodes.new(type="ShaderNodeBsdfGlass")
|
||||
node.inputs["Color"].default_value = [0.5, 0.5, 0.5, 0.5]
|
||||
node.inputs["Roughness"].default_value = 0.2
|
||||
obj.node_tree.links.new(node.outputs[0], output.inputs[0])
|
||||
|
||||
assert subject.get_surface_rendering_attributes(obj) == {
|
||||
"SurfaceColour": {
|
||||
"Name": None,
|
||||
@@ -244,10 +256,14 @@ class TestGetSurfaceRenderingAttributes(NewFile):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.diffuse_color = [1, 1, 1, 1]
|
||||
obj.use_nodes = True
|
||||
node = obj.node_tree.nodes["Principled BSDF"]
|
||||
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
|
||||
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
|
||||
obj.node_tree.nodes.remove(node)
|
||||
|
||||
node = obj.node_tree.nodes.new(type="ShaderNodeEmission")
|
||||
node.inputs["Color"].default_value = [0.5, 0.5, 0.5, 0.5]
|
||||
obj.node_tree.links.new(node.outputs[0], output.inputs[0])
|
||||
|
||||
assert subject.get_surface_rendering_attributes(obj) == {
|
||||
"SurfaceColour": {
|
||||
"Name": None,
|
||||
@@ -270,10 +286,14 @@ class TestGetSurfaceRenderingAttributes(NewFile):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.diffuse_color = [1, 1, 1, 1]
|
||||
obj.use_nodes = True
|
||||
node = obj.node_tree.nodes["Principled BSDF"]
|
||||
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
|
||||
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
|
||||
obj.node_tree.nodes.remove(node)
|
||||
|
||||
node = obj.node_tree.nodes.new(type="ShaderNodeVolumePrincipled")
|
||||
node.inputs["Color"].default_value = [0.5, 0.5, 0.5, 0.5]
|
||||
obj.node_tree.links.new(node.outputs[0], output.inputs[0])
|
||||
|
||||
assert subject.get_surface_rendering_attributes(obj) == {
|
||||
"SurfaceColour": {
|
||||
"Name": None,
|
||||
@@ -440,15 +460,3 @@ class TestIsEditingStyles(NewFile):
|
||||
subject.is_editing_styles() is False
|
||||
bpy.context.scene.BIMStylesProperties.is_editing = True
|
||||
subject.is_editing_styles() is True
|
||||
|
||||
|
||||
class TestSelectElements(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc().set(ifc)
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcPump")
|
||||
obj = bpy.data.objects.new("Object", None)
|
||||
bpy.context.scene.collection.objects.link(obj)
|
||||
tool.Ifc.link(element, obj)
|
||||
subject.select_elements([element])
|
||||
assert obj in bpy.context.selected_objects
|
||||
|
||||
@@ -196,18 +196,6 @@ class TestRunRootAssignClass(NewFile):
|
||||
pass
|
||||
|
||||
|
||||
class TestSelectElements(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc().set(ifc)
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcPump")
|
||||
obj = bpy.data.objects.new("Object", None)
|
||||
bpy.context.scene.collection.objects.link(obj)
|
||||
tool.Ifc.link(element, obj)
|
||||
subject.select_elements([element])
|
||||
assert obj in bpy.context.selected_objects
|
||||
|
||||
|
||||
class TestSelectSystemProducts(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
|
||||
Reference in New Issue
Block a user