mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
grid decorations.
This commit is contained in:
@@ -21,9 +21,8 @@ class BaseDecorator():
|
||||
|
||||
DEF_GLSL = """
|
||||
#define PI 3.141592653589793
|
||||
#define MAX_POINTS 64
|
||||
#define CIRCLE_SEGS 24
|
||||
// max points = SEGS (circle) + 2 (stem) + 3 (arrow)
|
||||
#define MAX_POINTS 29
|
||||
#define ARROW1_ANGLE PI / 12.0
|
||||
#define ARROW2_ANGLE PI / 3.0
|
||||
#define ARROW1_SIZE 16.0
|
||||
@@ -40,6 +39,10 @@ class BaseDecorator():
|
||||
#define BREAK_LENGTH 32.0
|
||||
#define BREAK_WIDTH 16.0
|
||||
|
||||
#define DASH_SIZE 48.0
|
||||
#define CIRCLE_SIZE 16.0
|
||||
#define DASH_PATTERN 0x03C0FFFFU
|
||||
|
||||
#define UNPROJ(v, p) (unwindowMatrix * vec4(v, 0, 0) * p.w);
|
||||
"""
|
||||
|
||||
@@ -261,7 +264,7 @@ class BaseDecorator():
|
||||
self.shader.uniform_float("winsize", (region.width, region.height))
|
||||
batch.draw(self.shader)
|
||||
|
||||
def draw_label(self, text, pos, dir, gap=4, center=True):
|
||||
def draw_label(self, text, pos, dir, gap=4, center=True, vcenter=False):
|
||||
"""Draw text label
|
||||
|
||||
Args:
|
||||
@@ -275,11 +278,18 @@ class BaseDecorator():
|
||||
|
||||
blf.size(self.font_id, self.font_size, self.dpi)
|
||||
|
||||
w, h = 0, 0
|
||||
if center or vcenter:
|
||||
w, h = blf.dimensions(self.font_id, text)
|
||||
|
||||
if center:
|
||||
# centering
|
||||
w, _ = blf.dimensions(self.font_id, text)
|
||||
# horizontal centering
|
||||
pos -= Vector((cos, sin)) * w * 0.5
|
||||
|
||||
if vcenter:
|
||||
# vertical centering
|
||||
pos -= Vector((-sin, cos)) * h * 0.5
|
||||
|
||||
if gap:
|
||||
# side-shifting
|
||||
pos += Vector((-sin, cos)) * gap
|
||||
@@ -827,3 +837,102 @@ class BreakDecorator(BaseDecorator):
|
||||
mesh = bmesh.from_edit_mesh(obj.data)
|
||||
vertices = [obj.matrix_world @ v.co for v in mesh.edges[0].verts]
|
||||
return vertices
|
||||
|
||||
|
||||
class GridDecorator(BaseDecorator):
|
||||
basename = "IfcGridAxis/"
|
||||
installed = None
|
||||
|
||||
GEOM_GLSL = """
|
||||
uniform vec2 winsize;
|
||||
|
||||
layout(lines) in;
|
||||
layout(line_strip, max_vertices=MAX_POINTS) out;
|
||||
|
||||
out float dist; // distance from starging point along segment
|
||||
|
||||
void main() {
|
||||
vec4 p0 = gl_in[0].gl_Position, p1 = gl_in[1].gl_Position;
|
||||
|
||||
mat4 windowMatrix = mat4(winsize.x/2, 0, 0, 0, 0, winsize.y/2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
|
||||
mat4 unwindowMatrix = inverse(windowMatrix);
|
||||
vec2 p0w = (windowMatrix * (p0 / p0.w)).xy, p1w = (windowMatrix * (p1 / p1.w)).xy;
|
||||
vec2 edge = p1w - p0w;
|
||||
vec2 dir = normalize(edge);
|
||||
vec2 gap = dir * CIRCLE_SIZE;
|
||||
|
||||
vec2 head[CIRCLE_SEGS];
|
||||
circle_head(p0w, p1w, CIRCLE_SIZE, head);
|
||||
|
||||
dist = 0;
|
||||
|
||||
for(int i=0; i<CIRCLE_SEGS; i++) {
|
||||
gl_Position = p0 + UNPROJ(head[i], p0);
|
||||
EmitVertex();
|
||||
}
|
||||
gl_Position = p0 + UNPROJ(head[0], p0);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
|
||||
for(int i=0; i<CIRCLE_SEGS; i++) {
|
||||
gl_Position = p1 + UNPROJ(head[i], p1);
|
||||
EmitVertex();
|
||||
}
|
||||
gl_Position = p1 + UNPROJ(head[0], p1);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
|
||||
dist = 0;
|
||||
gl_Position = p0 + UNPROJ(gap, p0);
|
||||
EmitVertex();
|
||||
dist = length(edge);
|
||||
gl_Position = p1 - UNPROJ(gap, p1);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
"""
|
||||
|
||||
FRAG_GLSL = """
|
||||
in vec2 gl_FragCoord;
|
||||
in float dist;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
uint bit = uint(fract(dist / DASH_SIZE) * 32);
|
||||
if ((DASH_PATTERN & (1U<<bit)) == 0U) discard;
|
||||
fragColor = COLOR;
|
||||
}
|
||||
"""
|
||||
|
||||
def get_mesh_geom(self, obj):
|
||||
# first vertices only
|
||||
vertices = [obj.matrix_world @ obj.data.vertices[i].co for i in (0, 1)]
|
||||
return vertices
|
||||
|
||||
def get_editmesh_geom(self, obj):
|
||||
# first vertices only
|
||||
mesh = bmesh.from_edit_mesh(obj.data)
|
||||
vertices = [obj.matrix_world @ v.co for v in mesh.edges[0].verts]
|
||||
return vertices
|
||||
|
||||
def decorate(self, obj):
|
||||
if obj.data.is_editmode:
|
||||
verts = self.get_editmesh_geom(obj)
|
||||
else:
|
||||
verts = self.get_mesh_geom(obj)
|
||||
self.draw_lines(obj, verts, [(0, 1)])
|
||||
self.draw_labels(obj, verts)
|
||||
|
||||
def draw_labels(self, obj, vertices):
|
||||
region = self.context.region
|
||||
region3d = self.context.region_data
|
||||
v0 = Vector(vertices[0])
|
||||
v1 = Vector(vertices[1])
|
||||
p0 = location_3d_to_region_2d(region, region3d, v0)
|
||||
p1 = location_3d_to_region_2d(region, region3d, v1)
|
||||
dir = p1 - p0
|
||||
if dir.length < 1:
|
||||
return
|
||||
text = obj.BIMObjectProperties.attributes['AxisTag'].string_value
|
||||
self.draw_label(text, p0, dir, vcenter=True, gap=0)
|
||||
self.draw_label(text, p1, dir, vcenter=True, gap=0)
|
||||
|
||||
@@ -368,6 +368,7 @@ def toggleDecorations(self, context):
|
||||
decoration.SectionDecorator.install(self, context)
|
||||
decoration.MiscDecorator.install(self, context)
|
||||
decoration.BreakDecorator.install(self, context)
|
||||
decoration.GridDecorator.install(self, context)
|
||||
else:
|
||||
decoration.DimensionDecorator.uninstall()
|
||||
decoration.EqualityDecorator.uninstall()
|
||||
@@ -378,6 +379,7 @@ def toggleDecorations(self, context):
|
||||
decoration.SectionDecorator.uninstall()
|
||||
decoration.MiscDecorator.uninstall()
|
||||
decoration.BreakDecorator.uninstall()
|
||||
decoration.GridDecorator.uninstall()
|
||||
|
||||
|
||||
def getScenarios(self, context):
|
||||
|
||||
Reference in New Issue
Block a user