mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 22:50:21 +00:00
drawing arrows
This commit is contained in:
@@ -1,10 +1,15 @@
|
|||||||
"""Viewport decorations"""
|
"""Viewport decorations"""
|
||||||
import math
|
import math
|
||||||
|
from functools import reduce
|
||||||
from bpy.types import SpaceView3D
|
from bpy.types import SpaceView3D
|
||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
import bpy
|
import bpy
|
||||||
import blf
|
import blf
|
||||||
from bpy_extras.view3d_utils import location_3d_to_region_2d
|
from bpy_extras.view3d_utils import location_3d_to_region_2d
|
||||||
|
import gpu
|
||||||
|
import bgl
|
||||||
|
from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertFormat
|
||||||
|
from gpu_extras.batch import batch_for_shader
|
||||||
|
|
||||||
|
|
||||||
class ViewDecorator(object):
|
class ViewDecorator(object):
|
||||||
@@ -31,11 +36,81 @@ class DimensionDecorator(ViewDecorator):
|
|||||||
- puts metric text next to each segment
|
- puts metric text next to each segment
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
VERT_GLSL = """
|
||||||
|
uniform mat4 viewMatrix;
|
||||||
|
in vec3 pos;
|
||||||
|
out vec4 gl_Position;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = viewMatrix * vec4(pos, 1.0);
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
GEOM_GLSL = """
|
||||||
|
layout(lines) in;
|
||||||
|
layout(line_strip, max_vertices=8) out;
|
||||||
|
|
||||||
|
uniform float angle;
|
||||||
|
uniform float length;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 p0 = gl_in[0].gl_Position, p1 = gl_in[1].gl_Position;
|
||||||
|
float c = cos(angle), s = sin(angle);
|
||||||
|
mat4 rot_a = mat4( c, -s, 0, 0,
|
||||||
|
+s, c, 0, 0,
|
||||||
|
0, 0, 1, 0,
|
||||||
|
0, 0, 0, 1);
|
||||||
|
mat4 rot_b = mat4( c, +s, 0, 0,
|
||||||
|
-s, c, 0, 0,
|
||||||
|
0, 0, 1, 0,
|
||||||
|
0, 0, 0, 1);
|
||||||
|
|
||||||
|
vec4 dir = normalize(p1 - p0);
|
||||||
|
|
||||||
|
vec4 arr_a = rot_a * dir * length;
|
||||||
|
vec4 arr_b = rot_b * dir * length;
|
||||||
|
|
||||||
|
gl_Position = p0;
|
||||||
|
EmitVertex();
|
||||||
|
gl_Position = p1;
|
||||||
|
EmitVertex();
|
||||||
|
EndPrimitive();
|
||||||
|
|
||||||
|
gl_Position = p0 + arr_a;
|
||||||
|
EmitVertex();
|
||||||
|
gl_Position = p0;
|
||||||
|
EmitVertex();
|
||||||
|
gl_Position = p0 + arr_b;
|
||||||
|
EmitVertex();
|
||||||
|
EndPrimitive();
|
||||||
|
|
||||||
|
gl_Position = p1 - arr_a;
|
||||||
|
EmitVertex();
|
||||||
|
gl_Position = p1;
|
||||||
|
EmitVertex();
|
||||||
|
gl_Position = p1 - arr_b;
|
||||||
|
EmitVertex();
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
FRAG_GLSL = """
|
||||||
|
uniform vec3 color;
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
fragColor = vec4(color, 1.0);
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, props, context):
|
def __init__(self, props, context):
|
||||||
self.context = context
|
self.context = context
|
||||||
self.props = props
|
self.props = props
|
||||||
self.font_id = 0 # TODO: take font from styles
|
self.font_id = 0 # TODO: take font from styles
|
||||||
self.dpi = context.preferences.system.dpi
|
self.dpi = context.preferences.system.dpi
|
||||||
|
self.shader = self.create_shader()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_shader(cls):
|
||||||
|
return GPUShader(vertexcode=cls.VERT_GLSL, fragcode=cls.FRAG_GLSL, geocode=cls.GEOM_GLSL)
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
# get active drawing, if any
|
# get active drawing, if any
|
||||||
@@ -48,9 +123,10 @@ class DimensionDecorator(ViewDecorator):
|
|||||||
return
|
return
|
||||||
curve = collection.all_objects['IfcAnnotation/Dimension']
|
curve = collection.all_objects['IfcAnnotation/Dimension']
|
||||||
|
|
||||||
for segm in self.iter_segments(curve):
|
segments = list(self.iter_segments(curve))
|
||||||
|
self.draw_arrows(segments)
|
||||||
|
for segm in segments:
|
||||||
self.draw_label(segm)
|
self.draw_label(segm)
|
||||||
self.draw_arrow(segm)
|
|
||||||
|
|
||||||
def iter_segments(self, curve):
|
def iter_segments(self, curve):
|
||||||
"""Yields each segment converted to world coords
|
"""Yields each segment converted to world coords
|
||||||
@@ -105,5 +181,18 @@ class DimensionDecorator(ViewDecorator):
|
|||||||
blf.draw(self.font_id, text)
|
blf.draw(self.font_id, text)
|
||||||
blf.disable(self.font_id, blf.ROTATION)
|
blf.disable(self.font_id, blf.ROTATION)
|
||||||
|
|
||||||
def draw_arrow(self, segm):
|
def draw_arrows(self, segments):
|
||||||
pass
|
def coords(segm):
|
||||||
|
return [(segm[0].x, segm[0].y, segm[0].z),
|
||||||
|
(segm[1].x, segm[1].y, segm[1].z)]
|
||||||
|
points = list(reduce(lambda points, segm: points + coords(segm),
|
||||||
|
segments, []))
|
||||||
|
batch = batch_for_shader(self.shader, 'LINES', {'pos': points})
|
||||||
|
self.shader.bind()
|
||||||
|
matrix = self.context.region_data.perspective_matrix
|
||||||
|
self.shader.uniform_float("viewMatrix", matrix)
|
||||||
|
# TODO: get everything from styles
|
||||||
|
self.shader.uniform_float('color', (1.0, 1.0, 1.0))
|
||||||
|
self.shader.uniform_float('angle', math.pi / 12)
|
||||||
|
self.shader.uniform_float('length', 0.05)
|
||||||
|
batch.draw(self.shader)
|
||||||
|
|||||||
Reference in New Issue
Block a user