2020-05-03 15:41:05 +10:00
|
|
|
import bpy
|
2020-05-03 19:54:27 +10:00
|
|
|
import os
|
2020-05-03 15:41:05 +10:00
|
|
|
from mathutils import Vector
|
|
|
|
|
|
|
|
|
|
|
2020-11-01 20:08:48 +07:00
|
|
|
class Annotator:
|
2020-05-04 12:20:34 +10:00
|
|
|
@staticmethod
|
|
|
|
|
def get_svg_text_size(size):
|
|
|
|
|
sizes = {
|
2020-11-01 20:08:48 +07:00
|
|
|
"1.8": "2.97",
|
|
|
|
|
"2.5": "4.13",
|
|
|
|
|
"3.5": "5.78",
|
|
|
|
|
"5.0": "8.25",
|
|
|
|
|
"7.0": "11.55",
|
2020-05-04 12:20:34 +10:00
|
|
|
}
|
|
|
|
|
return float(sizes[str(size)])
|
|
|
|
|
|
2020-05-03 15:41:05 +10:00
|
|
|
@staticmethod
|
2021-07-29 23:08:17 +02:00
|
|
|
def add_text(context, related_element=None):
|
2021-05-16 18:26:48 +10:00
|
|
|
curve = bpy.data.curves.new(type="FONT", name="Text")
|
2020-11-01 20:08:48 +07:00
|
|
|
curve.body = "TEXT"
|
2021-05-16 18:26:48 +10:00
|
|
|
obj = bpy.data.objects.new("Text", curve)
|
2021-07-29 23:08:17 +02:00
|
|
|
obj.matrix_world = context.scene.camera.matrix_world
|
2020-05-07 09:36:38 +10:00
|
|
|
if related_element is None:
|
2021-07-29 23:08:17 +02:00
|
|
|
location, _, _, _ = Annotator.get_placeholder_coords(context)
|
2020-05-07 09:36:38 +10:00
|
|
|
else:
|
|
|
|
|
obj.data.BIMTextProperties.related_element = related_element
|
|
|
|
|
location = related_element.location
|
|
|
|
|
obj.location = location
|
2020-05-03 15:41:05 +10:00
|
|
|
obj.hide_render = True
|
2020-11-01 20:08:48 +07:00
|
|
|
font = bpy.data.fonts.get("OpenGost TypeB TT")
|
2020-05-03 19:54:27 +10:00
|
|
|
if not font:
|
2020-11-01 20:08:48 +07:00
|
|
|
font = bpy.data.fonts.load(
|
2021-07-29 23:08:17 +02:00
|
|
|
os.path.join(context.scene.BIMProperties.data_dir, "fonts", "OpenGost Type B TT.ttf")
|
2020-11-01 20:08:48 +07:00
|
|
|
)
|
|
|
|
|
font.name = "OpenGost Type B TT"
|
2020-05-03 19:54:27 +10:00
|
|
|
obj.data.font = font
|
2020-11-01 20:08:48 +07:00
|
|
|
obj.data.BIMTextProperties.font_size = "2.5"
|
2021-07-29 23:08:17 +02:00
|
|
|
collection = context.scene.camera.users_collection[0]
|
2020-05-03 19:54:27 +10:00
|
|
|
collection.objects.link(obj)
|
|
|
|
|
Annotator.resize_text(obj)
|
2020-05-03 15:41:05 +10:00
|
|
|
return obj
|
|
|
|
|
|
2020-05-03 19:54:27 +10:00
|
|
|
@staticmethod
|
|
|
|
|
def resize_text(text_obj):
|
|
|
|
|
camera = None
|
|
|
|
|
for obj in text_obj.users_collection[0].objects:
|
|
|
|
|
if isinstance(obj.data, bpy.types.Camera):
|
|
|
|
|
camera = obj
|
|
|
|
|
break
|
|
|
|
|
if not camera:
|
|
|
|
|
return
|
|
|
|
|
# This is a magic number for OpenGost
|
|
|
|
|
font_size = 1.6 / 1000
|
|
|
|
|
font_size *= float(text_obj.data.BIMTextProperties.font_size)
|
2020-08-30 21:40:21 +10:00
|
|
|
|
2020-11-01 20:08:48 +07:00
|
|
|
if camera.data.BIMCameraProperties.diagram_scale == "CUSTOM":
|
|
|
|
|
human_scale, fraction = camera.data.BIMCameraProperties.custom_diagram_scale.split("|")
|
2020-08-30 21:40:21 +10:00
|
|
|
else:
|
2020-11-01 20:08:48 +07:00
|
|
|
human_scale, fraction = camera.data.BIMCameraProperties.diagram_scale.split("|")
|
|
|
|
|
numerator, denominator = fraction.split("/")
|
2020-08-30 21:40:21 +10:00
|
|
|
font_size /= float(numerator) / float(denominator)
|
|
|
|
|
|
2020-05-03 19:54:27 +10:00
|
|
|
text_obj.data.size = font_size
|
|
|
|
|
|
2020-05-03 15:41:05 +10:00
|
|
|
@staticmethod
|
2021-07-29 23:08:17 +02:00
|
|
|
def add_line_to_annotation(obj, context, co1=None, co2=None):
|
2020-08-29 18:56:23 +10:00
|
|
|
if co1 is None:
|
2021-07-29 23:08:17 +02:00
|
|
|
co1, co2, _, _ = Annotator.get_placeholder_coords(context)
|
2020-08-29 18:56:23 +10:00
|
|
|
co1 = obj.matrix_world.inverted() @ co1
|
|
|
|
|
co2 = obj.matrix_world.inverted() @ co2
|
2020-05-03 15:41:05 +10:00
|
|
|
if isinstance(obj.data, bpy.types.Mesh):
|
|
|
|
|
obj.data.vertices.add(2)
|
|
|
|
|
obj.data.vertices[-2].co = co1
|
|
|
|
|
obj.data.vertices[-1].co = co2
|
2020-06-06 23:42:24 +02:00
|
|
|
obj.data.edges.add(1)
|
2020-05-03 15:41:05 +10:00
|
|
|
obj.data.edges[-1].vertices = (obj.data.vertices[-2].index, obj.data.vertices[-1].index)
|
|
|
|
|
if isinstance(obj.data, bpy.types.Curve):
|
2020-11-01 20:08:48 +07:00
|
|
|
polyline = obj.data.splines.new("POLY")
|
2020-05-03 15:41:05 +10:00
|
|
|
polyline.points.add(1)
|
|
|
|
|
polyline.points[-2].co = list(co1) + [1]
|
|
|
|
|
polyline.points[-1].co = list(co2) + [1]
|
|
|
|
|
return obj
|
|
|
|
|
|
2020-12-26 21:59:57 +07:00
|
|
|
@staticmethod
|
2021-07-29 23:08:17 +02:00
|
|
|
def add_plane_to_annotation(obj, context):
|
|
|
|
|
co1, co2, co3, co4 = Annotator.get_placeholder_coords(context)
|
2020-12-26 21:59:57 +07:00
|
|
|
co1 = obj.matrix_world.inverted() @ co1 # bot left
|
|
|
|
|
co2 = obj.matrix_world.inverted() @ co2 # top left
|
|
|
|
|
co3 = obj.matrix_world.inverted() @ co3 # bot right
|
|
|
|
|
co4 = obj.matrix_world.inverted() @ co4 # top right
|
|
|
|
|
|
|
|
|
|
obj.data.vertices.add(4)
|
|
|
|
|
v1 = obj.data.vertices[-4]
|
|
|
|
|
v2 = obj.data.vertices[-3]
|
|
|
|
|
v3 = obj.data.vertices[-2]
|
|
|
|
|
v4 = obj.data.vertices[-1]
|
|
|
|
|
v1.co = co4
|
|
|
|
|
v2.co = co2
|
|
|
|
|
v3.co = co1
|
|
|
|
|
v4.co = co3
|
|
|
|
|
|
|
|
|
|
obj.data.edges.add(4)
|
|
|
|
|
e1 = obj.data.edges[-4]
|
|
|
|
|
e2 = obj.data.edges[-3]
|
|
|
|
|
e3 = obj.data.edges[-2]
|
|
|
|
|
e4 = obj.data.edges[-1]
|
|
|
|
|
e1.vertices = (v1.index, v2.index)
|
|
|
|
|
e2.vertices = (v2.index, v3.index)
|
|
|
|
|
e3.vertices = (v3.index, v4.index)
|
|
|
|
|
e4.vertices = (v4.index, v1.index)
|
|
|
|
|
|
|
|
|
|
obj.data.loops.add(4)
|
|
|
|
|
l1 = obj.data.loops[-4]
|
|
|
|
|
l2 = obj.data.loops[-3]
|
|
|
|
|
l3 = obj.data.loops[-2]
|
|
|
|
|
l4 = obj.data.loops[-1]
|
|
|
|
|
l1.vertex_index = v1.index
|
|
|
|
|
l1.edge_index = e1.index
|
|
|
|
|
l2.vertex_index = v2.index
|
|
|
|
|
l2.edge_index = e2.index
|
|
|
|
|
l3.vertex_index = v3.index
|
|
|
|
|
l3.edge_index = e3.index
|
|
|
|
|
l4.vertex_index = v4.index
|
|
|
|
|
l4.edge_index = e4.index
|
|
|
|
|
|
|
|
|
|
obj.data.polygons.add(1)
|
|
|
|
|
p1 = obj.data.polygons[-1]
|
|
|
|
|
p1.vertices = (v1.index, v2.index, v3.index, v4.index)
|
|
|
|
|
p1.loop_start = l1.index
|
|
|
|
|
p1.loop_total = 4
|
|
|
|
|
return obj
|
|
|
|
|
|
2020-05-03 15:41:05 +10:00
|
|
|
@staticmethod
|
2021-07-29 23:08:17 +02:00
|
|
|
def get_annotation_obj(name, data_type, context):
|
|
|
|
|
collection = context.scene.camera.users_collection[0]
|
2020-05-03 15:41:05 +10:00
|
|
|
for obj in collection.objects:
|
|
|
|
|
if name in obj.name:
|
|
|
|
|
return obj
|
2020-11-01 20:08:48 +07:00
|
|
|
if data_type == "mesh":
|
2021-05-16 18:26:48 +10:00
|
|
|
data = bpy.data.meshes.new(name)
|
2020-11-01 20:08:48 +07:00
|
|
|
elif data_type == "curve":
|
2021-05-16 18:26:48 +10:00
|
|
|
data = bpy.data.curves.new(name, type="CURVE")
|
2020-11-01 20:08:48 +07:00
|
|
|
data.dimensions = "3D"
|
2020-05-03 15:41:05 +10:00
|
|
|
data.resolution_u = 2
|
2021-05-16 18:26:48 +10:00
|
|
|
obj = bpy.data.objects.new(name, data)
|
2020-05-03 15:41:05 +10:00
|
|
|
collection.objects.link(obj)
|
|
|
|
|
return obj
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
2021-07-29 23:08:17 +02:00
|
|
|
def get_placeholder_coords(context):
|
|
|
|
|
camera = context.scene.camera
|
2020-05-03 15:41:05 +10:00
|
|
|
z_offset = camera.matrix_world.to_quaternion() @ Vector((0, 0, -1))
|
2021-07-29 23:08:17 +02:00
|
|
|
if context.scene.render.resolution_x > context.scene.render.resolution_y:
|
2020-11-01 20:08:48 +07:00
|
|
|
y = (
|
|
|
|
|
camera.data.ortho_scale
|
2021-07-29 23:08:17 +02:00
|
|
|
* (context.scene.render.resolution_y / context.scene.render.resolution_x)
|
2020-11-01 20:08:48 +07:00
|
|
|
/ 4
|
|
|
|
|
)
|
2020-05-03 15:41:05 +10:00
|
|
|
else:
|
|
|
|
|
y = camera.data.ortho_scale / 4
|
|
|
|
|
y_offset = camera.matrix_world.to_quaternion() @ Vector((0, y, 0))
|
2020-12-26 21:59:57 +07:00
|
|
|
x_offset = camera.matrix_world.to_quaternion() @ Vector((y/2, 0, 0))
|
|
|
|
|
return (camera.location + z_offset,
|
|
|
|
|
camera.location + z_offset + y_offset,
|
|
|
|
|
camera.location + z_offset + x_offset,
|
2021-05-16 18:26:48 +10:00
|
|
|
camera.location + z_offset + x_offset + y_offset)
|