mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 17:57:02 +00:00
add adjunt_overlapping_labels
This commit is contained in:
committed by
Bruno Perdigão
parent
a3801a0ce9
commit
4da0b04162
@@ -521,6 +521,10 @@ class PolylineDecorator:
|
|||||||
color = self.addon_prefs.decorations_colour
|
color = self.addon_prefs.decorations_colour
|
||||||
|
|
||||||
blf.color(self.font_id, *color)
|
blf.color(self.font_id, *color)
|
||||||
|
|
||||||
|
screen_coords = {}
|
||||||
|
label_index = 0
|
||||||
|
|
||||||
for i in range(len(self.polyline_points)):
|
for i in range(len(self.polyline_points)):
|
||||||
if i < 1 and self.measure_type == "POLY_AREA":
|
if i < 1 and self.measure_type == "POLY_AREA":
|
||||||
continue
|
continue
|
||||||
@@ -529,39 +533,39 @@ class PolylineDecorator:
|
|||||||
dim_text_pos = (Vector(self.polyline_points[i].position) + Vector(self.polyline_points[i - 1].position)) / 2
|
dim_text_pos = (Vector(self.polyline_points[i].position) + Vector(self.polyline_points[i - 1].position)) / 2
|
||||||
dim_text_coords = view3d_utils.location_3d_to_region_2d(region, rv3d, dim_text_pos)
|
dim_text_coords = view3d_utils.location_3d_to_region_2d(region, rv3d, dim_text_pos)
|
||||||
|
|
||||||
formatted_value = self.polyline_points[i].dim
|
if dim_text_coords:
|
||||||
|
formatted_value = self.polyline_points[i].dim
|
||||||
|
text = "d: " + formatted_value
|
||||||
|
screen_coords[f"distance_{label_index}"] = (dim_text_coords, text)
|
||||||
|
label_index += 1
|
||||||
|
|
||||||
blf.position(self.font_id, dim_text_coords[0], dim_text_coords[1], 0)
|
if self.measure_type != "SINGLE":
|
||||||
text = "d: " + formatted_value
|
for i in range(len(self.polyline_points)):
|
||||||
text_length = blf.dimensions(self.font_id, text)
|
if i ==1:
|
||||||
self.draw_text_background(context, dim_text_coords, text_length)
|
continue
|
||||||
blf.draw(self.font_id, text)
|
|
||||||
|
|
||||||
if i == 1:
|
angle_text_pos = Vector(self.polyline_points[i - 1].position)
|
||||||
continue
|
angle_text_coords = view3d_utils.location_3d_to_region_2d(region, rv3d, angle_text_pos)
|
||||||
angle_text_pos = Vector(self.polyline_points[i - 1].position)
|
|
||||||
angle_text_coords = view3d_utils.location_3d_to_region_2d(region, rv3d, angle_text_pos)
|
if angle_text_coords:
|
||||||
blf.position(self.font_id, angle_text_coords[0], angle_text_coords[1], 0)
|
text = "a: " + self.polyline_points[i].angle
|
||||||
text = "a: " + self.polyline_points[i].angle
|
screen_coords[f"angle_{label_index}"] = (angle_text_coords, text)
|
||||||
text_length = blf.dimensions(self.font_id, text)
|
label_index += 1
|
||||||
self.draw_text_background(context, angle_text_coords, text_length)
|
|
||||||
blf.draw(self.font_id, text)
|
|
||||||
|
|
||||||
if self.measure_type == "SINGLE":
|
if self.measure_type == "SINGLE":
|
||||||
axis_line, axis_line_center = self.calculate_measurement_x_y_and_z(context)
|
axis_line, axis_line_center = self.calculate_measurement_x_y_and_z(context)
|
||||||
for i, dim_text_pos in enumerate(axis_line_center):
|
if axis_line and axis_line_center:
|
||||||
dim_text_coords = view3d_utils.location_3d_to_region_2d(region, rv3d, dim_text_pos)
|
for i, dim_text_pos in enumerate(axis_line_center):
|
||||||
pos = blf.position(self.font_id, dim_text_coords[0], dim_text_coords[1], 0)
|
dim_text_coords = view3d_utils.location_3d_to_region_2d(region, rv3d, dim_text_pos)
|
||||||
value = round((axis_line[i][1] - axis_line[i][0]).length, 4)
|
if dim_text_coords:
|
||||||
direction = axis_line[i][1] - axis_line[i][0]
|
value = round((axis_line[i][1] - axis_line[i][0]).length, 4)
|
||||||
if (i == 0 and direction.x < 0) or (i == 1 and direction.y < 0) or (i == 2 and direction.z < 0):
|
direction = axis_line[i][1] - axis_line[i][0]
|
||||||
value = -value
|
if (i == 0 and direction.x < 0) or (i == 1 and direction.y < 0) or (i == 2 and direction.z < 0):
|
||||||
prefix = "xyz"[i]
|
value = -value
|
||||||
formatted_value = tool.Polyline.format_input_ui_units(value)
|
prefix = "xyz"[i]
|
||||||
text = f"{prefix}: {formatted_value}"
|
formatted_value = tool.Polyline.format_input_ui_units(value)
|
||||||
text_length = blf.dimensions(self.font_id, text)
|
text = f"{prefix}: {formatted_value}"
|
||||||
self.draw_text_background(context, dim_text_coords, text_length)
|
screen_coords[f"xyz_{i}"] = (dim_text_coords, text)
|
||||||
blf.draw(self.font_id, text)
|
|
||||||
|
|
||||||
# Area and Length text
|
# Area and Length text
|
||||||
polyline_verts = [Vector((p.x, p.y, p.z)) for p in self.polyline_points]
|
polyline_verts = [Vector((p.x, p.y, p.z)) for p in self.polyline_points]
|
||||||
@@ -576,28 +580,93 @@ class PolylineDecorator:
|
|||||||
polyline_verts[:-1]
|
polyline_verts[:-1]
|
||||||
) # Doesn't use the last point if is a closed polyline
|
) # Doesn't use the last point if is a closed polyline
|
||||||
area_text_coords = view3d_utils.location_3d_to_region_2d(region, rv3d, center)
|
area_text_coords = view3d_utils.location_3d_to_region_2d(region, rv3d, center)
|
||||||
value = self.polyline_data.area
|
if area_text_coords:
|
||||||
text = f"area: {value}"
|
value = self.polyline_data.area
|
||||||
text_length = blf.dimensions(self.font_id, text)
|
text = f"area: {value}"
|
||||||
area_text_coords[0] -= text_length[0] / 2 # Center text horizontally
|
screen_coords["area"] = (area_text_coords, text)
|
||||||
blf.position(self.font_id, area_text_coords[0], area_text_coords[1], 0)
|
|
||||||
self.draw_text_background(context, area_text_coords, text_length)
|
|
||||||
blf.draw(self.font_id, text)
|
|
||||||
|
|
||||||
# Length
|
# Length
|
||||||
if self.measure_type in {"POLYLINE", "POLY_AREA"}:
|
if self.measure_type in {"POLYLINE", "POLY_AREA"}:
|
||||||
if len(polyline_verts) < 3:
|
if len(polyline_verts) < 3:
|
||||||
return
|
return
|
||||||
total_length_text_coords = view3d_utils.location_3d_to_region_2d(region, rv3d, polyline_verts[-1])
|
total_length_text_coords = view3d_utils.location_3d_to_region_2d(region, rv3d, polyline_verts[-1])
|
||||||
blf.position(self.font_id, total_length_text_coords[0], total_length_text_coords[1], 0)
|
if total_length_text_coords:
|
||||||
value = self.polyline_data.total_length
|
value = self.polyline_data.total_length
|
||||||
text = f"length: {value}"
|
text = f"length: {value}"
|
||||||
|
screen_coords["length"] = (total_length_text_coords, text)
|
||||||
|
|
||||||
|
self.adjust_overlapping_labels(screen_coords)
|
||||||
|
|
||||||
|
for label_key, (screen_co, text) in screen_coords.items():
|
||||||
|
blf.position(self.font_id, screen_co.x, screen_co.y, 0)
|
||||||
|
blf.color(self.font_id, 1, 1, 1, 1)
|
||||||
text_length = blf.dimensions(self.font_id, text)
|
text_length = blf.dimensions(self.font_id, text)
|
||||||
self.draw_text_background(context, total_length_text_coords, text_length)
|
self.draw_text_background(context, screen_co, text_length)
|
||||||
blf.draw(self.font_id, text)
|
blf.draw(self.font_id, text)
|
||||||
|
|
||||||
blf.disable(self.font_id, blf.SHADOW)
|
blf.disable(self.font_id, blf.SHADOW)
|
||||||
|
|
||||||
|
def adjust_overlapping_labels(self, screen_coords):
|
||||||
|
font_id = self.font_id
|
||||||
|
text_dimensions = {}
|
||||||
|
|
||||||
|
for label_key, (screen_co, text) in screen_coords.items():
|
||||||
|
text_dimensions[label_key] = blf.dimensions(font_id, text)
|
||||||
|
|
||||||
|
min_spacing = 12
|
||||||
|
|
||||||
|
label_keys = list(screen_coords.keys())
|
||||||
|
for pass_num in range(3): # 3 passes to try to optimize complex overlaps
|
||||||
|
for i in range(len(label_keys)):
|
||||||
|
for j in range(i + 1, len(label_keys)):
|
||||||
|
key1, key2 = label_keys[i], label_keys[j]
|
||||||
|
co1, _ = screen_coords[key1]
|
||||||
|
co2, _ = screen_coords[key2]
|
||||||
|
dim1 = text_dimensions[key1]
|
||||||
|
dim2 = text_dimensions[key2]
|
||||||
|
|
||||||
|
bounds1 = {
|
||||||
|
"left": co1.x - min_spacing,
|
||||||
|
"right": co1.x + dim1[0] + min_spacing,
|
||||||
|
"top": co1.y + dim1[1] + min_spacing,
|
||||||
|
"bottom": co1.y - min_spacing,
|
||||||
|
}
|
||||||
|
bounds2 = {
|
||||||
|
"left": co2.x - min_spacing,
|
||||||
|
"right": co2.x + dim2[0] + min_spacing,
|
||||||
|
"top": co2.y + dim2[1] + min_spacing,
|
||||||
|
"bottom": co2.y - min_spacing,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
bounds1["left"] < bounds2["right"]
|
||||||
|
and bounds1["right"] > bounds2["left"]
|
||||||
|
and bounds1["bottom"] < bounds2["top"]
|
||||||
|
and bounds1["top"] > bounds2["bottom"]
|
||||||
|
):
|
||||||
|
x_overlap = min(bounds1["right"], bounds2["right"]) - max(bounds1["left"], bounds2["left"])
|
||||||
|
y_overlap = min(bounds1["top"], bounds2["top"]) - max(bounds1["bottom"], bounds2["bottom"])
|
||||||
|
|
||||||
|
separation_multiplier = 1.25
|
||||||
|
|
||||||
|
# Move labels in the direction requiring less movement
|
||||||
|
if x_overlap < y_overlap:
|
||||||
|
separation_distance = (x_overlap / 2 + min_spacing) * separation_multiplier
|
||||||
|
if co1.x < co2.x:
|
||||||
|
co1.x -= separation_distance
|
||||||
|
co2.x += separation_distance
|
||||||
|
else:
|
||||||
|
co1.x += separation_distance
|
||||||
|
co2.x -= separation_distance
|
||||||
|
else:
|
||||||
|
separation_distance = (y_overlap / 2 + min_spacing) * separation_multiplier
|
||||||
|
if co1.y < co2.y:
|
||||||
|
co1.y -= separation_distance
|
||||||
|
co2.y += separation_distance
|
||||||
|
else:
|
||||||
|
co1.y += separation_distance
|
||||||
|
co2.y -= separation_distance
|
||||||
|
|
||||||
def draw_measurements_poly(self, context):
|
def draw_measurements_poly(self, context):
|
||||||
self.shader_config(context)
|
self.shader_config(context)
|
||||||
polyline_verts: list[Vector] = []
|
polyline_verts: list[Vector] = []
|
||||||
|
|||||||
Reference in New Issue
Block a user