mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 02:23:34 +00:00
More slow progress in getting annotations round-tripping. See #1153.
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user