mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Section annotation - custom markers / toggle displaying the markers
Now it's possible to set custom markers in section annotation. To do so you need to add BBIM_Section pset to the annotation and then you can either toggle displaying some marker with ShowStartArrow/ShowEndArrow or you can write the id of some custom symbol in StartArrowSymbol/EndArrowSymbol (need to make sure the symbol is included in symbols.svg). Other changes: - removed vertex sorting in decoration.py so that start and end points will be the same thing both in svg and in viewport representation (previously the sorting was needed of the direction the arrow in shader wasn't inverted)); - fixed bug when in svg section arrow symbols wouldn't rotate if you move individual verts of the annotation, not the entire object (I guess this bug sneaked in after adapting elevation annotation)
This commit is contained in:
@@ -14,9 +14,9 @@ DATA;
|
||||
#7=IFCSIMPLEPROPERTYTEMPLATE('082PndS6v2kBOiJoSboMnh',$,'Reverse pattern direction','Reverse batting pattern (swap starting and ending points)',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#8=IFCPROPERTYSETTEMPLATE('1Dx2EiZnP67xotInXpwz90',$,'BBIM_Section','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#9,#10,#11,#12,#13));
|
||||
#9=IFCSIMPLEPROPERTYTEMPLATE('2a_9s8spHDc9dZHtgg71XL',$,'ShowStartArrow','Display start arrow.',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#10=IFCSIMPLEPROPERTYTEMPLATE('3i6SH_GbT7zhKea$wVE56A',$,'StartArrowSymbol','Custom symbol for the start of the section marker arrow.',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#10=IFCSIMPLEPROPERTYTEMPLATE('3i6SH_GbT7zhKea$wVE56A',$,'StartArrowSymbol','Custom symbol for the start of the section marker arrow. Need to make sure it''s present in "symbols.svg".',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#11=IFCSIMPLEPROPERTYTEMPLATE('1DtsPn5a9FG8$zXHDDMavY',$,'ShowEndArrow','Display end arrow.',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#12=IFCSIMPLEPROPERTYTEMPLATE('2$6U0mLI9AiPRWeBabdY3u',$,'EndArrowSymbol','Custom symbol for the end of the section marker arrow',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#12=IFCSIMPLEPROPERTYTEMPLATE('2$6U0mLI9AiPRWeBabdY3u',$,'EndArrowSymbol','Custom symbol for the end of the section marker arrow. Need to make sure it''s present in "symbols.svg".',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#13=IFCSIMPLEPROPERTYTEMPLATE('1naFqntIL7igCY7hCaE7kq',$,'HasConnectedSectionLine','Connect or disconnect section markers with line (by default = True).',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
||||
|
||||
@@ -126,6 +126,7 @@ class SchedulesData:
|
||||
|
||||
|
||||
class DecoratorData:
|
||||
# stores 1 type of data per object
|
||||
data = {}
|
||||
|
||||
@classmethod
|
||||
@@ -142,22 +143,42 @@ class DecoratorData:
|
||||
return thickness
|
||||
|
||||
@classmethod
|
||||
def get_section_pset_data(cls, obj):
|
||||
def get_section_markers_display_data(cls, obj):
|
||||
result = cls.data.get(obj.name, None)
|
||||
if result is not None:
|
||||
return result
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if element:
|
||||
# default values
|
||||
pset_data = {
|
||||
"HasConnectedSectionLine": True,
|
||||
"ShowStartArrow": True,
|
||||
"StartArrowSymbol": "",
|
||||
"ShowEndArrow": True,
|
||||
"EndArrowSymbol": "",
|
||||
}
|
||||
obj_pset_data = ifcopenshell.util.element.get_pset(element, "BBIM_Section") or {}
|
||||
pset_data.update(obj_pset_data)
|
||||
|
||||
cls.data[obj.name] = pset_data
|
||||
return pset_data
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
return
|
||||
|
||||
# default values
|
||||
pset_data = {
|
||||
"HasConnectedSectionLine": True,
|
||||
"ShowStartArrow": True,
|
||||
"StartArrowSymbol": "",
|
||||
"ShowEndArrow": True,
|
||||
"EndArrowSymbol": "",
|
||||
}
|
||||
obj_pset_data = ifcopenshell.util.element.get_pset(element, "BBIM_Section") or {}
|
||||
pset_data.update(obj_pset_data)
|
||||
|
||||
# create more usable display data
|
||||
start_symbol = pset_data["StartArrowSymbol"]
|
||||
end_symbol = pset_data["EndArrowSymbol"]
|
||||
display_data = {
|
||||
"start": {
|
||||
"add_circle": pset_data["ShowStartArrow"] and not start_symbol,
|
||||
"add_symbol": pset_data["ShowStartArrow"] or bool(start_symbol),
|
||||
"symbol": start_symbol or "section-arrow",
|
||||
},
|
||||
"end": {
|
||||
"add_circle": pset_data["ShowEndArrow"] and not end_symbol,
|
||||
"add_symbol": pset_data["ShowEndArrow"] or bool(end_symbol),
|
||||
"symbol": end_symbol or "section-arrow",
|
||||
},
|
||||
"connect_markers": pset_data["HasConnectedSectionLine"],
|
||||
}
|
||||
|
||||
cls.data[obj.name] = display_data
|
||||
return display_data
|
||||
|
||||
@@ -1812,6 +1812,10 @@ class SectionDecorator(LevelDecorator):
|
||||
uniform vec2 winsize;
|
||||
uniform float viewportDrawingScale;
|
||||
uniform float connect_markers;
|
||||
uniform float display_start_symbol;
|
||||
uniform float display_end_symbol;
|
||||
uniform float display_start_circle;
|
||||
uniform float display_end_circle;
|
||||
|
||||
layout(lines) in;
|
||||
layout(line_strip, max_vertices=MAX_POINTS) out;
|
||||
@@ -1835,7 +1839,7 @@ class SectionDecorator(LevelDecorator):
|
||||
vec4 p0w = CLIP2WIN(p0), p1w = CLIP2WIN(p1);
|
||||
vec4 edge = p1w - p0w, side = normalize(edge);
|
||||
vec4 gap = side * viewportDrawingScale * CIRCLE_SIZE;
|
||||
vec4 dir = vec4(cross(vec3(side.xy, 0), vec3(0, 0, 1)).xy, 0, 0);
|
||||
vec4 edge_ortho_dir = -vec4(cross(vec3(side.xy, 0), vec3(0, 0, 1)).xy, 0, 0);
|
||||
vec4 p;
|
||||
|
||||
vec4 head[CIRCLE_SEGS];
|
||||
@@ -1844,66 +1848,72 @@ class SectionDecorator(LevelDecorator):
|
||||
vec4 head5[5];
|
||||
|
||||
// start edge circle
|
||||
for(int i=0; i<CIRCLE_SEGS; i++) {
|
||||
p = p0w + head[i];
|
||||
if (display_start_circle > 0) {
|
||||
for(int i=0; i<CIRCLE_SEGS; i++) {
|
||||
p = p0w + head[i];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
}
|
||||
p = p0w + head[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
p = p0w + head[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
|
||||
// start edge triangle
|
||||
triangle_head(side, dir, viewportDrawingScale * TRIANGLE_L, viewportDrawingScale * TRIANGLE_W, viewportDrawingScale * CIRCLE_SIZE, head5);
|
||||
p = p0w + head5[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w + head5[1];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w + head5[2];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w + head5[3];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w + head5[4];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
|
||||
|
||||
if (display_start_symbol > 0) {
|
||||
// start edge triangle
|
||||
triangle_head(side, edge_ortho_dir, viewportDrawingScale * TRIANGLE_L, viewportDrawingScale * TRIANGLE_W, viewportDrawingScale * CIRCLE_SIZE, head5);
|
||||
p = p0w + head5[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w + head5[1];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w + head5[2];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w + head5[3];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w + head5[4];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
// end edge circle
|
||||
for(int i=0; i<CIRCLE_SEGS; i++) {
|
||||
p = p1w - head[i];
|
||||
if (display_end_circle > 0) {
|
||||
for(int i=0; i<CIRCLE_SEGS; i++) {
|
||||
p = p1w - head[i];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
}
|
||||
p = p1w - head[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
p = p1w - head[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
|
||||
// end edge triangle
|
||||
triangle_head(side, dir, viewportDrawingScale * TRIANGLE_L, viewportDrawingScale * TRIANGLE_W, viewportDrawingScale * CIRCLE_SIZE, head5);
|
||||
p = p1w + head5[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w + head5[1];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w + head5[2];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w + head5[3];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w + head5[4];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
if (display_end_symbol > 0) {
|
||||
triangle_head(side, edge_ortho_dir, viewportDrawingScale * TRIANGLE_L, viewportDrawingScale * TRIANGLE_W, viewportDrawingScale * CIRCLE_SIZE, head5);
|
||||
p = p1w + head5[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w + head5[1];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w + head5[2];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w + head5[3];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w + head5[4];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
float divider_line_size;
|
||||
if (connect_markers > 0) {
|
||||
@@ -1912,30 +1922,39 @@ class SectionDecorator(LevelDecorator):
|
||||
divider_line_size = CIRCLE_SIZE * 3;
|
||||
}
|
||||
|
||||
// NOTE: basically we consider first vertex to be
|
||||
// start and the second to be the end marker
|
||||
// which is a bit inconsistent with svg
|
||||
// but not that anyone will use multiple edge section annotation
|
||||
|
||||
// start reference divider
|
||||
p = p0w + normalize(vec4(-1, 0, 0, 0)) * viewportDrawingScale * divider_line_size;
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w + normalize(vec4(1, 0, 0, 0)) * viewportDrawingScale * CIRCLE_SIZE;
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
if (display_start_symbol > 0) {
|
||||
p = p0w + side * viewportDrawingScale * divider_line_size;
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w - side * viewportDrawingScale * CIRCLE_SIZE;
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
// end reference divider
|
||||
p = p1w + normalize(vec4(-1, 0, 0, 0)) * viewportDrawingScale * CIRCLE_SIZE;
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w + normalize(vec4(1, 0, 0, 0)) * viewportDrawingScale * divider_line_size;
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
if (display_end_symbol > 0) {
|
||||
p = p1w + side * viewportDrawingScale * CIRCLE_SIZE;
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w - side * viewportDrawingScale * divider_line_size;
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
// stem
|
||||
if (connect_markers > 0) {
|
||||
p = p0w + gap;
|
||||
p = p0w + (display_start_symbol > 0 ? gap : vec4(0));
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w - gap;
|
||||
p = p1w - (display_end_symbol > 0 ? gap : vec4(0));
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
@@ -1948,13 +1967,23 @@ class SectionDecorator(LevelDecorator):
|
||||
verts, idxs = self.get_editmesh_geom(obj)
|
||||
else:
|
||||
verts, idxs = self.get_mesh_geom(obj)
|
||||
vert_map = {v.freeze(): (obj.matrix_world.inverted() @ v).x for v in verts}
|
||||
verts = sorted(verts, key=lambda v: vert_map[v], reverse=True)
|
||||
|
||||
# TODO: add dashed line to shader
|
||||
# mind the vertices limit
|
||||
section_pset_data = DecoratorData.get_section_pset_data(obj)
|
||||
connect_markers = section_pset_data["HasConnectedSectionLine"]
|
||||
self.draw_lines(context, obj, verts, idxs, extra_float_kwargs={"connect_markers": float(connect_markers)})
|
||||
display_data = DecoratorData.get_section_markers_display_data(obj)
|
||||
self.draw_lines(
|
||||
context,
|
||||
obj,
|
||||
verts,
|
||||
idxs,
|
||||
extra_float_kwargs={
|
||||
"connect_markers": float(display_data["connect_markers"]),
|
||||
"display_start_symbol": float(display_data["start"]["add_symbol"]),
|
||||
"display_end_symbol": float(display_data["end"]["add_symbol"]),
|
||||
"display_start_circle": float(display_data["start"]["add_circle"]),
|
||||
"display_end_circle": float(display_data["end"]["add_circle"]),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class TextDecorator(BaseDecorator):
|
||||
|
||||
@@ -454,13 +454,17 @@ class SvgWriter:
|
||||
self.svg.add(self.svg.polyline(points=points, class_=" ".join(classes), style=polyline_style))
|
||||
|
||||
elif predefined_type == "SECTION":
|
||||
section_pset_data = DecoratorData.get_section_pset_data(obj)
|
||||
connect_markers = section_pset_data["HasConnectedSectionLine"]
|
||||
display_data = DecoratorData.get_section_markers_display_data(obj)
|
||||
connect_markers = display_data["connect_markers"]
|
||||
|
||||
if connect_markers:
|
||||
for edge in obj.data.edges:
|
||||
draw_simple_edge_annotation(*edge.vertices[:])
|
||||
else:
|
||||
for edge in obj.data.edges:
|
||||
v0_marker_position = "start" if edge.vertices[0] == 0 else "end"
|
||||
v1_marker_position = "start" if edge.vertices[1] == 0 else "end"
|
||||
|
||||
v0_global = matrix_world @ obj.data.vertices[edge.vertices[0]].co.xyz
|
||||
v1_global = matrix_world @ obj.data.vertices[edge.vertices[1]].co.xyz
|
||||
v0 = self.project_point_onto_camera(v0_global)
|
||||
@@ -472,20 +476,23 @@ class SvgWriter:
|
||||
circle_radius = 5
|
||||
segment_size = circle_radius * 3
|
||||
|
||||
self.svg.add(
|
||||
self.svg.line(
|
||||
start=start * self.svg_scale,
|
||||
end=start * self.svg_scale + edge_dir * segment_size,
|
||||
class_=" ".join(classes),
|
||||
if display_data[v0_marker_position]["add_symbol"]:
|
||||
self.svg.add(
|
||||
self.svg.line(
|
||||
start=start * self.svg_scale,
|
||||
end=start * self.svg_scale + edge_dir * segment_size,
|
||||
class_=" ".join(classes),
|
||||
)
|
||||
)
|
||||
)
|
||||
self.svg.add(
|
||||
self.svg.line(
|
||||
start=end * self.svg_scale,
|
||||
end=end * self.svg_scale - edge_dir * segment_size,
|
||||
class_=" ".join(classes),
|
||||
|
||||
if display_data[v1_marker_position]["add_symbol"]:
|
||||
self.svg.add(
|
||||
self.svg.line(
|
||||
start=end * self.svg_scale,
|
||||
end=end * self.svg_scale - edge_dir * segment_size,
|
||||
class_=" ".join(classes),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
else:
|
||||
for edge in obj.data.edges:
|
||||
@@ -507,58 +514,79 @@ class SvgWriter:
|
||||
|
||||
self.draw_line_annotation(obj)
|
||||
|
||||
v1 = self.project_point_onto_camera(obj.matrix_world @ Vector((0, 0, 0)))
|
||||
v2 = self.project_point_onto_camera(obj.matrix_world @ Vector((0, 0, -1)))
|
||||
angle = -math.degrees((v2 - v1).xy.angle_signed(Vector((0, 1))))
|
||||
display_data = DecoratorData.get_section_markers_display_data(obj)
|
||||
|
||||
for vert in obj.data.vertices:
|
||||
point = obj.matrix_world @ vert.co
|
||||
symbol_position = self.project_point_onto_camera(point)
|
||||
symbol_position = Vector(((x_offset + symbol_position.x), (y_offset - symbol_position.y)))
|
||||
transform = "rotate({}, {}, {})".format(
|
||||
angle,
|
||||
(symbol_position * self.svg_scale)[0],
|
||||
(symbol_position * self.svg_scale)[1],
|
||||
)
|
||||
for edge in obj.data.edges:
|
||||
edge_verts = [obj.data.vertices[v_i] for v_i in edge.vertices]
|
||||
|
||||
self.svg.add(
|
||||
self.svg.use("#section-arrow", insert=tuple(symbol_position * self.svg_scale), transform=transform)
|
||||
)
|
||||
self.svg.add(self.svg.use("#section-tag", insert=tuple(symbol_position * self.svg_scale)))
|
||||
# convert edge vertiices coordinates to svg space
|
||||
# to calculate the edge angle and for later use
|
||||
edge_verts_svg = []
|
||||
for vert in edge_verts:
|
||||
point = obj.matrix_world @ vert.co
|
||||
symbol_position = self.project_point_onto_camera(point)
|
||||
symbol_position = Vector(((x_offset + symbol_position.x), (y_offset - symbol_position.y)))
|
||||
symbol_position_svg = symbol_position * self.svg_scale
|
||||
edge_verts_svg.append(symbol_position_svg)
|
||||
|
||||
reference_id, sheet_id = self.get_reference_and_sheet_id_from_annotation(tool.Ifc.get_entity(obj))
|
||||
text_position = list(symbol_position * self.svg_scale)
|
||||
text_style = {
|
||||
"text-anchor": "middle",
|
||||
"alignment-baseline": "middle",
|
||||
"dominant-baseline": "middle",
|
||||
}
|
||||
self.svg.add(self.svg.text(reference_id, insert=(text_position[0], text_position[1] - 2.5), class_="SECTION", **text_style))
|
||||
self.svg.add(self.svg.text(sheet_id, insert=(text_position[0], text_position[1] + 2.5), class_="SECTION", **text_style))
|
||||
edge_dir = (edge_verts_svg[1] - edge_verts_svg[0]).normalized()
|
||||
angle = degrees( edge_dir.xy.angle_signed( Vector([1,0]) ) )
|
||||
|
||||
for v_i, symbol_position_svg in zip(edge.vertices, edge_verts_svg):
|
||||
current_marker_position = "start" if v_i == 0 else "end"
|
||||
|
||||
# marker arrow symbol
|
||||
if display_data[current_marker_position]["add_symbol"]:
|
||||
transform = "rotate({}, {}, {})".format(angle, *symbol_position_svg.xy)
|
||||
symbol_id = display_data[current_marker_position]["symbol"]
|
||||
self.svg.add(self.svg.use(f"#{symbol_id}", insert=symbol_position_svg, transform=transform))
|
||||
|
||||
# marker circle and it's text
|
||||
if display_data[current_marker_position]["add_circle"]:
|
||||
self.svg.add(self.svg.use("#section-tag", insert=symbol_position_svg))
|
||||
|
||||
reference_id, sheet_id = self.get_reference_and_sheet_id_from_annotation(tool.Ifc.get_entity(obj))
|
||||
text_position = symbol_position_svg
|
||||
text_style = {
|
||||
"text-anchor": "middle",
|
||||
"alignment-baseline": "middle",
|
||||
"dominant-baseline": "middle",
|
||||
}
|
||||
self.svg.add(
|
||||
self.svg.text(
|
||||
reference_id,
|
||||
insert=(text_position[0], text_position[1] - 2.5),
|
||||
class_="SECTION",
|
||||
**text_style,
|
||||
)
|
||||
)
|
||||
self.svg.add(
|
||||
self.svg.text(
|
||||
sheet_id,
|
||||
insert=(text_position[0], text_position[1] + 2.5),
|
||||
class_="SECTION",
|
||||
**text_style
|
||||
)
|
||||
)
|
||||
|
||||
def draw_elevation_annotation(self, obj):
|
||||
x_offset = self.raw_width / 2
|
||||
y_offset = self.raw_height / 2
|
||||
symbol_position = self.project_point_onto_camera(obj.location)
|
||||
symbol_position = Vector(((x_offset + symbol_position.x), (y_offset - symbol_position.y)))
|
||||
symbol_position_svg = symbol_position * self.svg_scale
|
||||
|
||||
v1 = self.project_point_onto_camera(obj.matrix_world @ Vector((0, 0, 0)))
|
||||
v2 = self.project_point_onto_camera(obj.matrix_world @ Vector((0, 0, -1)))
|
||||
angle = -math.degrees((v2 - v1).xy.angle_signed(Vector((0, 1))))
|
||||
|
||||
transform = "rotate({}, {}, {})".format(
|
||||
angle,
|
||||
(symbol_position * self.svg_scale)[0],
|
||||
(symbol_position * self.svg_scale)[1],
|
||||
)
|
||||
transform = "rotate({}, {}, {})".format(angle, *symbol_position_svg.xy)
|
||||
|
||||
self.svg.add(
|
||||
self.svg.use("#elevation-arrow", insert=tuple(symbol_position * self.svg_scale), transform=transform)
|
||||
)
|
||||
self.svg.add(self.svg.use("#elevation-tag", insert=tuple(symbol_position * self.svg_scale)))
|
||||
self.svg.add(self.svg.use("#elevation-arrow", insert=symbol_position_svg, transform=transform))
|
||||
self.svg.add(self.svg.use("#elevation-tag", insert=symbol_position_svg))
|
||||
|
||||
reference_id, sheet_id = self.get_reference_and_sheet_id_from_annotation(tool.Ifc.get_entity(obj))
|
||||
text_position = list(symbol_position * self.svg_scale)
|
||||
text_position = symbol_position_svg
|
||||
text_style = {
|
||||
"text-anchor": "middle",
|
||||
"alignment-baseline": "middle",
|
||||
@@ -766,7 +794,7 @@ class SvgWriter:
|
||||
bm.verts.index_update()
|
||||
bm.edges.index_update()
|
||||
new_verts = [bm.verts.new(p) for p in points_chunk]
|
||||
new_edges = [bm.edges.new( (new_verts[e[0]], new_verts[e[1]]) ) for e in ((0, 1), (1, 2))]
|
||||
new_edges = [bm.edges.new((new_verts[e[0]], new_verts[e[1]])) for e in ((0, 1), (1, 2))]
|
||||
self.draw_svg_3point_arc(obj, bm)
|
||||
|
||||
def draw_svg_3point_arc(self, obj, bm):
|
||||
@@ -967,7 +995,7 @@ class SvgWriter:
|
||||
run = (B - O).length
|
||||
if run != 0:
|
||||
angle_tg = rise / run
|
||||
angle = round( degrees( atan(angle_tg) ))
|
||||
angle = round(degrees(atan(angle_tg)))
|
||||
else:
|
||||
angle = 90
|
||||
|
||||
|
||||
Reference in New Issue
Block a user