Fixed text annotation rotation in viewport #3017

Fixed text annotation rotation in viewport for the views rotated by multipel axis.
Changed text direction calculation to be the same in both viewport and svg.
This commit is contained in:
Andrej730
2023-04-18 14:55:45 +05:00
parent 77445f9b22
commit 5d650d29e0
5 changed files with 22 additions and 21 deletions
@@ -113,9 +113,7 @@ class Annotator:
camera = tool.Ifc.get_object(drawing)
co1, _, _, _ = Annotator.get_placeholder_coords(camera)
matrix_world = camera.matrix_world.copy()
matrix_world[0][3] = co1.x
matrix_world[1][3] = co1.y
matrix_world[2][3] = co1.z
matrix_world.translation = co1
collection = camera.users_collection[0]
if object_type == "TEXT":
@@ -422,11 +422,14 @@ class BaseDecorator:
region = context.region
region3d = context.region_data
camera = context.scene.camera
text_dir = Vector((1, 0))
text_dir_world = region3d.perspective_matrix.inverted().to_quaternion() @ text_dir.to_3d()
text_dir_world_rotated = obj.matrix_world.to_quaternion() @ text_dir_world
text_dir = (region3d.perspective_matrix.to_quaternion() @ text_dir_world_rotated).to_2d().normalized()
def get_basis_vector(matrix, i=0):
"""returns basis vector for i in world space, unaffected by object scale"""
return matrix.inverted()[i].to_3d().normalized()
text_dir_world_x_axis = get_basis_vector(obj.matrix_world)
text_dir = (camera.matrix_world.inverted().to_quaternion() @ text_dir_world_x_axis).to_2d().normalized()
pos = location_3d_to_region_2d(region, region3d, text_world_position)
props = obj.BIMTextProperties
@@ -553,7 +553,9 @@ class CreateDrawing(bpy.types.Operator):
value = ifcopenshell.util.selector.get_element_value(element, key)
if value:
classes.append(
tool.Drawing.canonicalise_class_name(key) + "-" + tool.Drawing.canonicalise_class_name(str(value))
tool.Drawing.canonicalise_class_name(key)
+ "-"
+ tool.Drawing.canonicalise_class_name(str(value))
)
el.set("class", (el.get("class", "") + " " + " ".join(classes)).strip())
@@ -626,7 +628,6 @@ class CreateDrawing(bpy.types.Operator):
self.svg_writer.metadata = self.metadata
self.svg_writer.create_blank_svg(svg_path).draw_annotations(annotations, precision, decimal_places).save()
return svg_path
def get_scale(self):
@@ -707,8 +708,7 @@ class AddAnnotation(bpy.types.Operator, Operator):
if not drawing:
self.report({"WARNING"}, "Not a BIM camera")
return
# TODO: support adding multiple annotations if there are multiple selected objects
# that can be used as annotations references
r = core.add_annotation(tool.Ifc, tool.Collector, tool.Drawing, drawing=drawing, object_type=self.object_type)
if isinstance(r, str):
self.report({"WARNING"}, r)
@@ -1024,7 +1024,6 @@ class ActivateModel(bpy.types.Operator):
return {"FINISHED"}
class ActivateDrawing(bpy.types.Operator):
"""
Activates the selected drawing view
@@ -665,13 +665,13 @@ class SvgWriter:
text_position = Vector(((x_offset + text_position.x), (y_offset - text_position.y)))
text_position_svg = text_position * self.svg_scale
local_x_axis = text_obj.matrix_world.to_quaternion() @ Vector((1, 0, 0))
projected_x_axis = self.project_point_onto_camera(position + local_x_axis)
angle = math.degrees(
(Vector((x_offset + projected_x_axis.x, y_offset - projected_x_axis.y)) - text_position).angle_signed(
Vector((1, 0))
)
)
def get_basis_vector(matrix, i=0):
"""returns basis vector for i in world space, unaffected by object scale"""
return matrix.inverted()[i].to_3d().normalized()
text_dir_world_x_axis = get_basis_vector(text_obj.matrix_world)
text_dir = (self.camera.matrix_world.inverted().to_quaternion() @ text_dir_world_x_axis).to_2d().normalized()
angle = math.degrees(-text_dir.angle_signed(Vector((1, 0))))
transform = "rotate({}, {}, {})".format(angle, *text_position_svg)
classes = self.get_attribute_classes(text_obj)
+3 -2
View File
@@ -310,9 +310,10 @@ def update_drawing_name(ifc, drawing_tool, drawing=None, name=None):
def add_annotation(ifc, collector, drawing_tool, drawing=None, object_type=None):
context = drawing_tool.get_annotation_context(drawing_tool.get_drawing_target_view(drawing))
context = drawing_tool.get_annotation_context(target_view := drawing_tool.get_drawing_target_view(drawing))
if not context:
return "No annotation context for drawing"
return f"No annotation context Annotation/{target_view} for drawing"
drawing_tool.show_decorations()
obj = drawing_tool.create_annotation_object(drawing, object_type)
element = ifc.get_entity(obj)