Ifc Text rotation in viewport preview

This commit is contained in:
Andrej730
2023-03-22 14:05:03 +05:00
parent f8dc421f03
commit e173ea7f80
@@ -30,7 +30,7 @@ from math import acos, pi, atan, degrees
from functools import reduce
from itertools import chain
from bpy.types import SpaceView3D
from mathutils import Vector, Matrix
from mathutils import Vector, Matrix, geometry
from bpy_extras.view3d_utils import location_3d_to_region_2d
from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertFormat
from gpu_extras.batch import batch_for_shader
@@ -384,7 +384,7 @@ class BaseDecorator:
context,
text,
pos,
dir,
text_dir,
gap=4,
center=True,
vcenter=False,
@@ -409,9 +409,10 @@ class BaseDecorator:
color = context.scene.DocProperties.decorations_colour
ang = -Vector((1, 0)).angle_signed(dir)
ang = -Vector((1, 0)).angle_signed(text_dir)
cos = math.cos(ang)
sin = math.sin(ang)
rotated_y_axis = Vector([-sin, cos])
# Horrific prototype code
factor = self.camera_zoom_to_factor(context.space_data.region_3d.view_camera_zoom)
@@ -423,7 +424,7 @@ class BaseDecorator:
# font_size = 16 <-- this is a good default
# TODO: need to synchronize it better with svg
font_size_px = int(0.004118616 * mm_to_px) * font_size_mm / 2.5
pos = pos - Vector((0, line_no * font_size_px))
pos = pos - line_no * font_size_px * rotated_y_axis
blf.size(font_id, font_size_px, dpi)
@@ -2074,11 +2075,48 @@ class TextDecorator(BaseDecorator):
def decorate(self, context, obj):
self.draw_labels(context, obj)
def project_point_onto_camera(self, point, camera_projection):
# TODO is this needlessly complex?
camera = bpy.context.scene.camera
return camera.matrix_world.inverted() @ geometry.intersect_line_plane(
point.xyz,
point.xyz - Vector(camera_projection),
camera.location,
Vector(camera_projection),
)
def get_camera_dimensions(self):
render = bpy.context.scene.render
camera = bpy.context.scene.camera
if render.resolution_x > render.resolution_y: # is_landscape
width = camera.data.ortho_scale
height = width / render.resolution_x * render.resolution_y
else:
height = camera.data.ortho_scale
width = height / render.resolution_y * render.resolution_x
return width, height
def draw_labels(self, context, obj):
region = context.region
region3d = context.region_data
# TODO: support text rotation
dir = Vector((1, 0))
# TODO: optimize for realtime viewport render
# currently it's just copied from svgwriter
# to make rotation work in viewport
camera = bpy.context.scene.camera
camera_dimensions = Vector(self.get_camera_dimensions())
x_offset, y_offset = camera_dimensions / 2
position = obj.matrix_world.translation
camera_projection = tuple(
camera.matrix_world.to_quaternion() @ Vector((0, 0, -1))
)
text_position = self.project_point_onto_camera(position, camera_projection)
text_position = Vector(((x_offset + text_position.x), (y_offset - text_position.y)))
local_x_axis = obj.matrix_world.to_quaternion() @ Vector((1, 0, 0))
projected_x_axis = self.project_point_onto_camera(position + local_x_axis, camera_projection)
text_dir = (Vector((x_offset + projected_x_axis.x, y_offset + projected_x_axis.y)) - text_position)
pos = location_3d_to_region_2d(region, region3d, obj.matrix_world.translation)
props = obj.BIMTextProperties
text_data = props.get_text_edited_data() if props.is_editing else DecoratorData.get_ifc_text_data(obj)
@@ -2104,7 +2142,7 @@ class TextDecorator(BaseDecorator):
context,
line,
pos,
dir,
text_dir,
gap=0,
center=False,
vcenter=False,