mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 02:07:36 +00:00
Ifc Text rotation in viewport preview
This commit is contained in:
@@ -30,7 +30,7 @@ from math import acos, pi, atan, degrees
|
|||||||
from functools import reduce
|
from functools import reduce
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from bpy.types import SpaceView3D
|
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 bpy_extras.view3d_utils import location_3d_to_region_2d
|
||||||
from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertFormat
|
from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertFormat
|
||||||
from gpu_extras.batch import batch_for_shader
|
from gpu_extras.batch import batch_for_shader
|
||||||
@@ -384,7 +384,7 @@ class BaseDecorator:
|
|||||||
context,
|
context,
|
||||||
text,
|
text,
|
||||||
pos,
|
pos,
|
||||||
dir,
|
text_dir,
|
||||||
gap=4,
|
gap=4,
|
||||||
center=True,
|
center=True,
|
||||||
vcenter=False,
|
vcenter=False,
|
||||||
@@ -409,9 +409,10 @@ class BaseDecorator:
|
|||||||
|
|
||||||
color = context.scene.DocProperties.decorations_colour
|
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)
|
cos = math.cos(ang)
|
||||||
sin = math.sin(ang)
|
sin = math.sin(ang)
|
||||||
|
rotated_y_axis = Vector([-sin, cos])
|
||||||
|
|
||||||
# Horrific prototype code
|
# Horrific prototype code
|
||||||
factor = self.camera_zoom_to_factor(context.space_data.region_3d.view_camera_zoom)
|
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
|
# font_size = 16 <-- this is a good default
|
||||||
# TODO: need to synchronize it better with svg
|
# TODO: need to synchronize it better with svg
|
||||||
font_size_px = int(0.004118616 * mm_to_px) * font_size_mm / 2.5
|
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)
|
blf.size(font_id, font_size_px, dpi)
|
||||||
|
|
||||||
@@ -2074,11 +2075,48 @@ class TextDecorator(BaseDecorator):
|
|||||||
def decorate(self, context, obj):
|
def decorate(self, context, obj):
|
||||||
self.draw_labels(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):
|
def draw_labels(self, context, obj):
|
||||||
region = context.region
|
region = context.region
|
||||||
region3d = context.region_data
|
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)
|
pos = location_3d_to_region_2d(region, region3d, obj.matrix_world.translation)
|
||||||
props = obj.BIMTextProperties
|
props = obj.BIMTextProperties
|
||||||
text_data = props.get_text_edited_data() if props.is_editing else DecoratorData.get_ifc_text_data(obj)
|
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,
|
context,
|
||||||
line,
|
line,
|
||||||
pos,
|
pos,
|
||||||
dir,
|
text_dir,
|
||||||
gap=0,
|
gap=0,
|
||||||
center=False,
|
center=False,
|
||||||
vcenter=False,
|
vcenter=False,
|
||||||
|
|||||||
Reference in New Issue
Block a user