diff --git a/src/blenderbim/blenderbim/bim/module/georeference/__init__.py b/src/blenderbim/blenderbim/bim/module/georeference/__init__.py index 7d644a30df..609e9ce0d2 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/__init__.py @@ -25,14 +25,14 @@ classes = ( operator.EditGeoreferencing, operator.SetIfcGridNorth, operator.SetBlenderGridNorth, - operator.SetIfcTrueNorth, - operator.SetBlenderTrueNorth, +# operator.SetIfcTrueNorth, +# operator.SetBlenderTrueNorth, operator.RemoveGeoreferencing, operator.AddGeoreferencing, - operator.ConvertLocalToGlobal, - operator.ConvertGlobalToLocal, - operator.GetCursorLocation, - operator.SetCursorLocation, +# operator.ConvertLocalToGlobal, +# operator.ConvertGlobalToLocal, +# operator.GetCursorLocation, +# operator.SetCursorLocation, prop.BIMGeoreferenceProperties, ui.BIM_PT_gis, ui.BIM_PT_gis_utilities, diff --git a/src/blenderbim/blenderbim/bim/module/georeference/data.py b/src/blenderbim/blenderbim/bim/module/georeference/data.py index 263e75774e..2fa8ef89a0 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/data.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/data.py @@ -16,6 +16,8 @@ # You should have received a copy of the GNU General Public License # along with BlenderBIM Add-on. If not, see . +# ############################################################################ # + import blenderbim.tool as tool def refresh(): @@ -33,6 +35,20 @@ class GeoreferenceData: "true_north" : cls.true_north(), } cls.is_loaded = True + + @classmethod + def is_georeferenced(cls): + ifc = tool.Ifc.get() + if ifc.schema == "IFC2X3": + return + + map_conversions = [] + for context in ifc.by_type("IfcGeometricRepresentationContext", include_subtypes=False): + if not context.HasCoordinateOperation: + continue + map_conversions.append(context) + + return True if map_conversions else False @classmethod def map_conversion(cls): diff --git a/src/blenderbim/blenderbim/bim/module/georeference/operator.py b/src/blenderbim/blenderbim/bim/module/georeference/operator.py index b41a36379a..62e8e02b7d 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/operator.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/operator.py @@ -19,6 +19,7 @@ import bpy import blenderbim.tool as tool import blenderbim.core.georeference as core +import blenderbim.bim.handler class AddGeoreferencing(bpy.types.Operator, tool.Ifc.Operator): bl_idname = "bim.add_georeferencing" @@ -78,85 +79,10 @@ class SetBlenderGridNorth(bpy.types.Operator, tool.Ifc.Operator): bl_idname = "bim.set_blender_grid_north" bl_label = "Set Blender Grid North" bl_options = {"REGISTER", "UNDO"} - bl_description = "Set Blender grid north" + bl_description = "Set Blender grif north" def _execute(self, context): core.set_blender_grid_north() -class GetCursorLocation(bpy.types.Operator, tool.Ifc.Operator): - bl_idname = "bim.get_cursor_location" - bl_label = "Get Cursor Location" - bl_options = {"REGISTER", "UNDO"} - bl_description = "Insert the current cursor coordinates" - - @classmethod - def poll(cls, context): #TODO is it right to use the poll method? - file = tool.Ifc.get() - return file and file.by_type("IfcUnitAssignment") - - def _execute(self, context): - core.get_cursor_location(tool.Georeference) - -class SetCursorLocation(bpy.types.Operator, tool.Ifc.Operator): - bl_idname = "bim.set_cursor_location" - bl_label = "Set Cursor Location" - bl_options = {"REGISTER", "UNDO"} - bl_description = "Set curson location to coordinates" - @classmethod - def poll(cls, context): #TODO is it right to use the poll method? - file = tool.Ifc.get() - props = context.scene.BIMGeoreferenceProperties - return file and file.by_type("IfcUnitAssignment") and props.coordinate_output.count(",") == 2 - - def _execute(self, context): - core.set_cursor_location(tool.Georeference) - -class SetIfcTrueNorth(bpy.types.Operator, tool.Ifc.Operator): - bl_idname = "bim.set_ifc_true_north" - bl_label = "Set IFC True North" - bl_options = {"REGISTER", "UNDO"} - bl_description = "Set IFC True north" - - def _execute(self, context): - core.set_ifc_true_north(tool.Georeference) - -class SetBlenderTrueNorth(bpy.types.Operator, tool.Ifc.Operator): - bl_idname = "bim.set_blender_true_north" - bl_label = "Set Blender True North" - bl_options = {"REGISTER", "UNDO"} - bl_description = "Set Blender true north" - - def _execute(self, context): - core.set_blender_true_north(tool.Georeference) - -class ConvertLocalToGlobal(bpy.types.Operator, tool.Ifc.Operator): - bl_idname = "bim.convert_local_to_global" - bl_label = "Convert Local To Global" - bl_options = {"REGISTER", "UNDO"} - bl_description = "Convert local coordinate to global coordinate" - - @classmethod - def poll(cls, context): - file = tool.Ifc.get() - props = context.scene.BIMGeoreferenceProperties - return file and props.coordinate_input.count(",") == 2 - - def _execute(self, context): - core.convert_local_to_global(tool.Georeference) - -class ConvertGlobalToLocal(bpy.types.Operator, tool.Ifc.Operator): - bl_idname = "bim.convert_global_to_local" - bl_label = "Convert Global To Local" - bl_options = {"REGISTER", "UNDO"} - bl_description = "Convert global coordinate to local coordinate" - - @classmethod - def poll(cls, context): - file = tool.Ifc.get() - props = context.scene.BIMGeoreferenceProperties - return file and file.by_type("IfcUnitAssignment") and props.coordinate_input.count(",") == 2 - - def _execute(self, context): - core.convert_global_to_local(tool.Georeference) diff --git a/src/blenderbim/blenderbim/bim/module/georeference/ui.py b/src/blenderbim/blenderbim/bim/module/georeference/ui.py index 93dcc34c38..984590e51c 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/ui.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/ui.py @@ -18,6 +18,7 @@ import ifcopenshell.util.geolocation from bpy.types import Panel +#from ifcopenshell.api.georeference.data import Data from blenderbim.bim.ifc import IfcStore from blenderbim.bim.helper import draw_attributes, draw_attribute from blenderbim.bim.module.georeference.data import GeoreferenceData @@ -72,8 +73,8 @@ class BIM_PT_gis(Panel): row.prop(props, "true_north_ordinate") if hasattr(context.scene, "sun_pos_properties"): row = self.layout.row(align=True) - row.operator("bim.set_ifc_true_north", text="Set IFC North") - row.operator("bim.set_blender_true_north", text="Set Blender North") + # row.operator("bim.set_ifc_true_north", text="Set IFC North") + # row.operator("bim.set_blender_true_north", text="Set Blender North") def draw_ui(self, context): @@ -82,7 +83,7 @@ class BIM_PT_gis(Panel): if not GeoreferenceData.data["projected_crs"]: row = self.layout.row(align=True) row.label(text="Not Georeferenced") - if IfcStore.get_file().schema != "IFC2X3": #TODO Is it correct to use IfcStore.get_file() or is it better tool.Ifc.get()? + if IfcStore.get_file().schema != "IFC2X3": row.operator("bim.add_georeferencing", icon="ADD", text="") if props.has_blender_offset: @@ -178,19 +179,16 @@ class BIM_PT_gis_utilities(Panel): bl_category = "BlenderBIM" def draw(self, context): - if not GeoreferenceData.is_loaded: - GeoreferenceData.load() - props = context.scene.BIMGeoreferenceProperties row = self.layout.row(align=True) row.prop(props, "coordinate_input", text="Input") - row.operator("bim.get_cursor_location", text="", icon="TRACKER") + #row.operator("bim.get_cursor_location", text="", icon="TRACKER") row = self.layout.row(align=True) row.prop(props, "coordinate_output", text="Output") - row.operator("bim.set_cursor_location", text="", icon="TRACKER") + #row.operator("bim.set_cursor_location", text="", icon="TRACKER") row = self.layout.row(align=True) - row.operator("bim.convert_local_to_global", text="Local to Global") - row.operator("bim.convert_global_to_local", text="Global to Local") + #row.operator("bim.convert_local_to_global", text="Local to Global") + #row.operator("bim.convert_global_to_local", text="Global to Local") diff --git a/src/blenderbim/blenderbim/core/georeference.py b/src/blenderbim/blenderbim/core/georeference.py index 4e5a174b90..4ef8dcf960 100644 --- a/src/blenderbim/blenderbim/core/georeference.py +++ b/src/blenderbim/blenderbim/core/georeference.py @@ -18,60 +18,71 @@ import bpy import blenderbim.bim.helper +import ifcopenshell from blenderbim.bim.module.georeference.data import GeoreferenceData -from math import radians, degrees, atan, tan, cos, sin - def add_georeferencing(ifc): ifc.run("georeference.add_georeferencing") -def enable_editing_georeferencing(georeference): - props = bpy.context.scene.BIMGeoreferenceProperties - +def enable_editing_georeferencing(georeference): #TODO simplify this function georeference.clear_projected_crs() blenderbim.bim.helper.import_attributes( "IfcProjectedCRS", - props.projected_crs, + bpy.context.scene.BIMGeoreferenceProperties.projected_crs, GeoreferenceData.data["projected_crs"], georeference.import_projected_crs_attributes, ) - + georeference.clear_map_conversion() - + blenderbim.bim.helper.import_attributes( "IfcMapConversion", - props.map_conversion, + bpy.context.scene.BIMGeoreferenceProperties.map_conversion, GeoreferenceData.data["map_conversion"], georeference.import_map_conversion_attributes, ) - georeference.set_has_true_north_prop(GeoreferenceData.data["true_north"]) - georeference.set_true_north_prop(GeoreferenceData.data["true_north"]) - georeference.enable_editing() + bpy.context.scene.BIMGeoreferenceProperties.has_true_north = bool(GeoreferenceData.data["true_north"]) + + if GeoreferenceData.data["true_north"]: + bpy.context.scene.BIMGeoreferenceProperties.true_north_abscissa = str(GeoreferenceData.data["true_north"][0]) + bpy.context.scene.BIMGeoreferenceProperties.true_north_ordinate = str(GeoreferenceData.data["true_north"][1]) + + bpy.context.scene.BIMGeoreferenceProperties.is_editing = True def remove_georeferencing(ifc): ifc.run("georeference.remove_georeferencing") def edit_georeferencing(ifc, georeference): props = bpy.context.scene.BIMGeoreferenceProperties + ifc_file = georeference.get_file() projected_crs = blenderbim.bim.helper.export_attributes(props.projected_crs, georeference.export_crs_attributes) map_conversion = blenderbim.bim.helper.export_attributes(props.map_conversion, georeference.export_map_attributes) - - true_north = georeference.get_true_north_props(props) - - ifc.run( + + true_north = None +# if props.has_true_north: +# try: +# true_north = [float(props.true_north_abscissa), float(props.true_north_ordinate)] +# except ValueError: +# self.report({"ERROR"}, "True North Abscissa and Ordinate expect a number") + + ifcopenshell.api.run( #TODO use ifc.run "georeference.edit_georeferencing", + ifc_file, **{ "map_conversion": map_conversion, "projected_crs": projected_crs, "true_north": true_north, } ) - - georeference.disable_editing() + + bpy.ops.bim.disable_editing_georeferencing() + +def disable_editing_georeferencing(georeference): + georeference.set_false_is_editing() def set_ifc_grid_north(georeference): georeference.set_ifc_grid_north() @@ -79,21 +90,4 @@ def set_ifc_grid_north(georeference): def set_blender_grid_north(georeference): georeference.set_blender_grid_north() -def get_cursor_location(georeference): - georeference.get_cursor_location() - -def set_cursor_location(georeference): - georeference.set_cursor_location() - -def set_ifc_true_north(georeference): - georeference.set_ifc_true_north() - -def set_blender_true_north(georeference): - georeference.set_blender_true_north() - -def convert_local_to_global(georeference): - georeference.convert_local_to_global(GeoreferenceData.data["map_conversion"]) - -def convert_global_to_local(georeference): - georeference.convert_global_to_local(GeoreferenceData.data["map_conversion"]) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index da0733aef4..8d5997e8c4 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -250,24 +250,15 @@ class Geometry: class Georeference: def clear_projected_crs(cls): pass def clear_map_conversion(cls): pass - def set_has_true_north_prop(cls, data): pass - def set_true_north_prop(cls, data): pass - def get_true_north_props(cls, props): pass - def enable_editing(cls): pass - def disable_editing(cls): pass def get_file(cls): pass + def set_false_is_editing(cls): pass def import_projected_crs_attributes(cls, name, prop, data): pass def import_map_conversion_attributes(cls, name, prop, data): pass def export_crs_attributes(cls, attributes, prop): pass def export_map_attributes(cls, attributes, prop): pass def set_ifc_grid_north(cls): pass def set_blender_grid_north(cls): pass - def get_cursor_location(cls): pass - def set_cursor_location(cls): pass - def set_ifc_true_north(cls): pass - def set_blender_true_north(cls): pass - def convert_local_to_global(cls, map_conversion): pass - def convert_global_to_local(cls, map_conversion): pass + @interface class Ifc: diff --git a/src/blenderbim/blenderbim/tool/georeference.py b/src/blenderbim/blenderbim/tool/georeference.py index 587acfcabe..16ee96efe0 100644 --- a/src/blenderbim/blenderbim/tool/georeference.py +++ b/src/blenderbim/blenderbim/tool/georeference.py @@ -17,13 +17,11 @@ # along with BlenderBIM Add-on. If not, see . - import bpy import json import blenderbim.core.tool import blenderbim.tool as tool import ifcopenshell -import blenderbim.bim.helper from ifcopenshell.api.unit.data import Data as UnitData @@ -37,34 +35,6 @@ class Georeference(blenderbim.core.tool.Georeference): def clear_map_conversion(cls): bpy.context.scene.BIMGeoreferenceProperties.map_conversion.clear() - @classmethod - def set_has_true_north_prop(cls, data): - bpy.context.scene.BIMGeoreferenceProperties.has_true_north = bool(data) - - @classmethod - def set_true_north_prop(cls, data): - if data: - bpy.context.scene.BIMGeoreferenceProperties.true_north_abscissa = str(data[0]) - bpy.context.scene.BIMGeoreferenceProperties.true_north_ordinate = str(data[1]) - - @classmethod - def get_true_north_props(cls, props): - true_north = None - if props.has_true_north: - try: - true_north = [float(props.true_north_abscissa), float(props.true_north_ordinate)] - except ValueError: - self.report({"ERROR"}, "True North Abscissa and Ordinate expect a number") #TODO use the correct report method - return true_north - - @classmethod - def enable_editing(cls): - bpy.context.scene.BIMGeoreferenceProperties.is_editing = True - - @classmethod - def disable_editing(cls): - bpy.context.scene.BIMGeoreferenceProperties.is_editing = False - @classmethod def get_file(cls): return tool.Ifc.get() @@ -93,7 +63,7 @@ class Georeference(blenderbim.core.tool.Georeference): return True @classmethod - def export_crs_attributes(cls, attributes, prop): + def export_crs_attributes(cls, attributes, prop,): ifc_file = tool.Ifc.get() if not prop.is_null and prop.name == "MapUnit": attributes[prop.name] = ifc_file.by_id(int(prop.enum_value)) @@ -106,6 +76,11 @@ class Georeference(blenderbim.core.tool.Georeference): attributes[prop.name] = float(prop.string_value) return True + @classmethod + def set_false_is_editing(cls): + props = bpy.context.scene.BIMGeoreferenceProperties + props.is_editing = False + @classmethod def set_ifc_grid_north(cls): x_angle = -bpy.context.scene.sun_pos_properties.north_offset @@ -121,111 +96,4 @@ class Georeference(blenderbim.core.tool.Georeference): ) ) - @classmethod - def get_cursor_location(cls): - props = bpy.context.scene.BIMGeoreferenceProperties - scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) - project_coordinates = [o / scale for o in bpy.context.scene.cursor.location] - props.coordinate_input = ",".join([str(o) for o in project_coordinates]) - - - @classmethod - def set_cursor_location(cls): - props = bpy.context.scene.BIMGeoreferenceProperties - scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) - bpy.context.scene.cursor.location = [float(co) * scale for co in props.coordinate_output.split(",")] - - @classmethod - def set_ifc_true_north(cls): - y_angle = -bpy.context.scene.sun_pos_properties.north_offset + radians(90) - bpy.context.scene.BIMGeoreferenceProperties.true_north_abscissa = str(cos(y_angle)) - bpy.context.scene.BIMGeoreferenceProperties.true_north_ordinate = str(sin(y_angle)) - - @classmethod - def set_blender_true_north(cls): - bpy.context.scene.sun_pos_properties.north_offset = -radians( - ifcopenshell.util.geolocation.yaxis2angle( - float(context.scene.BIMGeoreferenceProperties.true_north_abscissa), - float(context.scene.BIMGeoreferenceProperties.true_north_ordinate), - ) - ) - - - @classmethod - def convert_local_to_global(cls, map_conversion): - props = bpy.context.scene.BIMGeoreferenceProperties - x, y, z = [float(co) for co in props.coordinate_input.split(",")] - - if props.has_blender_offset: - results = ifcopenshell.util.geolocation.xyz2enh( - x, - y, - z, - float(props.blender_eastings), - float(props.blender_northings), - float(props.blender_orthogonal_height), - float(props.blender_x_axis_abscissa), - float(props.blender_x_axis_ordinate), - 1.0, - ) - x, y, z = results - - # TODO: what if the project CRS units and the project units are different? - - if map_conversion: - results = ifcopenshell.util.geolocation.xyz2enh( - x, - y, - z, - map_conversion["Eastings"], - map_conversion["Northings"], - map_conversion["OrthogonalHeight"], - map_conversion.get("XAxisAbscissa", 1.0), - map_conversion.get("XAxisOrdinate", 0.0), - map_conversion.get("Scale", 1.0), - ) - else: - results = (x, y, z) - - props.coordinate_output = ",".join([str(r) for r in results]) - bpy.context.scene.cursor.location = results - - @classmethod - def convert_global_to_local(cls, map_conversion): - props = bpy.context.scene.BIMGeoreferenceProperties - - x, y, z = [float(co) for co in props.coordinate_input.split(",")] - - if map_conversion: - results = ifcopenshell.util.geolocation.enh2xyz( - x, - y, - z, - map_conversion["Eastings"], - map_conversion["Northings"], - map_conversion["OrthogonalHeight"], - map_conversion.get("XAxisAbscissa", 1.0), - map_conversion.get("XAxisOrdinate", 0.0), - map_conversion.get("Scale", 1.0), - ) - else: - results = (x, y, z) - - if props.has_blender_offset: - results = ifcopenshell.util.geolocation.enh2xyz( - results[0], - results[1], - results[2], - float(props.blender_eastings), - float(props.blender_northings), - float(props.blender_orthogonal_height), - float(props.blender_x_axis_abscissa), - float(props.blender_x_axis_ordinate), - 1.0, - ) - - props.coordinate_output = ",".join([str(r) for r in results]) - - scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) - bpy.context.scene.cursor.location = [o * scale for o in results]