diff --git a/src/blenderbim/blenderbim/bim/module/georeference/__init__.py b/src/blenderbim/blenderbim/bim/module/georeference/__init__.py index 7d644a30df..146ce8b1c3 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/__init__.py @@ -33,6 +33,7 @@ classes = ( operator.ConvertGlobalToLocal, operator.GetCursorLocation, operator.SetCursorLocation, + operator.ConvertAngleToCoordinates, prop.BIMGeoreferenceProperties, ui.BIM_PT_gis, ui.BIM_PT_gis_utilities, diff --git a/src/blenderbim/blenderbim/bim/module/georeference/operator.py b/src/blenderbim/blenderbim/bim/module/georeference/operator.py index 71bde91ba8..cbcfe930ea 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/operator.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/operator.py @@ -171,3 +171,19 @@ class ConvertGlobalToLocal(bpy.types.Operator, tool.Ifc.Operator): def _execute(self, context): core.convert_global_to_local(tool.Georeference) + +class ConvertAngleToCoordinates(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.convert_angle_to_coord" + bl_label = "Convert Angle To Y Axis" + bl_options = {"REGISTER", "UNDO"} + bl_description = "Convert angle to Y axis" + type: bpy.props.StringProperty() + + @classmethod + def poll(cls, context): + file = tool.Ifc.get() + props = context.scene.BIMGeoreferenceProperties + return file and (props.angle_degree_input_x or props.angle_degree_input_y) + + def _execute(self, context): + core.convert_angle_to_coord(tool.Georeference, type=self.type) diff --git a/src/blenderbim/blenderbim/bim/module/georeference/prop.py b/src/blenderbim/blenderbim/bim/module/georeference/prop.py index b85cb01275..efac699ed3 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/prop.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/prop.py @@ -37,6 +37,12 @@ class BIMGeoreferenceProperties(PropertyGroup): projected_crs: CollectionProperty(name="Projected CRS", type=Attribute) coordinate_input: StringProperty(name="Coordinate Input", description='Formatted "x,y,z" (without quotes)') coordinate_output: StringProperty(name="Coordinate Output", description='Formatted "x,y,z" (without quotes)') + angle_degree_input_x: FloatProperty(name="Angle Degree Input", description="Angle (in degrees) rel to Easting") + angle_degree_input_y: FloatProperty(name="Angle Degree Input", description="Angle (in degrees) rel to +Y") + x_axis_abscissa_output: StringProperty(name="X Axis Abscissa Ordinate Output", description="X axis abscissa and ordinate", ) + x_axis_ordinate_output: StringProperty(name="X Axis Abscissa Ordinate Output", description="X axis abscissa and ordinate", ) + y_axis_abscissa_output: StringProperty(name="Y Axis Abscissa Ordinate Output", description="Y axis abscissa and ordinate", ) + y_axis_ordinate_output: StringProperty(name="Y Axis Abscissa Ordinate Output", description="Y axis abscissa and ordinate", ) has_blender_offset: BoolProperty(name="Has Blender Offset") blender_eastings: StringProperty(name="Blender Eastings", default="0") blender_northings: StringProperty(name="Blender Northings", default="0") diff --git a/src/blenderbim/blenderbim/bim/module/georeference/ui.py b/src/blenderbim/blenderbim/bim/module/georeference/ui.py index 15c28e3467..d7c3131a0a 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/ui.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/ui.py @@ -167,3 +167,21 @@ class BIM_PT_gis_utilities(Panel): 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 = self.layout.row(align=True) + row.label(text="Orientation Calculator", icon="TRACKING_REFINE_FORWARDS") + row = self.layout.row(align=True) + row.prop(props, "angle_degree_input_x", text="Angle (°) rel to Easting") + row.operator("bim.convert_angle_to_coord", text="", icon="FILE_REFRESH").type = "rel_x" + row = self.layout.row(align=True) + row.prop(props, "x_axis_abscissa_output", text="XAxis Abscissa") + row = self.layout.row(align=True) + row.prop(props, "x_axis_ordinate_output", text="XAxis Ordinate") + + row = self.layout.row(align=True) + row.prop(props, "angle_degree_input_y", text="Angle (°) rel to to +Y") + row.operator("bim.convert_angle_to_coord", text="", icon="FILE_REFRESH").type = "rel_y" + 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 diff --git a/src/blenderbim/blenderbim/core/georeference.py b/src/blenderbim/blenderbim/core/georeference.py index 8cde5d9b20..f3faded3b2 100644 --- a/src/blenderbim/blenderbim/core/georeference.py +++ b/src/blenderbim/blenderbim/core/georeference.py @@ -80,3 +80,7 @@ def convert_global_to_local(georeference): coordinates = georeference.enh2xyz(georeference.get_coordinates("input"), georeference.get_map_conversion()) georeference.set_coordinates("output", coordinates) georeference.set_cursor_location(coordinates) + +def convert_angle_to_coord(georeference, type): + vector_coordinates = georeference.angle2coords(georeference.get_angle(type), type) + georeference.set_vector_coordinates(vector_coordinates,type) \ No newline at end of file diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 44ba4d4d8a..25fa289a5d 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -370,13 +370,15 @@ class Geometry: @interface 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 get_angle(cls, type): pass def get_coordinates(cls, io): pass def get_cursor_location(cls): pass - def get_map_conversion(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 @@ -388,6 +390,7 @@ class Georeference: def set_cursor_location(cls, coordinates): pass 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 diff --git a/src/blenderbim/blenderbim/tool/georeference.py b/src/blenderbim/blenderbim/tool/georeference.py index 3be71c6fee..2dc6001b61 100644 --- a/src/blenderbim/blenderbim/tool/georeference.py +++ b/src/blenderbim/blenderbim/tool/georeference.py @@ -272,3 +272,27 @@ class Georeference(blenderbim.core.tool.Georeference): float(props.map_conversion.get("XAxisOrdinate").string_value), ) bpy.context.scene.sun_pos_properties.north_offset = -radians(angle) + + @classmethod + def angle2coords(cls, angle, type): + if type == "rel_x": + return ifcopenshell.util.geolocation.angle2xaxis(angle) + elif type == "rel_y": + return ifcopenshell.util.geolocation.angle2yaxis(angle) + + @classmethod + def get_angle(cls, type): + if type == "rel_x": + return bpy.context.scene.BIMGeoreferenceProperties.angle_degree_input_x + elif type == "rel_y": + return bpy.context.scene.BIMGeoreferenceProperties.angle_degree_input_y + + @classmethod + def set_vector_coordinates(cls, vector_coordinates, type): + x, y = vector_coordinates + if type == "rel_x": + bpy.context.scene.BIMGeoreferenceProperties.x_axis_abscissa_output = str(x) + bpy.context.scene.BIMGeoreferenceProperties.x_axis_ordinate_output = str(y) + elif type == "rel_y": + bpy.context.scene.BIMGeoreferenceProperties.y_axis_abscissa_output = str(x) + bpy.context.scene.BIMGeoreferenceProperties.y_axis_ordinate_output = str(y) diff --git a/src/ifcopenshell-python/ifcopenshell/util/geolocation.py b/src/ifcopenshell-python/ifcopenshell/util/geolocation.py index 2f739ad306..cc8da275e1 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/geolocation.py +++ b/src/ifcopenshell-python/ifcopenshell/util/geolocation.py @@ -187,3 +187,18 @@ def get_true_north(ifc_file): except: return 0 return 0 + + +# Used for converting an angle in degrees to return the X and Y vectors of the X Axis in IFC grid north geolocation: +def angle2xaxis(angle): + angle_rad = math.radians(angle) + x = math.cos(angle_rad) + y = - math.sin(angle_rad) + return x, y + +# Used for converting True North angle as seen in CAD (relative to +Y) +def angle2yaxis(angle): + angle_rad = math.radians(angle) + x = - math.sin(angle_rad) + y = math.cos(angle_rad) + return x, y