From 516503b9ca115278a452b8b1c6c081ac54959afc Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sat, 16 Oct 2021 15:46:02 +1100 Subject: [PATCH] Fix #1801. Fix bug where importing multiple assets sharing an already imported material fails. --- .../blenderbim/bim/module/project/operator.py | 4 +- .../test/bim/feature/project.feature | 25 +++++ src/blenderbim/test/bim/test_feature.py | 5 + src/blenderbim/test/files/basic.ifc | 94 ++++++++++++++++++- 4 files changed, 123 insertions(+), 5 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/project/operator.py b/src/blenderbim/blenderbim/bim/module/project/operator.py index 93ff048698..1c9aaccbc6 100644 --- a/src/blenderbim/blenderbim/bim/module/project/operator.py +++ b/src/blenderbim/blenderbim/bim/module/project/operator.py @@ -145,7 +145,8 @@ class SelectLibraryFile(bpy.types.Operator): IfcStore.library_path = self.filepath IfcStore.library_file = ifcopenshell.open(self.filepath) bpy.ops.bim.refresh_library() - context.area.tag_redraw() + if context.area: + context.area.tag_redraw() return {"FINISHED"} def invoke(self, context, event): @@ -399,6 +400,7 @@ class AppendLibraryElement(bpy.types.Operator): ifc_importer = import_ifc.IfcImporter(ifc_import_settings) ifc_importer.file = self.file ifc_importer.type_collection = type_collection + ifc_importer.material_creator.load_existing_materials() self.import_type_materials(element, ifc_importer) self.import_type_styles(element, ifc_importer) ifc_importer.create_type_product(element) diff --git a/src/blenderbim/test/bim/feature/project.feature b/src/blenderbim/test/bim/feature/project.feature index 28fb55c42c..e968410146 100644 --- a/src/blenderbim/test/bim/feature/project.feature +++ b/src/blenderbim/test/bim/feature/project.feature @@ -14,6 +14,31 @@ Scenario: Create project And the object "IfcBuilding/My Building" is in the collection "IfcBuilding/My Building" And the object "IfcBuildingStorey/My Storey" is in the collection "IfcBuildingStorey/My Storey" +Scenario: Append library element + Given an empty IFC project + When I press "bim.select_library_file(filepath='{cwd}/test/files/basic.ifc')" + And I press "bim.change_library_element(element_name='IfcTypeProduct')" + And I press "bim.change_library_element(element_name='IfcSlabType')" + And I press "bim.append_library_element(definition=242, prop_index=0)" + Then the object "IfcSlabType/Slab" is an "IfcSlabType" + And the object "IfcSlabType/Slab" is in the collection "Types" + +Scenario: Append library element - append two elements sharing a material + Given an empty IFC project + And I press "bim.select_library_file(filepath='{cwd}/test/files/basic.ifc')" + And I press "bim.change_library_element(element_name='IfcTypeProduct')" + And I press "bim.change_library_element(element_name='IfcSlabType')" + And I press "bim.append_library_element(definition=242, prop_index=0)" + When I press "bim.rewind_library" + And I press "bim.change_library_element(element_name='IfcWallType')" + And I press "bim.append_library_element(definition=291, prop_index=0)" + Then the object "IfcSlabType/Slab" is an "IfcSlabType" + And the object "IfcSlabType/Slab" is in the collection "Types" + And the object "IfcWallType/Wall" is an "IfcWallType" + And the object "IfcWallType/Wall" is in the collection "Types" + And the object "IfcSlabType/Slab" has the material "SurfaceStyle" + And the object "IfcWallType/Wall" has the material "SurfaceStyle" + Scenario: Load project Given an empty Blender session When I press "bim.load_project(filepath='{cwd}/test/files/basic.ifc')" diff --git a/src/blenderbim/test/bim/test_feature.py b/src/blenderbim/test/bim/test_feature.py index a763d4e0fc..1749ed55eb 100644 --- a/src/blenderbim/test/bim/test_feature.py +++ b/src/blenderbim/test/bim/test_feature.py @@ -302,6 +302,11 @@ def prop_is_value(prop, value): assert False, f"Value is {actual_value}" +@then(parsers.parse('the object "{name}" has the material "{material}"')) +def the_object_name_is_in_the_collection_collection(name, material): + assert material in [ms.material.name for ms in the_object_name_exists(name).material_slots] + + @then(parsers.parse('the object "{name}" is in the collection "{collection}"')) def the_object_name_is_in_the_collection_collection(name, collection): assert collection in [c.name for c in the_object_name_exists(name).users_collection] diff --git a/src/blenderbim/test/files/basic.ifc b/src/blenderbim/test/files/basic.ifc index ac80e3976f..a6a6a7179d 100644 --- a/src/blenderbim/test/files/basic.ifc +++ b/src/blenderbim/test/files/basic.ifc @@ -1,7 +1,7 @@ ISO-10303-21; HEADER; FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1'); -FILE_NAME('basic.ifc','2021-09-12T16:48:33+10:00',(),(),'IfcOpenShell 0.6.0b0','BlenderBIM 0.0.999999','Nobody'); +FILE_NAME('basic.ifc','2021-10-16T11:16:34+11:00',(),(),'IfcOpenShell v0.7.0-6cc7d796','BlenderBIM 0.0.999999','Nobody'); FILE_SCHEMA(('IFC4')); ENDSEC; DATA; @@ -85,8 +85,8 @@ DATA; #98=IFCCOLOURRGB($,0.800000011920929,0.800000011920929,0.800000011920929); #99=IFCCOLOURRGB($,0.800000011920929,0.800000011920929,0.800000011920929); #100=IFCSURFACESTYLERENDERING(#98,0.,#99,$,$,$,$,$,.NOTDEFINED.); -#101=IFCSURFACESTYLE('Material',.BOTH.,(#100)); -#102=IFCSTYLEDITEM(#92,(#101),'Material'); +#101=IFCSURFACESTYLE('SurfaceStyle',.BOTH.,(#100)); +#102=IFCSTYLEDITEM(#92,(#101),'SurfaceStyle'); #103=IFCOWNERHISTORY(#9,#8,.READWRITE.,.ADDED.,1631353439,#9,#8,1631353439); #104=IFCRELCONTAINEDINSPATIALSTRUCTURE('2T4j5EAcn0qQ9vTOZFK9HO',#103,$,$,(#79),#44); #110=IFCCARTESIANPOINT((0.,0.,0.)); @@ -109,7 +109,7 @@ DATA; #132=IFCBOUNDINGBOX(#131,2.,2.,2.); #133=IFCSHAPEREPRESENTATION(#22,'Box','BoundingBox',(#132)); #134=IFCPRODUCTDEFINITIONSHAPE($,$,(#133,#130)); -#135=IFCSTYLEDITEM(#129,(#101),'Material'); +#135=IFCSTYLEDITEM(#129,(#101),'SurfaceStyle'); #136=IFCOWNERHISTORY(#9,#8,.READWRITE.,.MODIFIED.,1631429228,#9,#8,1631353443); #137=IFCRELCONTAINEDINSPATIALSTRUCTURE('1CgivZt6z1l8IgKaTkZMcT',#136,$,$,(#116,#159),#71); #148=IFCCARTESIANPOINT((0.,0.,3.)); @@ -151,5 +151,91 @@ DATA; #214=IFCDIRECTION((1.,0.,0.)); #215=IFCAXIS2PLACEMENT3D(#212,#213,#214); #216=IFCLOCALPLACEMENT(#174,#215); +#223=IFCCARTESIANPOINT((0.,0.,0.)); +#224=IFCDIRECTION((0.,0.,1.)); +#225=IFCDIRECTION((1.,0.,0.)); +#226=IFCAXIS2PLACEMENT3D(#223,#224,#225); +#227=IFCLOCALPLACEMENT(#70,#226); +#228=IFCINDEXEDPOLYGONALFACE((4,6,5,2)); +#229=IFCINDEXEDPOLYGONALFACE((7,3,1,8)); +#230=IFCINDEXEDPOLYGONALFACE((8,1,2,5)); +#231=IFCINDEXEDPOLYGONALFACE((5,6,7,8)); +#232=IFCINDEXEDPOLYGONALFACE((3,7,6,4)); +#233=IFCINDEXEDPOLYGONALFACE((4,2,1,3)); +#234=IFCCARTESIANPOINTLIST3D(((1.,1.,1.),(1.,-1.,1.),(-1.,1.,1.),(-1.,-1.,1.),(1.,-1.,-1.),(-1.,-1.,-1.),(-1.,1.,-1.),(1.,1.,-1.))); +#235=IFCPOLYGONALFACESET(#234,$,(#228,#229,#230,#231,#232,#233),$); +#236=IFCSHAPEREPRESENTATION(#21,'Body','Tessellation',(#235)); +#237=IFCCARTESIANPOINT((-1.,-1.,-1.)); +#238=IFCBOUNDINGBOX(#237,2.,2.,2.); +#239=IFCSHAPEREPRESENTATION(#22,'Box','BoundingBox',(#238)); +#240=IFCPRODUCTDEFINITIONSHAPE($,$,(#239,#236)); +#241=IFCSTYLEDITEM(#235,(#101),'SurfaceStyle'); +#242=IFCSLABTYPE('3Yf_WvSET99eu_bTvaRiKy',#78,'Slab',$,$,$,(#259,#265),$,$,.BASESLAB.); +#243=IFCINDEXEDPOLYGONALFACE((4,6,5,2)); +#244=IFCINDEXEDPOLYGONALFACE((7,3,1,8)); +#245=IFCINDEXEDPOLYGONALFACE((8,1,2,5)); +#246=IFCINDEXEDPOLYGONALFACE((5,6,7,8)); +#247=IFCINDEXEDPOLYGONALFACE((3,7,6,4)); +#248=IFCINDEXEDPOLYGONALFACE((4,2,1,3)); +#249=IFCCARTESIANPOINTLIST3D(((1.,1.,1.),(1.,-1.,1.),(-1.,1.,1.),(-1.,-1.,1.),(1.,-1.,-1.),(-1.,-1.,-1.),(-1.,1.,-1.),(1.,1.,-1.))); +#250=IFCPOLYGONALFACESET(#249,$,(#243,#244,#245,#246,#247,#248),$); +#251=IFCSHAPEREPRESENTATION(#21,'Body','Tessellation',(#250)); +#252=IFCCARTESIANPOINT((-1.,-1.,-1.)); +#253=IFCBOUNDINGBOX(#252,2.,2.,2.); +#254=IFCSHAPEREPRESENTATION(#22,'Box','BoundingBox',(#253)); +#255=IFCCARTESIANPOINT((0.,0.,0.)); +#256=IFCDIRECTION((1.,0.,0.)); +#257=IFCDIRECTION((0.,0.,1.)); +#258=IFCAXIS2PLACEMENT3D(#255,#257,#256); +#259=IFCREPRESENTATIONMAP(#258,#254); +#260=IFCSTYLEDITEM(#250,(#101),'SurfaceStyle'); +#261=IFCCARTESIANPOINT((0.,0.,0.)); +#262=IFCDIRECTION((1.,0.,0.)); +#263=IFCDIRECTION((0.,0.,1.)); +#264=IFCAXIS2PLACEMENT3D(#261,#263,#262); +#265=IFCREPRESENTATIONMAP(#264,#251); +#272=IFCCARTESIANPOINT((0.,0.,-3.)); +#273=IFCDIRECTION((0.,0.,1.)); +#274=IFCDIRECTION((1.,0.,0.)); +#275=IFCAXIS2PLACEMENT3D(#272,#273,#274); +#276=IFCLOCALPLACEMENT(#152,#275); +#277=IFCINDEXEDPOLYGONALFACE((4,6,5,2)); +#278=IFCINDEXEDPOLYGONALFACE((7,3,1,8)); +#279=IFCINDEXEDPOLYGONALFACE((8,1,2,5)); +#280=IFCINDEXEDPOLYGONALFACE((5,6,7,8)); +#281=IFCINDEXEDPOLYGONALFACE((3,7,6,4)); +#282=IFCINDEXEDPOLYGONALFACE((4,2,1,3)); +#283=IFCCARTESIANPOINTLIST3D(((1.,1.,1.),(1.,-1.,1.),(-1.,1.,1.),(-1.,-1.,1.),(1.,-1.,-1.),(-1.,-1.,-1.),(-1.,1.,-1.),(1.,1.,-1.))); +#284=IFCPOLYGONALFACESET(#283,$,(#277,#278,#279,#280,#281,#282),$); +#285=IFCSHAPEREPRESENTATION(#21,'Body','Tessellation',(#284)); +#286=IFCCARTESIANPOINT((-1.,-1.,-1.)); +#287=IFCBOUNDINGBOX(#286,2.,2.,2.); +#288=IFCSHAPEREPRESENTATION(#22,'Box','BoundingBox',(#287)); +#289=IFCPRODUCTDEFINITIONSHAPE($,$,(#288,#285)); +#290=IFCSTYLEDITEM(#284,(#101),'SurfaceStyle'); +#291=IFCWALLTYPE('3BIuGkv6r8X8juaWvaUCg3',#115,'Wall',$,$,$,(#308,#314),$,$,.ELEMENTEDWALL.); +#292=IFCINDEXEDPOLYGONALFACE((4,6,5,2)); +#293=IFCINDEXEDPOLYGONALFACE((7,3,1,8)); +#294=IFCINDEXEDPOLYGONALFACE((8,1,2,5)); +#295=IFCINDEXEDPOLYGONALFACE((5,6,7,8)); +#296=IFCINDEXEDPOLYGONALFACE((3,7,6,4)); +#297=IFCINDEXEDPOLYGONALFACE((4,2,1,3)); +#298=IFCCARTESIANPOINTLIST3D(((1.,1.,1.),(1.,-1.,1.),(-1.,1.,1.),(-1.,-1.,1.),(1.,-1.,-1.),(-1.,-1.,-1.),(-1.,1.,-1.),(1.,1.,-1.))); +#299=IFCPOLYGONALFACESET(#298,$,(#292,#293,#294,#295,#296,#297),$); +#300=IFCSHAPEREPRESENTATION(#21,'Body','Tessellation',(#299)); +#301=IFCCARTESIANPOINT((-1.,-1.,-1.)); +#302=IFCBOUNDINGBOX(#301,2.,2.,2.); +#303=IFCSHAPEREPRESENTATION(#22,'Box','BoundingBox',(#302)); +#304=IFCCARTESIANPOINT((0.,0.,0.)); +#305=IFCDIRECTION((1.,0.,0.)); +#306=IFCDIRECTION((0.,0.,1.)); +#307=IFCAXIS2PLACEMENT3D(#304,#306,#305); +#308=IFCREPRESENTATIONMAP(#307,#303); +#309=IFCSTYLEDITEM(#299,(#101),'SurfaceStyle'); +#310=IFCCARTESIANPOINT((0.,0.,0.)); +#311=IFCDIRECTION((1.,0.,0.)); +#312=IFCDIRECTION((0.,0.,1.)); +#313=IFCAXIS2PLACEMENT3D(#310,#312,#311); +#314=IFCREPRESENTATIONMAP(#313,#300); ENDSEC; END-ISO-10303-21;