From a3844fe09860e6198e84c3a377647c3f3090ae10 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 7 Jul 2024 23:59:13 +1000 Subject: [PATCH] More tests and fixes for linking in models with different project norths --- .../blenderbim/bim/module/project/operator.py | 2 +- src/blenderbim/blenderbim/tool/loader.py | 15 ++-- .../test/bim/feature/project.feature | 71 +++++++++++++++++-- src/blenderbim/test/bim/test_feature.py | 7 +- 4 files changed, 83 insertions(+), 12 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/project/operator.py b/src/blenderbim/blenderbim/bim/module/project/operator.py index b7b2cd944b..68f7360c9d 100644 --- a/src/blenderbim/blenderbim/bim/module/project/operator.py +++ b/src/blenderbim/blenderbim/bim/module/project/operator.py @@ -1112,7 +1112,7 @@ except Exception as e: data = json.load(f) gprops = bpy.context.scene.BIMGeoreferenceProperties - for prop in ("model_origin", "blender_x_axis_abscissa", "blender_x_axis_ordinate"): + for prop in ("model_origin", "model_project_north"): if (value := data.get(prop, None)) is not None: setattr(gprops, prop, value) diff --git a/src/blenderbim/blenderbim/tool/loader.py b/src/blenderbim/blenderbim/tool/loader.py index 15067b16e4..e2fd6345a5 100644 --- a/src/blenderbim/blenderbim/tool/loader.py +++ b/src/blenderbim/blenderbim/tool/loader.py @@ -564,9 +564,12 @@ class Loader(blenderbim.core.tool.Loader): @classmethod def set_manual_blender_offset(cls, ifc_file: ifcopenshell.file) -> None: - model_origin = np.array(ifcopenshell.util.geolocation.auto_xyz2enh(ifc_file, 0, 0, 0)) false_origin = np.array(cls.settings.false_origin) - model_offset = false_origin - model_origin + model_offset = np.array( + ifcopenshell.util.geolocation.auto_enh2xyz( + ifc_file, *cls.settings.false_origin, is_specified_in_map_units=False + ) + ) zero_origin = np.array((0, 0, 0)) has_offset = not np.allclose(model_offset, zero_origin) @@ -582,7 +585,7 @@ class Loader(blenderbim.core.tool.Loader): if not has_offset: model_offset = false_origin = (0, 0, 0) - if not has_rotation: + if np.isclose(project_north, 0): project_north = 0 if has_offset or has_rotation: @@ -676,6 +679,8 @@ class Loader(blenderbim.core.tool.Loader): if offset_point is None: return cls.settings.false_origin = ifcopenshell.util.geolocation.auto_xyz2enh(ifc_file, *offset_point) + if angle := ifcopenshell.util.geolocation.get_grid_north(ifc_file): + cls.settings.project_north = angle cls.set_manual_blender_offset(ifc_file) @classmethod @@ -742,7 +747,5 @@ class Loader(blenderbim.core.tool.Loader): ) gprops.model_project_north = gprops.blender_project_north else: - gprops.model_origin = ",".join( - map(str, ifcopenshell.util.geolocation.auto_xyz2enh(ifc_file, 0, 0, 0)) - ) + gprops.model_origin = ",".join(map(str, ifcopenshell.util.geolocation.auto_xyz2enh(ifc_file, 0, 0, 0))) gprops.model_project_north = str(ifcopenshell.util.geolocation.get_grid_north(ifc_file)) diff --git a/src/blenderbim/test/bim/feature/project.feature b/src/blenderbim/test/bim/feature/project.feature index 0fd1458f80..85f90b1aa5 100644 --- a/src/blenderbim/test/bim/feature/project.feature +++ b/src/blenderbim/test/bim/feature/project.feature @@ -454,10 +454,10 @@ Scenario: Load project elements - all georeferencing coordinate situations with Scenario: Load project elements - all georeferencing coordinate situations with an offset site - manual false origin mode Given an empty Blender session And I press "bim.load_project(filepath='{cwd}/test/files/geolocation-offsetsite.ifc', is_advanced=True)" - When I set "scene.BIMProjectProperties.false_origin_mode" to "MANUAL" - When I set "scene.BIMProjectProperties.false_origin" to "0,10000,0" - When I set "scene.BIMProjectProperties.distance_limit" to "5" - And I press "bim.load_project_elements" + And I set "scene.BIMProjectProperties.false_origin_mode" to "MANUAL" + And I set "scene.BIMProjectProperties.false_origin" to "0,10000,0" + And I set "scene.BIMProjectProperties.distance_limit" to "5" + When I press "bim.load_project_elements" Then "scene.BIMGeoreferenceProperties.has_blender_offset" is "True" And "scene.BIMGeoreferenceProperties.blender_eastings" is "0.0" And "scene.BIMGeoreferenceProperties.blender_northings" is "10000.0" @@ -489,6 +489,36 @@ Scenario: Load project elements - all georeferencing coordinate situations with And the object "IfcActuator/J" has a vertex at "10.366,3.813,-1" And the object "IfcActuator/J" has a vertex at "12.298,4.331,-1" +Scenario: Load project elements - all georeferencing coordinate situations with an offset site - manual false origin mode - with custom project north + Given an empty Blender session + And I press "bim.load_project(filepath='{cwd}/test/files/geolocation-offsetsite.ifc', is_advanced=True)" + And I set "scene.BIMProjectProperties.false_origin_mode" to "MANUAL" + And I set "scene.BIMProjectProperties.false_origin" to "0,10000,0" + And I set "scene.BIMProjectProperties.project_north" to "-15" + And I set "scene.BIMProjectProperties.distance_limit" to "5" + When I press "bim.load_project_elements" + Then "scene.BIMGeoreferenceProperties.has_blender_offset" is "True" + And "scene.BIMGeoreferenceProperties.blender_eastings" is "0.0" + And "scene.BIMGeoreferenceProperties.blender_northings" is "10000.0" + And "scene.BIMGeoreferenceProperties.blender_orthogonal_height" is "0.0" + And "scene.BIMGeoreferenceProperties.blender_offset_x" is "0.0" + And "scene.BIMGeoreferenceProperties.blender_offset_y" is "10000.0" + And "scene.BIMGeoreferenceProperties.blender_offset_z" is "0.0" + And the object "IfcSite/My Site" is at "0,0,0" + And the object "IfcBuilding/My Building" is at "0,0,0" + And the object "IfcBuildingStorey/My Storey" is at "0,0,0" + And the object "IfcActuator/A" is at "7,3,0" + And the object "IfcActuator/B" is at "6,1,0" + And the object "IfcActuator/C" is at "0,0,0" + And the object "IfcActuator/D" is at "13,4,-1" + And the object "IfcActuator/E" is at "6,3,0" + And the object "IfcActuator/F" is at "3,3,0" + And the object "IfcActuator/G" is at "15,6,-1" + And the object "IfcActuator/H" is at "9,2,0" + And the object "IfcActuator/I" is at "3,3,0" + And the object "IfcActuator/J" is at "11,3,-1" + And the object "IfcActuator/K" is at "10,0,0" + Scenario: Load project elements - all georeferencing coordinate situations with a map conversion - disabled false origin mode (this should be identical to the situation with no map conversion) Given an empty Blender session And I press "bim.load_project(filepath='{cwd}/test/files/geolocation-mapconversion.ifc', is_advanced=True)" @@ -718,6 +748,39 @@ Scenario: Link IFC - manual false origin mode And the object "Chunk" has a vertex at "-1,-1,-1" And the object "Chunk" has a vertex at "7,4,-1" +Scenario: Link IFC - automatic false origin mode - two different false origins and project norths - grid north is up because we start with geolocation.ifc + Given an empty Blender session + # Not currently possible via UI + And I set "scene.BIMProjectProperties.distance_limit" to "5" + And I set "scene.BIMProjectProperties.false_origin_mode" to "AUTOMATIC" + When I press "bim.link_ifc(filepath='{cwd}/test/files/geolocation.ifc', use_cache=False)" + And I press "bim.link_ifc(filepath='{cwd}/test/files/geolocation-mapconversion-angle.ifc', use_cache=False)" + Then the object "Col:IfcProject/geolocation.ifc:Chunk" exists + And the object "Col:IfcProject/geolocation-mapconversion-angle.ifc:Chunk" exists + And the object "Col:IfcProject/geolocation.ifc:Chunk" has a vertex at "-11,-2,0" + And the object "Col:IfcProject/geolocation.ifc:Chunk" has a vertex at "-4,-5,0" + And the object "Col:IfcProject/geolocation.ifc:Chunk" has a vertex at "4,0,0" + And the object "Col:IfcProject/geolocation-mapconversion-angle.ifc:Chunk" has a vertex at "4.732,-3.268,0" + And the object "Col:IfcProject/geolocation-mapconversion-angle.ifc:Chunk" has a vertex at "9.294,-9.366,0" + And the object "Col:IfcProject/geolocation-mapconversion-angle.ifc:Chunk" has a vertex at "18.722,-9.036,0" + +Scenario: Link IFC - automatic false origin mode - two different false origins and project norths - project north is up because we start with geolocation-mapconversion-angle.ifc + Given an empty Blender session + # Not currently possible via UI + And I set "scene.BIMProjectProperties.distance_limit" to "5" + And I set "scene.BIMProjectProperties.false_origin_mode" to "AUTOMATIC" + When I press "bim.link_ifc(filepath='{cwd}/test/files/geolocation-mapconversion-angle.ifc', use_cache=False)" + And I press "bim.link_ifc(filepath='{cwd}/test/files/geolocation.ifc', use_cache=False)" + Then the object "Col:IfcProject/geolocation.ifc:Chunk" exists + And the object "Col:IfcProject/geolocation-mapconversion-angle.ifc:Chunk" exists + And the object "Col:IfcProject/geolocation-mapconversion-angle.ifc:Chunk" has a vertex at "-11,-2,0" + And the object "Col:IfcProject/geolocation-mapconversion-angle.ifc:Chunk" has a vertex at "-4,-5,0" + And the object "Col:IfcProject/geolocation-mapconversion-angle.ifc:Chunk" has a vertex at "4,0,0" + And the object "Col:IfcProject/geolocation.ifc:Chunk" has a vertex at "-25.258,-8.768,0" + And the object "Col:IfcProject/geolocation.ifc:Chunk" has a vertex at "-17.696,-7.866,0" + And the object "Col:IfcProject/geolocation.ifc:Chunk" has a vertex at "-13.268,0.464,0" + + Scenario: Toggle link visibility - wireframe mode Given an empty IFC project And I press "bim.link_ifc(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 9e7ba63eb8..c51f1e4ae9 100644 --- a/src/blenderbim/test/bim/test_feature.py +++ b/src/blenderbim/test/bim/test_feature.py @@ -373,7 +373,12 @@ def nothing_happens(): @then(parsers.parse('the object "{name}" exists')) def the_object_name_exists(name: str) -> bpy.types.Object: - obj = bpy.data.objects.get(name) + # Some objects from linked collections may share the same name. This disambiguates them. + if name.startswith("Col:"): + _, collection_name, name = name.split(":") + obj = bpy.data.collections.get(collection_name).objects.get(name) + else: + obj = bpy.data.objects.get(name) if not obj: assert False, f'The object "{name}" does not exist' return obj