Skip to content
This repository was archived by the owner on Nov 24, 2024. It is now read-only.

Commit f37283f

Browse files
qwiglydeeMoult
authored andcommitted
drawing arrows
1 parent cc5f34a commit f37283f

1 file changed

Lines changed: 93 additions & 4 deletions

File tree

src/ifcblenderexport/blenderbim/bim/decoration.py

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
"""Viewport decorations"""
22
import math
3+
from functools import reduce
34
from bpy.types import SpaceView3D
45
from mathutils import Vector
56
import bpy
67
import blf
78
from bpy_extras.view3d_utils import location_3d_to_region_2d
9+
import gpu
10+
import bgl
11+
from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertFormat
12+
from gpu_extras.batch import batch_for_shader
813

914

1015
class ViewDecorator(object):
@@ -31,11 +36,81 @@ class DimensionDecorator(ViewDecorator):
3136
- puts metric text next to each segment
3237
"""
3338

39+
VERT_GLSL = """
40+
uniform mat4 viewMatrix;
41+
in vec3 pos;
42+
out vec4 gl_Position;
43+
44+
void main() {
45+
gl_Position = viewMatrix * vec4(pos, 1.0);
46+
}
47+
"""
48+
GEOM_GLSL = """
49+
layout(lines) in;
50+
layout(line_strip, max_vertices=8) out;
51+
52+
uniform float angle;
53+
uniform float length;
54+
55+
void main() {
56+
vec4 p0 = gl_in[0].gl_Position, p1 = gl_in[1].gl_Position;
57+
float c = cos(angle), s = sin(angle);
58+
mat4 rot_a = mat4( c, -s, 0, 0,
59+
+s, c, 0, 0,
60+
0, 0, 1, 0,
61+
0, 0, 0, 1);
62+
mat4 rot_b = mat4( c, +s, 0, 0,
63+
-s, c, 0, 0,
64+
0, 0, 1, 0,
65+
0, 0, 0, 1);
66+
67+
vec4 dir = normalize(p1 - p0);
68+
69+
vec4 arr_a = rot_a * dir * length;
70+
vec4 arr_b = rot_b * dir * length;
71+
72+
gl_Position = p0;
73+
EmitVertex();
74+
gl_Position = p1;
75+
EmitVertex();
76+
EndPrimitive();
77+
78+
gl_Position = p0 + arr_a;
79+
EmitVertex();
80+
gl_Position = p0;
81+
EmitVertex();
82+
gl_Position = p0 + arr_b;
83+
EmitVertex();
84+
EndPrimitive();
85+
86+
gl_Position = p1 - arr_a;
87+
EmitVertex();
88+
gl_Position = p1;
89+
EmitVertex();
90+
gl_Position = p1 - arr_b;
91+
EmitVertex();
92+
EndPrimitive();
93+
}
94+
"""
95+
FRAG_GLSL = """
96+
uniform vec3 color;
97+
out vec4 fragColor;
98+
99+
void main() {
100+
fragColor = vec4(color, 1.0);
101+
}
102+
"""
103+
34104
def __init__(self, props, context):
35105
self.context = context
36106
self.props = props
37107
self.font_id = 0 # TODO: take font from styles
38108
self.dpi = context.preferences.system.dpi
109+
self.shader = self.create_shader()
110+
111+
@classmethod
112+
def create_shader(cls):
113+
return GPUShader(vertexcode=cls.VERT_GLSL, fragcode=cls.FRAG_GLSL, geocode=cls.GEOM_GLSL)
39114

40115
def __call__(self):
41116
# get active drawing, if any
@@ -48,9 +123,10 @@ def __call__(self):
48123
return
49124
curve = collection.all_objects['IfcAnnotation/Dimension']
50125

51-
for segm in self.iter_segments(curve):
126+
segments = list(self.iter_segments(curve))
127+
self.draw_arrows(segments)
128+
for segm in segments:
52129
self.draw_label(segm)
53-
self.draw_arrow(segm)
54130

55131
def iter_segments(self, curve):
56132
"""Yields each segment converted to world coords
@@ -105,5 +181,18 @@ def draw_label(self, segm):
105181
blf.draw(self.font_id, text)
106182
blf.disable(self.font_id, blf.ROTATION)
107183

108-
def draw_arrow(self, segm):
109-
pass
184+
def draw_arrows(self, segments):
185+
def coords(segm):
186+
return [(segm[0].x, segm[0].y, segm[0].z),
187+
(segm[1].x, segm[1].y, segm[1].z)]
188+
points = list(reduce(lambda points, segm: points + coords(segm),
189+
segments, []))
190+
batch = batch_for_shader(self.shader, 'LINES', {'pos': points})
191+
self.shader.bind()
192+
matrix = self.context.region_data.perspective_matrix
193+
self.shader.uniform_float("viewMatrix", matrix)
194+
# TODO: get everything from styles
195+
self.shader.uniform_float('color', (1.0, 1.0, 1.0))
196+
self.shader.uniform_float('angle', math.pi / 12)
197+
self.shader.uniform_float('length', 0.05)
198+
batch.draw(self.shader)

0 commit comments

Comments
 (0)