diff --git a/src/blenderbim/blenderbim/bim/module/georeference/data.py b/src/blenderbim/blenderbim/bim/module/georeference/data.py index 66df12b93b..d362027939 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/data.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/data.py @@ -56,7 +56,12 @@ class GeoreferenceData: @classmethod def map_conversion(cls): if tool.Ifc.get_schema() == "IFC2X3": - return {} + project = tool.Ifc.get().by_type("IfcProject")[0] + map_conversion = ifcopenshell.util.element.get_pset(project, "ePSet_MapConversion") + if not map_conversion: + return {} + del map_conversion["id"] + return map_conversion for context in tool.Ifc.get().by_type("IfcGeometricRepresentationContext", include_subtypes=False): if context.HasCoordinateOperation: @@ -72,8 +77,8 @@ class GeoreferenceData: def map_derived_angle(cls): if ( cls.data["map_conversion"] - and cls.data["map_conversion"]["XAxisAbscissa"] is not None - and cls.data["map_conversion"]["XAxisOrdinate"] is not None + and cls.data["map_conversion"].get("XAxisAbscissa", None) is not None + and cls.data["map_conversion"].get("XAxisOrdinate", None) is not None ): return str( round( @@ -88,7 +93,12 @@ class GeoreferenceData: @classmethod def projected_crs(cls): if tool.Ifc.get_schema() == "IFC2X3": - return {} + project = tool.Ifc.get().by_type("IfcProject")[0] + projected_crs = ifcopenshell.util.element.get_pset(project, "ePSet_ProjectedCRS") + if not projected_crs: + return {} + del projected_crs["id"] + return projected_crs for context in tool.Ifc.get().by_type("IfcGeometricRepresentationContext", include_subtypes=False): if context.HasCoordinateOperation: diff --git a/src/blenderbim/blenderbim/bim/module/georeference/ui.py b/src/blenderbim/blenderbim/bim/module/georeference/ui.py index bb75f06f5e..f401376bbe 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/ui.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/ui.py @@ -78,10 +78,14 @@ class BIM_PT_gis(Panel): def draw_ui(self, context): props = context.scene.BIMGeoreferenceProperties + if tool.Ifc.get_schema() == "IFC2X3": + row = self.layout.row() + row.label(text="IFC2X3 Fallback In Use", icon="ERROR") + if not GeoreferenceData.data["projected_crs"]: row = self.layout.row(align=True) row.label(text="Not Georeferenced") - if tool.Ifc.get_schema != "IFC2X3": + if tool.Ifc.get_schema() != "IFC2X3": row.operator("bim.add_georeferencing", icon="ADD", text="") if props.has_blender_offset: @@ -110,8 +114,9 @@ class BIM_PT_gis(Panel): if GeoreferenceData.data["projected_crs"]: row = self.layout.row(align=True) row.label(text="Projected CRS", icon="WORLD") - row.operator("bim.enable_editing_georeferencing", icon="GREASEPENCIL", text="") - row.operator("bim.remove_georeferencing", icon="X", text="") + if tool.Ifc.get_schema() != "IFC2X3": + row.operator("bim.enable_editing_georeferencing", icon="GREASEPENCIL", text="") + row.operator("bim.remove_georeferencing", icon="X", text="") for key, value in GeoreferenceData.data["projected_crs"].items(): if not value: @@ -184,4 +189,4 @@ class BIM_PT_gis_utilities(Panel): row = self.layout.row(align=True) row.prop(props, "y_axis_abscissa_output", text="North Abscissa") row = self.layout.row(align=True) - row.prop(props, "y_axis_ordinate_output", text="North Ordinate") \ No newline at end of file + row.prop(props, "y_axis_ordinate_output", text="North Ordinate") diff --git a/src/blenderbim/blenderbim/core/georeference.py b/src/blenderbim/blenderbim/core/georeference.py index dcc9823904..9c6e6de118 100644 --- a/src/blenderbim/blenderbim/core/georeference.py +++ b/src/blenderbim/blenderbim/core/georeference.py @@ -71,13 +71,13 @@ def set_cursor_location(georeference): def convert_local_to_global(georeference): - coordinates = georeference.xyz2enh(georeference.get_coordinates("input"), georeference.get_map_conversion()) + coordinates = georeference.xyz2enh(georeference.get_coordinates("input")) georeference.set_coordinates("output", coordinates) georeference.set_cursor_location(coordinates) def convert_global_to_local(georeference): - coordinates = georeference.enh2xyz(georeference.get_coordinates("input"), georeference.get_map_conversion()) + coordinates = georeference.enh2xyz(georeference.get_coordinates("input")) georeference.set_coordinates("output", coordinates) georeference.set_cursor_location(coordinates) @@ -86,4 +86,4 @@ def convert_angle_to_coord(georeference, type): georeference.set_vector_coordinates(vector_coordinates,type) def import_plot(georeference, filepath): - georeference.import_plot(filepath, georeference.get_map_conversion()) + georeference.import_plot(filepath) diff --git a/src/blenderbim/blenderbim/core/spatial.py b/src/blenderbim/blenderbim/core/spatial.py index 109168847b..0e75438933 100644 --- a/src/blenderbim/blenderbim/core/spatial.py +++ b/src/blenderbim/blenderbim/core/spatial.py @@ -17,7 +17,6 @@ # along with BlenderBIM Add-on. If not, see . import blenderbim.core -import bpy def reference_structure(ifc, spatial, structure=None, element=None): @@ -98,33 +97,43 @@ def select_similar_container(ifc, spatial, obj=None): def select_product(spatial, product): spatial.select_products([product]) + def load_container_manager(spatial): spatial.load_container_manager() + def edit_container_attributes(spatial, entity=None): spatial.edit_container_attributes(entity) spatial.load_container_manager() + def contract_container(spatial, container=None): spatial.contract_container(container) spatial.load_container_manager() + def expand_container(spatial, container=None): spatial.expand_container(container) spatial.load_container_manager() + def delete_container(ifc, spatial, geometry, container=None): geometry.delete_ifc_object(ifc.get_object(container)) spatial.load_container_manager() + def select_decomposed_elements(spatial): container = spatial.get_active_container() if container: spatial.select_products(spatial.get_decomposed_elements(container)) -#HERE STARTS SPATIAL TOOL + +# HERE STARTS SPATIAL TOOL + def generate_spaces_from_walls(ifc, spatial, collector): + import bpy + active_obj = bpy.context.active_object element = ifc.get_entity(active_obj) container = spatial.get_container(element) @@ -172,9 +181,8 @@ def generate_spaces_from_walls(ifc, spatial, collector): bpy.context.view_layer.active_layer_collection.collection.objects.link(obj) bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcSpace") container_obj = ifc.get_object(container) - blenderbim.core.spatial.assign_container( - ifc, collector, spatial, structure_obj=container_obj, element_obj=obj - ) + blenderbim.core.spatial.assign_container(ifc, collector, spatial, structure_obj=container_obj, element_obj=obj) + def toggle_space_visibility(ifc, spatial): model = ifc.get() @@ -182,4 +190,3 @@ def toggle_space_visibility(ifc, spatial): if not spaces: return spatial.toggle_spaces_visibility_wired_and_textured(spaces) - diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index de5d5f31cb..afa3a6810c 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -384,12 +384,11 @@ class Georeference: def angle2coords(cls, angle, type): pass def disable_editing(cls): pass def enable_editing(cls): pass - def enh2xyz(cls, map_conversion, coordinates): pass + def enh2xyz(cls, coordinates): pass def get_angle(cls, type): pass def get_coordinates(cls, io): pass def get_cursor_location(cls): pass def get_map_conversion_attributes(cls): pass - def get_map_conversion(cls): pass def get_projected_crs_attributes(cls): pass def get_true_north_attributes(cls): pass def import_map_conversion(cls): pass @@ -402,7 +401,7 @@ class Georeference: def set_ifc_grid_north(cls): pass def set_ifc_true_north(cls): pass def set_vector_coordinates(cls, vector_coordinates, type): pass - def xyz2enh(cls, map_conversion, coordinates): pass + def xyz2enh(cls, coordinates): pass @interface diff --git a/src/blenderbim/blenderbim/tool/georeference.py b/src/blenderbim/blenderbim/tool/georeference.py index 52c31de1a2..037b5c6645 100644 --- a/src/blenderbim/blenderbim/tool/georeference.py +++ b/src/blenderbim/blenderbim/tool/georeference.py @@ -174,15 +174,7 @@ class Georeference(blenderbim.core.tool.Georeference): ) @classmethod - def get_map_conversion(cls): - if tool.Ifc.get_schema() == "IFC2X3": - return - for context in tool.Ifc.get().by_type("IfcGeometricRepresentationContext", include_subtypes=False): - if context.HasCoordinateOperation: - return context.HasCoordinateOperation[0] - - @classmethod - def xyz2enh(cls, coordinates, map_conversion): + def xyz2enh(cls, coordinates): props = bpy.context.scene.BIMGeoreferenceProperties if props.has_blender_offset: coordinates = ifcopenshell.util.geolocation.xyz2enh( @@ -196,53 +188,12 @@ class Georeference(blenderbim.core.tool.Georeference): float(props.blender_x_axis_ordinate), 1.0, ) - if map_conversion: - unit = map_conversion.TargetCRS.MapUnit - e = map_conversion.Eastings - n = map_conversion.Northings - h = map_conversion.OrthogonalHeight - if unit: - scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) - e = ifcopenshell.util.unit.convert(e, getattr(unit, "Prefix", None), unit.Name, None, None) / scale - n = ifcopenshell.util.unit.convert(n, getattr(unit, "Prefix", None), unit.Name, None, None) / scale - h = ifcopenshell.util.unit.convert(h, getattr(unit, "Prefix", None), unit.Name, None, None) / scale - coordinates = ifcopenshell.util.geolocation.xyz2enh( - coordinates[0], - coordinates[1], - coordinates[2], - e, - n, - h, - map_conversion.XAxisAbscissa or 1.0, - map_conversion.XAxisOrdinate or 0.0, - map_conversion.Scale or 1.0, - ) - return coordinates + return ifcopenshell.util.geolocation.auto_xyz2enh(tool.Ifc.get(), *coordinates) @classmethod - def enh2xyz(cls, coordinates, map_conversion): + def enh2xyz(cls, coordinates): + coordinates = ifcopenshell.util.geolocation.auto_enh2xyz(tool.Ifc.get(), *coordinates) props = bpy.context.scene.BIMGeoreferenceProperties - if map_conversion: - unit = map_conversion.TargetCRS.MapUnit - e = map_conversion.Eastings - n = map_conversion.Northings - h = map_conversion.OrthogonalHeight - if unit: - scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) - e = ifcopenshell.util.unit.convert(e, getattr(unit, "Prefix", None), unit.Name, None, None) / scale - n = ifcopenshell.util.unit.convert(n, getattr(unit, "Prefix", None), unit.Name, None, None) / scale - h = ifcopenshell.util.unit.convert(h, getattr(unit, "Prefix", None), unit.Name, None, None) / scale - coordinates = ifcopenshell.util.geolocation.enh2xyz( - coordinates[0], - coordinates[1], - coordinates[2], - e, - n, - h, - map_conversion.XAxisAbscissa or 1.0, - map_conversion.XAxisOrdinate or 0.0, - map_conversion.Scale or 1.0, - ) if props.has_blender_offset: coordinates = ifcopenshell.util.geolocation.enh2xyz( coordinates[0], @@ -316,7 +267,7 @@ class Georeference(blenderbim.core.tool.Georeference): rows = parse_csv(filepath) vertices = [] for row in rows: - coordinates = cls.enh2xyz([float(row[0]), float(row[1]), float(row[2])], map_conversion) + coordinates = cls.enh2xyz([float(row[0]), float(row[1]), float(row[2])]) vertices.append(coordinates) mesh = bpy.data.meshes.new("mesh") diff --git a/src/blenderbim/test/core/test_georeference.py b/src/blenderbim/test/core/test_georeference.py index 957e43b232..13aee6060c 100644 --- a/src/blenderbim/test/core/test_georeference.py +++ b/src/blenderbim/test/core/test_georeference.py @@ -97,8 +97,7 @@ class TestSetCursorLocation: class TestConvertLocalToGlobal: def test_run(self, georeference): georeference.get_coordinates("input").should_be_called().will_return("coordinates") - georeference.get_map_conversion().should_be_called().will_return("map_conversion") - georeference.xyz2enh("coordinates", "map_conversion").should_be_called().will_return("enh") + georeference.xyz2enh("coordinates").should_be_called().will_return("enh") georeference.set_coordinates("output", "enh").should_be_called() georeference.set_cursor_location("enh").should_be_called() subject.convert_local_to_global(georeference) @@ -107,8 +106,7 @@ class TestConvertLocalToGlobal: class TestConvertGlobalToLocal: def test_run(self, georeference): georeference.get_coordinates("input").should_be_called().will_return("coordinates") - georeference.get_map_conversion().should_be_called().will_return("map_conversion") - georeference.enh2xyz("coordinates", "map_conversion").should_be_called().will_return("xyz") + georeference.enh2xyz("coordinates").should_be_called().will_return("xyz") georeference.set_coordinates("output", "xyz").should_be_called() georeference.set_cursor_location("xyz").should_be_called() subject.convert_global_to_local(georeference) diff --git a/src/blenderbim/test/tool/test_georeference.py b/src/blenderbim/test/tool/test_georeference.py index 8540fed870..177d9aeb6b 100644 --- a/src/blenderbim/test/tool/test_georeference.py +++ b/src/blenderbim/test/tool/test_georeference.py @@ -247,25 +247,21 @@ class TestSetBlenderTrueNorth(NewFile): assert round(math.degrees(bpy.context.scene.sun_pos_properties.north_offset)) == 45 -class TestGetMapConversion(NewFile): - def test_run(self): - ifc = ifcopenshell.file() - tool.Ifc.set(ifc) - ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") - ifcopenshell.api.run("context.add_context", ifc, context_type="Model") - ifcopenshell.api.run("georeference.add_georeferencing", ifc) - assert subject.get_map_conversion().is_a("IfcMapConversion") - - class TestXyz2Enh(NewFile): def test_run(self): - assert subject.xyz2enh([0.0, 0.0, 0.0], None) == [0.0, 0.0, 0.0] + ifc = ifcopenshell.file() + ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") + tool.Ifc.set(ifc) + assert subject.xyz2enh([0.0, 0.0, 0.0]) == (0.0, 0.0, 0.0) def test_using_the_blender_offset(self): + ifc = ifcopenshell.file() + ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") + tool.Ifc.set(ifc) props = bpy.context.scene.BIMGeoreferenceProperties props.has_blender_offset = True props.blender_eastings = "1.0" - assert subject.xyz2enh([0.0, 0.0, 0.0], None) == (1.0, 0.0, 0.0) + assert subject.xyz2enh([0.0, 0.0, 0.0]) == (1.0, 0.0, 0.0) def test_using_the_map_conversion(self): ifc = ifcopenshell.file() @@ -275,7 +271,7 @@ class TestXyz2Enh(NewFile): ifcopenshell.api.run("georeference.add_georeferencing", ifc) map_conversion = ifc.by_type("IfcMapConversion")[0] map_conversion.Eastings = 1.0 - assert subject.xyz2enh([0.0, 0.0, 0.0], map_conversion) == (1.0, 0.0, 0.0) + assert subject.xyz2enh([0.0, 0.0, 0.0]) == (1.0, 0.0, 0.0) def test_applying_both_blender_offset_and_map_conversion(self): props = bpy.context.scene.BIMGeoreferenceProperties @@ -288,18 +284,24 @@ class TestXyz2Enh(NewFile): ifcopenshell.api.run("georeference.add_georeferencing", ifc) map_conversion = ifc.by_type("IfcMapConversion")[0] map_conversion.Northings = 1.0 - assert subject.xyz2enh([0.0, 0.0, 0.0], map_conversion) == (1.0, 1.0, 0.0) + assert subject.xyz2enh([0.0, 0.0, 0.0]) == (1.0, 1.0, 0.0) class TestEnh2Xyz(NewFile): def test_run(self): - assert subject.enh2xyz([0.0, 0.0, 0.0], None) == [0.0, 0.0, 0.0] + ifc = ifcopenshell.file() + ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") + tool.Ifc.set(ifc) + assert subject.enh2xyz([0.0, 0.0, 0.0]) == (0.0, 0.0, 0.0) def test_using_the_blender_offset(self): + ifc = ifcopenshell.file() + ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject") + tool.Ifc.set(ifc) props = bpy.context.scene.BIMGeoreferenceProperties props.has_blender_offset = True props.blender_eastings = "1.0" - assert subject.enh2xyz([0.0, 0.0, 0.0], None) == (-1.0, 0.0, 0.0) + assert subject.enh2xyz([0.0, 0.0, 0.0]) == (-1.0, 0.0, 0.0) def test_using_the_map_conversion(self): ifc = ifcopenshell.file() @@ -309,7 +311,7 @@ class TestEnh2Xyz(NewFile): ifcopenshell.api.run("georeference.add_georeferencing", ifc) map_conversion = ifc.by_type("IfcMapConversion")[0] map_conversion.Eastings = 1.0 - assert subject.enh2xyz([0.0, 0.0, 0.0], map_conversion) == (-1.0, 0.0, 0.0) + assert subject.enh2xyz([0.0, 0.0, 0.0]) == (-1.0, 0.0, 0.0) def test_applying_both_blender_offset_and_map_conversion(self): props = bpy.context.scene.BIMGeoreferenceProperties @@ -322,7 +324,7 @@ class TestEnh2Xyz(NewFile): ifcopenshell.api.run("georeference.add_georeferencing", ifc) map_conversion = ifc.by_type("IfcMapConversion")[0] map_conversion.Northings = 1.0 - assert subject.enh2xyz([0.0, 0.0, 0.0], map_conversion) == (-1.0, -1.0, 0.0) + assert subject.enh2xyz([0.0, 0.0, 0.0]) == (-1.0, -1.0, 0.0) class TestSetIfcGridNorth(NewFile):