diff --git a/src/bonsai/bonsai/bim/module/drawing/helper.py b/src/bonsai/bonsai/bim/module/drawing/helper.py index a9333fb6a4..f782cdbb7a 100644 --- a/src/bonsai/bonsai/bim/module/drawing/helper.py +++ b/src/bonsai/bonsai/bim/module/drawing/helper.py @@ -131,18 +131,30 @@ def format_distance( suppress_zero_inches=False, in_unit_length=False, ): - s_code = "\u00b2" # Superscript two THIS IS LEGACY (but being kept for when Area Measurements are re-implimented) - - # Get Scene Unit Settings - scaleFactor = bpy.context.scene.unit_settings.scale_length + # Get Blender Scene Unit Settings + unit_scale = bpy.context.scene.unit_settings.scale_length unit_system = bpy.context.scene.unit_settings.system unit_length = bpy.context.scene.unit_settings.length_unit - if area_unit := ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "AREAUNIT"): - area_unit_symbol = " " + ifcopenshell.util.unit.get_unit_symbol(area_unit) - else: - area_unit_symbol = "" + area_unit_symbol = " m2" if unit_system == "METRIC" else " ft2" + # Get IFC Unit Settings + if tool.Ifc.get(): + if length_unit := ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "LENGTHUNIT"): + unit_system = "METRIC" if length_unit.Name == "METRE" else "IMPERIAL" + unit_length = length_unit.Name + if hasattr(length_unit, "Prefix") and length_unit.Prefix: + unit_length = length_unit.Prefix + length_unit.Name + string_conversion = { + "foot": "FEET", + "inch": "INCHES", + "METRE": "METERS", + "CENTIMETRE": "CENTIMETERS", + "MILLIMETRE": "MILLIMETERS", + } + unit_length = string_conversion[unit_length] + if area_unit := ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "AREAUNIT"): + area_unit_symbol = " " + ifcopenshell.util.unit.get_unit_symbol(area_unit) - value *= scaleFactor + value *= unit_scale # Imperial Formatting if unit_system == "IMPERIAL": diff --git a/src/bonsai/bonsai/bim/module/model/decorator.py b/src/bonsai/bonsai/bim/module/model/decorator.py index 264865cd3a..ee6df0f75e 100644 --- a/src/bonsai/bonsai/bim/module/model/decorator.py +++ b/src/bonsai/bonsai/bim/module/model/decorator.py @@ -637,7 +637,10 @@ class PolylineDecorator: mouse_point = [Vector((snap_prop.x, snap_prop.y, snap_prop.z))] # Plane Method or Default Container - default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z + if tool.Ifc.get(): + default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z + else: + default_container_elevation = 0.0 projection_point = [] if not self.tool_state: pass diff --git a/src/bonsai/bonsai/bim/module/model/polyline.py b/src/bonsai/bonsai/bim/module/model/polyline.py index 502a467a88..a202faccce 100644 --- a/src/bonsai/bonsai/bim/module/model/polyline.py +++ b/src/bonsai/bonsai/bim/module/model/polyline.py @@ -558,7 +558,6 @@ class PolylineOperator: return context.space_data.type == "VIEW_3D" def __init__(self): - self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) self.mousemove_count = 0 self.action_count = 0 self.visible_objs = [] @@ -950,6 +949,7 @@ class PolylineOperator: elif getattr(props, offset_type) in {"INTERIOR", "TOP"}: self.offset = -thickness * direction + self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) props.offset = self.offset / self.unit_scale tool.Blender.update_viewport() diff --git a/src/bonsai/bonsai/tool/blender.py b/src/bonsai/bonsai/tool/blender.py index 8ac081eb93..235b1a23d0 100644 --- a/src/bonsai/bonsai/tool/blender.py +++ b/src/bonsai/bonsai/tool/blender.py @@ -1629,3 +1629,16 @@ class Blender(bonsai.core.tool.Blender): old_history_size = tool.Ifc.get().history_size tool.Ifc.get().set_history_size(0) tool.Ifc.get().set_history_size(old_history_size) + + @classmethod + def get_unit_scale(cls): + unit_length = bpy.context.scene.unit_settings.length_unit + unit_scale = 1.0 + if unit_length == "CENTIMETERS": + unit_scale = 0.01 + if unit_length == "MILLIMETERS": + unit_scale = 0.001 + if unit_length == "FEET": + unit_scale = 0.3048 + + return unit_scale diff --git a/src/bonsai/bonsai/tool/polyline.py b/src/bonsai/bonsai/tool/polyline.py index 471826b22e..86193ad29e 100644 --- a/src/bonsai/bonsai/tool/polyline.py +++ b/src/bonsai/bonsai/tool/polyline.py @@ -113,16 +113,24 @@ class Polyline(bonsai.core.tool.Polyline): cls, context: bpy.types.Context, input_ui: PolylineUI, tool_state: ToolState, should_round: bool = False ) -> None: - try: - polyline_data = context.scene.BIMPolylineProperties.insertion_polyline[0] + polyline_data = context.scene.BIMPolylineProperties.insertion_polyline + if len(polyline_data) > 0: + polyline_data = polyline_data[0] polyline_points = polyline_data.polyline_points - default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z - last_point_data = polyline_points[len(polyline_points) - 1] - except: + if len(polyline_points) > 0: + last_point_data = polyline_points[len(polyline_points) - 1] + else: + last_point_data = None + else: polyline_points = [] - default_container_elevation = 0 last_point_data = None + if tool.Ifc.get(): + default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z + else: + default_container_elevation = 0 + + mouse_point = context.scene.BIMPolylineProperties.snap_mouse_point[0] if last_point_data: @@ -253,16 +261,23 @@ class Polyline(bonsai.core.tool.Polyline): @classmethod def calculate_x_y_and_z(cls, context: bpy.types.Context, input_ui: PolylineUI, tool_state: ToolState) -> None: - try: + polyline_data = context.scene.BIMPolylineProperties.insertion_polyline + if len(polyline_data) > 0: polyline_data = context.scene.BIMPolylineProperties.insertion_polyline[0] polyline_points = polyline_data.polyline_points - default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z - last_point_data = polyline_points[len(polyline_points) - 1] - last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z)) - except: + if len(polyline_points) > 0: + last_point_data = polyline_points[len(polyline_points) - 1] + last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z)) + else: + last_point = Vector((0, 0, 0)) + else: polyline_points = [] - default_container_elevation = 0 last_point = Vector((0, 0, 0)) + + if tool.Ifc.get(): + default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z + else: + default_container_elevation = 0 snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0] snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z)) @@ -440,7 +455,10 @@ class Polyline(bonsai.core.tool.Polyline): return dimension * unit_scale try: - unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + if tool.Ifc.get(): + unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + else: + unit_scale = tool.Blender.get_unit_scale() if bpy.context.scene.unit_settings.system == "IMPERIAL": parser = Lark(grammar_imperial) else: @@ -461,14 +479,15 @@ class Polyline(bonsai.core.tool.Polyline): @classmethod def format_input_ui_units(cls, value: float, is_area: bool = False) -> str: - unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + if tool.Ifc.get(): + unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + else: + unit_scale = tool.Blender.get_unit_scale() if bpy.context.scene.unit_settings.system == "IMPERIAL": dprops = tool.Drawing.get_document_props() precision = dprops.imperial_precision if is_area: - props = tool.Blender.get_bim_props() - area_unit = props.area_unit - unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get(), unit_type=area_unit) + unit_scale = 1 else: precision = None diff --git a/src/bonsai/bonsai/tool/raycast.py b/src/bonsai/bonsai/tool/raycast.py index b0c4abd4ec..9dbcc57ad9 100644 --- a/src/bonsai/bonsai/tool/raycast.py +++ b/src/bonsai/bonsai/tool/raycast.py @@ -155,7 +155,8 @@ class Raycast(bonsai.core.tool.Raycast): loc = Vector((0, 0, 0)) # For empty object we just get the object location and return - if obj.type == "EMPTY": + + if obj and obj.type == "EMPTY": v = obj.location intersection = tool.Cad.point_on_edge(v, (ray_target, loc)) intersection = tool.Cad.point_on_edge(v, (ray_target, loc)) @@ -168,7 +169,6 @@ class Raycast(bonsai.core.tool.Raycast): "distance": distance, } points.append(snap_point) - print("empty", snap_point) return points if not custom_bmesh: @@ -292,7 +292,10 @@ class Raycast(bonsai.core.tool.Raycast): mouse_pos = event.mouse_region_x, event.mouse_region_y ray_origin, ray_target, ray_direction = cls.get_viewport_ray_data(context, event) - default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z + if tool.Ifc.get(): + default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z + else: + default_container_elevation = 0.0 intersection = Vector((0, 0, default_container_elevation)) try: loc = view3d_utils.region_2d_to_location_3d(region, rv3d, mouse_pos, ray_direction) diff --git a/src/bonsai/bonsai/tool/snap.py b/src/bonsai/bonsai/tool/snap.py index 2d2b2ae08b..c20ff83b3a 100644 --- a/src/bonsai/bonsai/tool/snap.py +++ b/src/bonsai/bonsai/tool/snap.py @@ -53,7 +53,10 @@ class Snap(bonsai.core.tool.Snap): distances = [3, 5, 15, 30] unit_system = tool.Drawing.get_unit_system() - unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + if tool.Ifc.get(): + unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) + else: + unit_scale = tool.Blender.get_unit_scale() if unit_system == "IMPERIAL": factor = unit_scale fractions = [24, 12, 6, 2] @@ -452,7 +455,10 @@ class Snap(bonsai.core.tool.Snap): detected_snaps.append(snap_point) # Axis and Plane - elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z + if tool.Ifc.get(): + elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z + else: + elevation = 0.0 plane_origin, plane_normal = select_plane_method() tool_state.plane_origin = plane_origin # This will be used along with plane method