#1153 Viewport decoration now supports miscellaneous linework and fills

This commit is contained in:
Dion Moult
2022-04-24 11:12:24 +10:00
parent 31ddb0f2c5
commit 7c460bcf29
@@ -170,12 +170,33 @@ class BaseDecorator:
returns: iterable of blender objects returns: iterable of blender objects
""" """
results = [] results = []
decoration_presets = (
"DIMENSION",
"EQUAL_DIMENSION",
"TEXT_LEADER",
"STAIR_ARROW",
"HIDDEN_LINE",
"PLAN_LEVEL",
"SECTION_LEVEL",
"BREAKLINE",
"GRID",
"ELEVATION",
"SECTION",
"TEXT",
)
for obj in collection.all_objects: for obj in collection.all_objects:
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
if not element: if not element:
continue continue
if element.is_a("IfcAnnotation") and element.ObjectType == self.objecttype: if element.is_a("IfcAnnotation"):
results.append(obj) if element.ObjectType == self.objecttype:
results.append(obj)
elif (
self.objecttype == "MISC"
and element.ObjectType not in decoration_presets
and isinstance(obj.data, bpy.types.Mesh)
):
results.append(obj)
return results return results
def get_path_geom(self, obj, topo=True): def get_path_geom(self, obj, topo=True):
@@ -247,7 +268,7 @@ class BaseDecorator:
"""perform actual drawing stuff""" """perform actual drawing stuff"""
raise NotImplementedError() raise NotImplementedError()
def draw_lines(self, context, obj, vertices, indices, topology=None): def draw_lines(self, context, obj, vertices, indices, topology=None, is_scale_dependant=True):
region = context.region region = context.region
region3d = context.region_data region3d = context.region_data
color = context.scene.DocProperties.decorations_colour color = context.scene.DocProperties.decorations_colour
@@ -277,14 +298,15 @@ class BaseDecorator:
self.shader.uniform_float("winsize", (region.width, region.height)) self.shader.uniform_float("winsize", (region.width, region.height))
self.shader.uniform_float("color", color) self.shader.uniform_float("color", color)
# Horrific prototype code if is_scale_dependant:
factor = self.camera_zoom_to_factor(context.space_data.region_3d.view_camera_zoom) # Horrific prototype code
camera_width_px = factor * context.region.width factor = self.camera_zoom_to_factor(context.space_data.region_3d.view_camera_zoom)
mm_to_px = camera_width_px / self.camera_width_mm camera_width_px = factor * context.region.width
# 0.00025 is a magic constant number I visually discovered to get the right number. mm_to_px = camera_width_px / self.camera_width_mm
# It probably should be dynamically calculated using system.dpi or something. # 0.00025 is a magic constant number I visually discovered to get the right number.
viewport_drawing_scale = 0.00025 * mm_to_px # It probably should be dynamically calculated using system.dpi or something.
self.shader.uniform_float("viewportDrawingScale", viewport_drawing_scale) viewport_drawing_scale = 0.00025 * mm_to_px
self.shader.uniform_float("viewportDrawingScale", viewport_drawing_scale)
batch.draw(self.shader) batch.draw(self.shader)
@@ -671,6 +693,7 @@ class HiddenDecorator(BaseDecorator):
GEOM_GLSL = """ GEOM_GLSL = """
uniform vec2 winsize; uniform vec2 winsize;
uniform float viewportDrawingScale;
layout(lines) in; layout(lines) in;
layout(line_strip, max_vertices=MAX_POINTS) out; layout(line_strip, max_vertices=MAX_POINTS) out;
@@ -725,10 +748,61 @@ class HiddenDecorator(BaseDecorator):
self.draw_lines(context, obj, verts, idxs) self.draw_lines(context, obj, verts, idxs)
class MiscDecorator(HiddenDecorator): class MiscDecorator(BaseDecorator):
objecttype = "MISC" objecttype = "MISC"
FRAG_GLSL = BaseDecorator.FRAG_GLSL GEOM_GLSL = """
uniform vec2 winsize;
uniform float viewportDrawingScale;
layout(lines) in;
layout(line_strip, max_vertices=MAX_POINTS) out;
out float dist; // distance from starging point along segment
void main() {
vec4 clip2win = matCLIP2WIN();
vec4 win2clip = matWIN2CLIP();
vec4 p0 = gl_in[0].gl_Position, p1 = gl_in[1].gl_Position;
vec4 p0w = CLIP2WIN(p0), p1w = CLIP2WIN(p1);
vec4 edge = p1w - p0w, dir = normalize(edge);
vec4 gap = dir * 1;
vec4 p;
// NB: something should be used to affect position, otherwise compiler eliminates winsize
dist = 0;
p = p0w + gap;
gl_Position = WIN2CLIP(p);
EmitVertex();
dist = length(edge);
p = p1w - gap;
gl_Position = WIN2CLIP(p);
EmitVertex();
EndPrimitive();
}
"""
FRAG_GLSL = """
uniform vec4 color;
in vec2 gl_FragCoord;
in float dist;
out vec4 fragColor;
void main() {
fragColor = color;
}
"""
def decorate(self, context, obj):
if obj.data.is_editmode:
verts, idxs = self.get_editmesh_geom(obj)
else:
verts, idxs = self.get_mesh_geom(obj)
self.draw_lines(context, obj, verts, idxs, is_scale_dependant=False)
class LevelDecorator(BaseDecorator): class LevelDecorator(BaseDecorator):
@@ -990,21 +1064,10 @@ class BreakDecorator(BaseDecorator):
def decorate(self, context, obj): def decorate(self, context, obj):
if obj.data.is_editmode: if obj.data.is_editmode:
verts = self.get_editmesh_geom(obj) verts, idxs = self.get_editmesh_geom(obj)
else: else:
verts = self.get_mesh_geom(obj) verts, idxs = self.get_mesh_geom(obj)
self.draw_lines(context, obj, verts, [(0, 1)]) self.draw_lines(context, obj, verts, idxs)
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
class GridDecorator(BaseDecorator): class GridDecorator(BaseDecorator):
@@ -1363,7 +1426,6 @@ class SectionDecorator(LevelDecorator):
self.draw_lines(context, obj, verts, idxs) self.draw_lines(context, obj, verts, idxs)
class TextDecorator(BaseDecorator): class TextDecorator(BaseDecorator):
"""Decorator for text objects """Decorator for text objects
- draws the text next to the origin - draws the text next to the origin