More slow progress in getting annotations round-tripping. See #1153.

This commit is contained in:
Dion Moult
2021-11-17 18:24:56 +11:00
parent 18719c16df
commit 5c224150ec
5 changed files with 76 additions and 65 deletions
+5 -3
View File
@@ -1321,10 +1321,11 @@ class IfcImporter:
return element.ObjectType in [
"DIMENSION",
"EQUAL_DIMENSION",
"LEVEL",
"MISC",
"PLAN_LEVEL",
"SECTION_LEVEL",
"STAIR_ARROW",
"TEXT_LEADER",
"MISC",
]
def is_drawing_annotation(self, element):
@@ -1335,8 +1336,9 @@ class IfcImporter:
"EQUAL_DIMENSION",
"GRID",
"HIDDEN_LINE",
"LEVEL",
"MISC",
"PLAN_LEVEL",
"SECTION_LEVEL",
"STAIR_ARROW",
"TEXT",
"TEXT_LEADER",
@@ -340,6 +340,9 @@ class BaseDecorator:
blf.rotation(font_id, ang)
blf.color(font_id, *color)
#blf.enable(font_id, blf.SHADOW)
#blf.shadow(font_id, 5, 0, 0, 0, 1)
#blf.shadow_offset(font_id, 1, -1)
blf.draw(font_id, text)
blf.disable(font_id, blf.ROTATION)
@@ -577,7 +580,7 @@ class StairDecorator(BaseDecorator):
DEF_GLSL = (
BaseDecorator.DEF_GLSL
+ """
#define CIRCLE_SIZE 8.0
#define CIRCLE_SIZE 6.0
#define ARROW_ANGLE PI / 3.0
#define ARROW_SIZE 24.0
"""
@@ -607,7 +610,7 @@ class StairDecorator(BaseDecorator):
// start edge circle for first segment
if (t0 == 1u) {
vec4 head[CIRCLE_SEGS];
circle_head(CIRCLE_SIZE, head);
circle_head(viewportDrawingScale * CIRCLE_SIZE, head);
for(int i=0; i<CIRCLE_SEGS; i++) {
p = p0w + head[i];
@@ -619,13 +622,13 @@ class StairDecorator(BaseDecorator):
EmitVertex();
EndPrimitive();
gap0 = dir * CIRCLE_SIZE;
gap0 = dir * viewportDrawingScale * CIRCLE_SIZE;
}
// end edge arrow for last segment
if (t1 == 2u) {
vec4 head[3];
arrow_head(dir, ARROW_SIZE, ARROW_ANGLE, head);
arrow_head(dir, viewportDrawingScale * ARROW_SIZE, ARROW_ANGLE, head);
p = p1w - head[1];
gl_Position = WIN2CLIP(p);
@@ -668,7 +671,6 @@ class HiddenDecorator(BaseDecorator):
GEOM_GLSL = """
uniform vec2 winsize;
uniform float viewportDrawingScale;
layout(lines) in;
layout(line_strip, max_vertices=MAX_POINTS) out;
@@ -702,13 +704,14 @@ class HiddenDecorator(BaseDecorator):
"""
FRAG_GLSL = """
uniform float viewportDrawingScale;
uniform vec4 color;
in vec2 gl_FragCoord;
in float dist;
out vec4 fragColor;
void main() {
uint bit = uint(fract(dist / DASH_SIZE) * 32);
uint bit = uint(fract(dist / (viewportDrawingScale * DASH_SIZE)) * 32);
if ((DASH_PATTERN & (1U<<bit)) == 0U) discard;
fragColor = color;
}
@@ -785,7 +788,7 @@ class PlanLevelDecorator(LevelDecorator):
// end edge cross+circle for last segment
if (t1 == 2u) {
vec4 head_o[CIRCLE_SEGS];
circle_head(CIRCLE_SIZE, head_o);
circle_head(viewportDrawingScale * CIRCLE_SIZE, head_o);
for(int i=0; i<CIRCLE_SEGS; i++) {
p = p1w + head_o[i];
@@ -798,7 +801,7 @@ class PlanLevelDecorator(LevelDecorator):
EndPrimitive();
vec4 head_x[3];
cross_head(dir, CROSS_SIZE, head_x);
cross_head(dir, viewportDrawingScale * CROSS_SIZE, head_x);
p = p1w + head_x[1];
gl_Position = WIN2CLIP(p);
@@ -857,8 +860,8 @@ class SectionLevelDecorator(LevelDecorator):
out float dist; // distance from starging point along segment
void callout_head(in vec4 dir, out vec4 head[4]) {
vec2 gap = dir.xy * CALLOUT_GAP;
vec2 tail = dir.xy * -CALLOUT_SIZE;
vec2 gap = dir.xy * viewportDrawingScale * CALLOUT_GAP;
vec2 tail = dir.xy * viewportDrawingScale * -CALLOUT_SIZE;
vec2 side = cross(vec3(dir.xy, 0), vec3(0, 0, 1)).xy * CALLOUT_GAP;
head[0] = vec4(tail + side, 0, 0);
@@ -955,8 +958,8 @@ class BreakDecorator(BaseDecorator):
vec4 p;
vec4 quart = dir * BREAK_LENGTH * .25;
vec4 side = vec4(cross(vec3(dir.xy, 0), vec3(0, 0, 1)).xy, 0, 0) * BREAK_WIDTH;
vec4 quart = dir * viewportDrawingScale * BREAK_LENGTH * .25;
vec4 side = vec4(cross(vec3(dir.xy, 0), vec3(0, 0, 1)).xy, 0, 0) * viewportDrawingScale * BREAK_WIDTH;
// TODO: check if there's enough length for zigzag
@@ -1157,12 +1160,12 @@ class SectionViewDecorator(LevelDecorator):
vec4 p0w = CLIP2WIN(p0), p1w = CLIP2WIN(p1);
vec4 edge = p1w - p0w, dir = normalize(edge);
vec4 gap = dir * TRIANGLE_L * .5;
vec4 gap = dir * viewportDrawingScale * TRIANGLE_L * .5;
vec4 side = vec4(cross(vec3(dir.xy, 0), vec3(0, 0, 1)).xy, 0, 0);
vec4 p;
vec4 head[CIRCLE_SEGS];
circle_head(CIRCLE_SIZE, head);
circle_head(viewportDrawingScale * CIRCLE_SIZE, head);
vec4 head3[3];
@@ -1178,7 +1181,7 @@ class SectionViewDecorator(LevelDecorator):
EndPrimitive();
// start edge triangle
triangle_head(dir, -side, TRIANGLE_L, TRIANGLE_W, head3);
triangle_head(dir, -side, viewportDrawingScale * TRIANGLE_L, viewportDrawingScale * TRIANGLE_W, head3);
p = p0w + head3[0];
gl_Position = WIN2CLIP(p);
EmitVertex();
@@ -1202,7 +1205,7 @@ class SectionViewDecorator(LevelDecorator):
EndPrimitive();
// end edge triangle
triangle_head(-dir, -side, TRIANGLE_L, TRIANGLE_W, head3);
triangle_head(-dir, -side, viewportDrawingScale * TRIANGLE_L, viewportDrawingScale * TRIANGLE_W, head3);
p = p1w + head3[0];
gl_Position = WIN2CLIP(p);
EmitVertex();
@@ -499,7 +499,7 @@ class CreateDrawing(bpy.types.Operator):
elif element.ObjectType == "SOLID_LINE":
svg_writer.annotations.setdefault("solid_objs", []).append((obj, obj.data))
elif element.ObjectType == "PLAN_LEVEL":
svg_writer.annotations["plan_level_obj"] = obj
svg_writer.annotations.setdefault("plan_level_objs", []).append(obj)
elif element.ObjectType == "SECTION_LEVEL":
svg_writer.annotations["section_level_obj"] = obj
elif element.ObjectType == "TEXT":
@@ -288,7 +288,7 @@ class DocProperties(PropertyGroup):
drawing_styles: CollectionProperty(name="Drawing Styles", type=DrawingStyle)
should_draw_decorations: BoolProperty(name="Should Draw Decorations", update=toggleDecorations)
decorations_colour: FloatVectorProperty(
name="Decorations Colour", subtype="COLOR", default=(1, 0.5, 0, 1), min=0.0, max=1.0, size=4
name="Decorations Colour", subtype="COLOR", default=(1, 1, 1, 1), min=0.0, max=1.0, size=4
)
@property
@@ -211,50 +211,8 @@ class SvgWriter:
self.draw_leader_annotations()
if self.annotations.get("plan_level_obj"):
matrix_world = self.annotations["plan_level_obj"].matrix_world
for spline in self.annotations["plan_level_obj"].data.splines:
classes = ["annotation", "plan-level"]
points = self.get_spline_points(spline)
projected_points = [self.project_point_onto_camera(matrix_world @ p.co.xyz) for p in points]
d = " ".join(
[
"L {} {}".format((x_offset + p.x) * self.scale, (y_offset - p.y) * self.scale)
for p in projected_points
]
)
d = "M{}".format(d[1:])
path = self.svg.add(self.svg.path(d=d, class_=" ".join(classes)))
path["marker-end"] = "url(#plan-level-marker)"
text_position = Vector(
(
(x_offset + projected_points[0].x) * self.scale,
((y_offset - projected_points[0].y) * self.scale) - 2.5,
)
)
# TODO: allow metric to be configurable
rl = ((matrix_world @ points[0].co).xyz + self.annotations["plan_level_obj"].location).z
if bpy.context.scene.unit_settings.system == "IMPERIAL":
rl = helper.format_distance(rl)
else:
rl = "{:.3f}m".format(rl)
if projected_points[0].x > projected_points[-1].x:
text_anchor = "end"
else:
text_anchor = "start"
self.svg.add(
self.svg.text(
"RL +{}".format(rl),
insert=tuple(text_position),
**{
"font-size": annotation.Annotator.get_svg_text_size(2.5),
"font-family": "OpenGost Type B TT",
"text-anchor": text_anchor,
"alignment-baseline": "baseline",
"dominant-baseline": "baseline",
},
)
)
for obj in self.annotations.get("plan_level_objs", []):
self.draw_plan_level_annotation(obj)
if self.annotations.get("section_level_obj"):
matrix_world = self.annotations["section_level_obj"].matrix_world
@@ -577,6 +535,54 @@ class SvgWriter:
d = "M{}".format(d[1:])
path = self.svg.add(self.svg.path(d=d, class_=" ".join(["breakline"])))
def draw_plan_level_annotation(self, obj):
x_offset = self.raw_width / 2
y_offset = self.raw_height / 2
matrix_world = obj.matrix_world
for spline in obj.data.splines:
classes = ["annotation", "plan-level"]
points = self.get_spline_points(spline)
projected_points = [self.project_point_onto_camera(matrix_world @ p.co.xyz) for p in points]
d = " ".join(
[
"L {} {}".format((x_offset + p.x) * self.scale, (y_offset - p.y) * self.scale)
for p in projected_points
]
)
d = "M{}".format(d[1:])
path = self.svg.add(self.svg.path(d=d, class_=" ".join(classes)))
path["marker-end"] = "url(#plan-level-marker)"
text_position = Vector(
(
(x_offset + projected_points[0].x) * self.scale,
((y_offset - projected_points[0].y) * self.scale) - 2.5,
)
)
# TODO: allow metric to be configurable
rl = ((matrix_world @ points[0].co).xyz + obj.location).z
if bpy.context.scene.unit_settings.system == "IMPERIAL":
rl = helper.format_distance(rl)
else:
rl = "{:.3f}m".format(rl)
if projected_points[0].x > projected_points[-1].x:
text_anchor = "end"
else:
text_anchor = "start"
self.svg.add(
self.svg.text(
"RL +{}".format(rl),
insert=tuple(text_position),
**{
"font-size": annotation.Annotator.get_svg_text_size(2.5),
"font-family": "OpenGost Type B TT",
"text-anchor": text_anchor,
"alignment-baseline": "baseline",
"dominant-baseline": "baseline",
},
)
)
def draw_dimension_annotations(self, dimension_obj, text_override=None):
matrix_world = dimension_obj.matrix_world
for spline in dimension_obj.data.splines: