See #6164. Allow measure tool to work without IFC Project.

This commit is contained in:
Bruno Perdigão
2025-03-11 11:56:08 -03:00
parent 6bd8636c92
commit 7af672712f
7 changed files with 89 additions and 33 deletions
+21 -9
View File
@@ -131,18 +131,30 @@ def format_distance(
suppress_zero_inches=False, suppress_zero_inches=False,
in_unit_length=False, in_unit_length=False,
): ):
s_code = "\u00b2" # Superscript two THIS IS LEGACY (but being kept for when Area Measurements are re-implimented) # Get Blender Scene Unit Settings
unit_scale = bpy.context.scene.unit_settings.scale_length
# Get Scene Unit Settings
scaleFactor = bpy.context.scene.unit_settings.scale_length
unit_system = bpy.context.scene.unit_settings.system unit_system = bpy.context.scene.unit_settings.system
unit_length = bpy.context.scene.unit_settings.length_unit 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 = " m2" if unit_system == "METRIC" else " ft2"
area_unit_symbol = " " + ifcopenshell.util.unit.get_unit_symbol(area_unit) # Get IFC Unit Settings
else: if tool.Ifc.get():
area_unit_symbol = "" 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 # Imperial Formatting
if unit_system == "IMPERIAL": if unit_system == "IMPERIAL":
@@ -637,7 +637,10 @@ class PolylineDecorator:
mouse_point = [Vector((snap_prop.x, snap_prop.y, snap_prop.z))] mouse_point = [Vector((snap_prop.x, snap_prop.y, snap_prop.z))]
# Plane Method or Default Container # 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 = [] projection_point = []
if not self.tool_state: if not self.tool_state:
pass pass
@@ -558,7 +558,6 @@ class PolylineOperator:
return context.space_data.type == "VIEW_3D" return context.space_data.type == "VIEW_3D"
def __init__(self): def __init__(self):
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
self.mousemove_count = 0 self.mousemove_count = 0
self.action_count = 0 self.action_count = 0
self.visible_objs = [] self.visible_objs = []
@@ -950,6 +949,7 @@ class PolylineOperator:
elif getattr(props, offset_type) in {"INTERIOR", "TOP"}: elif getattr(props, offset_type) in {"INTERIOR", "TOP"}:
self.offset = -thickness * direction self.offset = -thickness * direction
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
props.offset = self.offset / self.unit_scale props.offset = self.offset / self.unit_scale
tool.Blender.update_viewport() tool.Blender.update_viewport()
+13
View File
@@ -1629,3 +1629,16 @@ class Blender(bonsai.core.tool.Blender):
old_history_size = tool.Ifc.get().history_size old_history_size = tool.Ifc.get().history_size
tool.Ifc.get().set_history_size(0) tool.Ifc.get().set_history_size(0)
tool.Ifc.get().set_history_size(old_history_size) 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
+36 -17
View File
@@ -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 cls, context: bpy.types.Context, input_ui: PolylineUI, tool_state: ToolState, should_round: bool = False
) -> None: ) -> None:
try: polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline[0] if len(polyline_data) > 0:
polyline_data = polyline_data[0]
polyline_points = polyline_data.polyline_points polyline_points = polyline_data.polyline_points
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z if len(polyline_points) > 0:
last_point_data = polyline_points[len(polyline_points) - 1] last_point_data = polyline_points[len(polyline_points) - 1]
except: else:
last_point_data = None
else:
polyline_points = [] polyline_points = []
default_container_elevation = 0
last_point_data = None 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] mouse_point = context.scene.BIMPolylineProperties.snap_mouse_point[0]
if last_point_data: if last_point_data:
@@ -253,17 +261,24 @@ class Polyline(bonsai.core.tool.Polyline):
@classmethod @classmethod
def calculate_x_y_and_z(cls, context: bpy.types.Context, input_ui: PolylineUI, tool_state: ToolState) -> None: 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_data = context.scene.BIMPolylineProperties.insertion_polyline[0]
polyline_points = polyline_data.polyline_points polyline_points = polyline_data.polyline_points
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z if len(polyline_points) > 0:
last_point_data = polyline_points[len(polyline_points) - 1] last_point_data = polyline_points[len(polyline_points) - 1]
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z)) last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
except: else:
last_point = Vector((0, 0, 0))
else:
polyline_points = [] polyline_points = []
default_container_elevation = 0
last_point = Vector((0, 0, 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_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z)) 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 return dimension * unit_scale
try: 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": if bpy.context.scene.unit_settings.system == "IMPERIAL":
parser = Lark(grammar_imperial) parser = Lark(grammar_imperial)
else: else:
@@ -461,14 +479,15 @@ class Polyline(bonsai.core.tool.Polyline):
@classmethod @classmethod
def format_input_ui_units(cls, value: float, is_area: bool = False) -> str: 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": if bpy.context.scene.unit_settings.system == "IMPERIAL":
dprops = tool.Drawing.get_document_props() dprops = tool.Drawing.get_document_props()
precision = dprops.imperial_precision precision = dprops.imperial_precision
if is_area: if is_area:
props = tool.Blender.get_bim_props() unit_scale = 1
area_unit = props.area_unit
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get(), unit_type=area_unit)
else: else:
precision = None precision = None
+6 -3
View File
@@ -155,7 +155,8 @@ class Raycast(bonsai.core.tool.Raycast):
loc = Vector((0, 0, 0)) loc = Vector((0, 0, 0))
# For empty object we just get the object location and return # For empty object we just get the object location and return
if obj.type == "EMPTY":
if obj and obj.type == "EMPTY":
v = obj.location v = obj.location
intersection = tool.Cad.point_on_edge(v, (ray_target, loc)) intersection = tool.Cad.point_on_edge(v, (ray_target, loc))
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, "distance": distance,
} }
points.append(snap_point) points.append(snap_point)
print("empty", snap_point)
return points return points
if not custom_bmesh: if not custom_bmesh:
@@ -292,7 +292,10 @@ class Raycast(bonsai.core.tool.Raycast):
mouse_pos = event.mouse_region_x, event.mouse_region_y mouse_pos = event.mouse_region_x, event.mouse_region_y
ray_origin, ray_target, ray_direction = cls.get_viewport_ray_data(context, event) 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)) intersection = Vector((0, 0, default_container_elevation))
try: try:
loc = view3d_utils.region_2d_to_location_3d(region, rv3d, mouse_pos, ray_direction) loc = view3d_utils.region_2d_to_location_3d(region, rv3d, mouse_pos, ray_direction)
+8 -2
View File
@@ -53,7 +53,10 @@ class Snap(bonsai.core.tool.Snap):
distances = [3, 5, 15, 30] distances = [3, 5, 15, 30]
unit_system = tool.Drawing.get_unit_system() 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": if unit_system == "IMPERIAL":
factor = unit_scale factor = unit_scale
fractions = [24, 12, 6, 2] fractions = [24, 12, 6, 2]
@@ -452,7 +455,10 @@ class Snap(bonsai.core.tool.Snap):
detected_snaps.append(snap_point) detected_snaps.append(snap_point)
# Axis and Plane # 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() plane_origin, plane_normal = select_plane_method()
tool_state.plane_origin = plane_origin # This will be used along with plane method tool_state.plane_origin = plane_origin # This will be used along with plane method