Section annotation option not to draw full line between the markers

Here's the example - https://i.imgur.com/db09OVF.png

To make it work need to add BBIM_Section property set to the annotation and set "HasConnectedSectionLine" to False (by default it's True).
Also added preview for this feature in viewport.
This commit is contained in:
Andrej730
2023-03-10 12:37:30 +05:00
parent 3706ecc5f2
commit c9f93b2316
4 changed files with 121 additions and 44 deletions
@@ -1,7 +1,7 @@
ISO-10303-21;
HEADER;
FILE_DESCRIPTION((),'2;1');
FILE_NAME('EPset_Annotation.ifc','2020-01-01T00:00:00',(),(),'EPset_Annotation','EPset_Annotation',$);
FILE_NAME('Psets_BBIM_Annotation.ifc','2020-01-01T00:00:00',(),(),'Psets_BBIM_Annotation','Psets_BBIM_Annotation',$);
FILE_SCHEMA(('IFC4'));
ENDSEC;
DATA;
@@ -12,5 +12,11 @@ DATA;
#5=IFCPROPERTYSETTEMPLATE('0iKwujnQL9IevVQato8f7Z',$,'BBIM_Batting','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#6,#7));
#6=IFCSIMPLEPROPERTYTEMPLATE('0t2LEesGT1QRQtrIZUAR8L',$,'Thickness','Batting thickness',.P_SINGLEVALUE.,'IfcPositiveLengthMeasure',$,$,$,$,$,.READWRITE.);
#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.);
#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.);
#13=IFCSIMPLEPROPERTYTEMPLATE('1naFqntIL7igCY7hCaE7kq',$,'HasConnectedSectionLine','Connect or disconnect section markers with line (by default = True).',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
ENDSEC;
END-ISO-10303-21;
@@ -136,8 +136,28 @@ class DecoratorData:
element = tool.Ifc.get_entity(obj)
if element:
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
thickness = ifcopenshell.util.element.get_pset(element, "BBIM_Batting", "Thickness")
thickness = ifcopenshell.util.element.get_pset(element, "BBIM_Batting", "Thickness")
thickness = thickness * unit_scale if thickness else 1.5
cls.data[obj.name] = thickness
return thickness
return 1.5
@classmethod
def get_section_pset_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
@@ -309,6 +309,7 @@ class BaseDecorator:
indices = []
idx = 0
# TODO: are we adding same verts twice?
for edge in mesh.edges:
vertices.extend(edge.verts)
indices.append((idx, idx + 1))
@@ -1818,6 +1819,7 @@ class SectionDecorator(LevelDecorator):
GEOM_GLSL = """
uniform vec2 winsize;
uniform float viewportDrawingScale;
uniform float connect_markers;
layout(lines) in;
layout(line_strip, max_vertices=MAX_POINTS) out;
@@ -1879,14 +1881,7 @@ class SectionDecorator(LevelDecorator):
EmitVertex();
EndPrimitive();
// start reference divider
p = p0w + normalize(vec4(-1, 0, 0, 0)) * viewportDrawingScale * CIRCLE_SIZE;
gl_Position = WIN2CLIP(p);
EmitVertex();
p = p0w + normalize(vec4(1, 0, 0, 0)) * viewportDrawingScale * CIRCLE_SIZE;
gl_Position = WIN2CLIP(p);
EmitVertex();
EndPrimitive();
// end edge circle
for(int i=0; i<CIRCLE_SEGS; i++) {
@@ -1918,23 +1913,41 @@ class SectionDecorator(LevelDecorator):
EmitVertex();
EndPrimitive();
float divider_line_size;
if (connect_markers > 0) {
divider_line_size = CIRCLE_SIZE;
} else {
divider_line_size = CIRCLE_SIZE * 3;
}
// 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();
// 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 * CIRCLE_SIZE;
p = p1w + normalize(vec4(1, 0, 0, 0)) * viewportDrawingScale * divider_line_size;
gl_Position = WIN2CLIP(p);
EmitVertex();
EndPrimitive();
// stem
p = p0w + gap;
gl_Position = WIN2CLIP(p);
EmitVertex();
p = p1w - gap;
gl_Position = WIN2CLIP(p);
EmitVertex();
EndPrimitive();
if (connect_markers > 0) {
p = p0w + gap;
gl_Position = WIN2CLIP(p);
EmitVertex();
p = p1w - gap;
gl_Position = WIN2CLIP(p);
EmitVertex();
EndPrimitive();
}
}
"""
@@ -1945,7 +1958,11 @@ class SectionDecorator(LevelDecorator):
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)
self.draw_lines(context, obj, verts, idxs)
# 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)})
class TextDecorator(BaseDecorator):
@@ -31,10 +31,12 @@ import ifcopenshell.util.representation
import blenderbim.tool as tool
import blenderbim.bim.module.drawing.helper as helper
import blenderbim.bim.module.drawing.annotation as annotation
from math import pi, ceil, atan, degrees
from mathutils import Vector
from mathutils import geometry
from blenderbim.bim.module.drawing.data import DecoratorData
from blenderbim.bim.ifc import IfcStore
from math import pi, ceil, atan, degrees
from mathutils import geometry, Vector
from bpy_extras import view3d_utils
@@ -367,13 +369,25 @@ class SvgWriter:
self.draw_edge_annotation(obj, classes)
def draw_edge_annotation(self, obj, classes):
predefined_type = classes[2]
predefined_type = classes[2].split("-", 1)[1]
if predefined_type.endswith("-BATTING"):
x_offset = self.raw_width / 2
y_offset = self.raw_height / 2
matrix_world = obj.matrix_world
x_offset = self.raw_width / 2
y_offset = self.raw_height / 2
matrix_world = obj.matrix_world
def draw_simple_edge_annotation(v0, v1):
v0_global = matrix_world @ obj.data.vertices[v0].co.xyz
v1_global = matrix_world @ obj.data.vertices[v1].co.xyz
v0 = self.project_point_onto_camera(v0_global)
v1 = self.project_point_onto_camera(v1_global)
start = Vector(((x_offset + v0.x), (y_offset - v0.y)))
end = Vector(((x_offset + v1.x), (y_offset - v1.y)))
line = self.svg.add(
self.svg.line(start=start * self.svg_scale, end=end * self.svg_scale, class_=" ".join(classes))
)
# BATTING ANNOTATIONS
if predefined_type == "BATTING":
v0_global = matrix_world @ obj.data.vertices[0].co.xyz
v1_global = matrix_world @ obj.data.vertices[1].co.xyz
v0 = self.project_point_onto_camera(v0_global)
@@ -439,23 +453,43 @@ class SvgWriter:
)
self.svg.add(self.svg.polyline(points=points, class_=" ".join(classes), style=polyline_style))
else:
x_offset = self.raw_width / 2
y_offset = self.raw_height / 2
matrix_world = obj.matrix_world
for edge in obj.data.edges:
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)
v1 = self.project_point_onto_camera(v1_global)
start = Vector(((x_offset + v0.x), (y_offset - v0.y)))
end = Vector(((x_offset + v1.x), (y_offset - v1.y)))
vector = end - start
line = self.svg.add(
self.svg.line(
start=tuple(start * self.svg_scale), end=tuple(end * self.svg_scale), class_=" ".join(classes)
elif predefined_type == "SECTION":
section_pset_data = DecoratorData.get_section_pset_data(obj)
connect_markers = section_pset_data["HasConnectedSectionLine"]
if connect_markers:
for edge in obj.data.edges:
draw_simple_edge_annotation(*edge.vertices[:])
else:
for edge in obj.data.edges:
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)
v1 = self.project_point_onto_camera(v1_global)
start = Vector(((x_offset + v0.x), (y_offset - v0.y)))
end = Vector(((x_offset + v1.x), (y_offset - v1.y)))
edge_dir = (end - start).normalized()
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),
)
)
)
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:
draw_simple_edge_annotation(*edge.vertices[:])
def draw_leader_annotation(self, obj):
self.draw_line_annotation(obj)