mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 18:21:59 +00:00
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:
@@ -1,7 +1,7 @@
|
|||||||
ISO-10303-21;
|
ISO-10303-21;
|
||||||
HEADER;
|
HEADER;
|
||||||
FILE_DESCRIPTION((),'2;1');
|
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'));
|
FILE_SCHEMA(('IFC4'));
|
||||||
ENDSEC;
|
ENDSEC;
|
||||||
DATA;
|
DATA;
|
||||||
@@ -12,5 +12,11 @@ DATA;
|
|||||||
#5=IFCPROPERTYSETTEMPLATE('0iKwujnQL9IevVQato8f7Z',$,'BBIM_Batting','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#6,#7));
|
#5=IFCPROPERTYSETTEMPLATE('0iKwujnQL9IevVQato8f7Z',$,'BBIM_Batting','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#6,#7));
|
||||||
#6=IFCSIMPLEPROPERTYTEMPLATE('0t2LEesGT1QRQtrIZUAR8L',$,'Thickness','Batting thickness',.P_SINGLEVALUE.,'IfcPositiveLengthMeasure',$,$,$,$,$,.READWRITE.);
|
#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.);
|
#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;
|
ENDSEC;
|
||||||
END-ISO-10303-21;
|
END-ISO-10303-21;
|
||||||
|
|||||||
@@ -140,4 +140,24 @@ class DecoratorData:
|
|||||||
thickness = thickness * unit_scale if thickness else 1.5
|
thickness = thickness * unit_scale if thickness else 1.5
|
||||||
cls.data[obj.name] = thickness
|
cls.data[obj.name] = thickness
|
||||||
return 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 = []
|
indices = []
|
||||||
idx = 0
|
idx = 0
|
||||||
|
|
||||||
|
# TODO: are we adding same verts twice?
|
||||||
for edge in mesh.edges:
|
for edge in mesh.edges:
|
||||||
vertices.extend(edge.verts)
|
vertices.extend(edge.verts)
|
||||||
indices.append((idx, idx + 1))
|
indices.append((idx, idx + 1))
|
||||||
@@ -1818,6 +1819,7 @@ class SectionDecorator(LevelDecorator):
|
|||||||
GEOM_GLSL = """
|
GEOM_GLSL = """
|
||||||
uniform vec2 winsize;
|
uniform vec2 winsize;
|
||||||
uniform float viewportDrawingScale;
|
uniform float viewportDrawingScale;
|
||||||
|
uniform float connect_markers;
|
||||||
|
|
||||||
layout(lines) in;
|
layout(lines) in;
|
||||||
layout(line_strip, max_vertices=MAX_POINTS) out;
|
layout(line_strip, max_vertices=MAX_POINTS) out;
|
||||||
@@ -1879,14 +1881,7 @@ class SectionDecorator(LevelDecorator):
|
|||||||
EmitVertex();
|
EmitVertex();
|
||||||
EndPrimitive();
|
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
|
// end edge circle
|
||||||
for(int i=0; i<CIRCLE_SEGS; i++) {
|
for(int i=0; i<CIRCLE_SEGS; i++) {
|
||||||
@@ -1918,23 +1913,41 @@ class SectionDecorator(LevelDecorator):
|
|||||||
EmitVertex();
|
EmitVertex();
|
||||||
EndPrimitive();
|
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
|
// end reference divider
|
||||||
p = p1w + normalize(vec4(-1, 0, 0, 0)) * viewportDrawingScale * CIRCLE_SIZE;
|
p = p1w + normalize(vec4(-1, 0, 0, 0)) * viewportDrawingScale * CIRCLE_SIZE;
|
||||||
gl_Position = WIN2CLIP(p);
|
gl_Position = WIN2CLIP(p);
|
||||||
EmitVertex();
|
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);
|
gl_Position = WIN2CLIP(p);
|
||||||
EmitVertex();
|
EmitVertex();
|
||||||
EndPrimitive();
|
EndPrimitive();
|
||||||
|
|
||||||
// stem
|
// stem
|
||||||
p = p0w + gap;
|
if (connect_markers > 0) {
|
||||||
gl_Position = WIN2CLIP(p);
|
p = p0w + gap;
|
||||||
EmitVertex();
|
gl_Position = WIN2CLIP(p);
|
||||||
p = p1w - gap;
|
EmitVertex();
|
||||||
gl_Position = WIN2CLIP(p);
|
p = p1w - gap;
|
||||||
EmitVertex();
|
gl_Position = WIN2CLIP(p);
|
||||||
EndPrimitive();
|
EmitVertex();
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -1945,7 +1958,11 @@ class SectionDecorator(LevelDecorator):
|
|||||||
verts, idxs = self.get_mesh_geom(obj)
|
verts, idxs = self.get_mesh_geom(obj)
|
||||||
vert_map = {v.freeze(): (obj.matrix_world.inverted() @ v).x for v in verts}
|
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)
|
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):
|
class TextDecorator(BaseDecorator):
|
||||||
|
|||||||
@@ -31,10 +31,12 @@ import ifcopenshell.util.representation
|
|||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
import blenderbim.bim.module.drawing.helper as helper
|
import blenderbim.bim.module.drawing.helper as helper
|
||||||
import blenderbim.bim.module.drawing.annotation as annotation
|
import blenderbim.bim.module.drawing.annotation as annotation
|
||||||
from math import pi, ceil, atan, degrees
|
|
||||||
from mathutils import Vector
|
from blenderbim.bim.module.drawing.data import DecoratorData
|
||||||
from mathutils import geometry
|
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
|
||||||
|
from math import pi, ceil, atan, degrees
|
||||||
|
from mathutils import geometry, Vector
|
||||||
from bpy_extras import view3d_utils
|
from bpy_extras import view3d_utils
|
||||||
|
|
||||||
|
|
||||||
@@ -367,13 +369,25 @@ class SvgWriter:
|
|||||||
self.draw_edge_annotation(obj, classes)
|
self.draw_edge_annotation(obj, classes)
|
||||||
|
|
||||||
def draw_edge_annotation(self, 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
|
||||||
x_offset = self.raw_width / 2
|
y_offset = self.raw_height / 2
|
||||||
y_offset = self.raw_height / 2
|
matrix_world = obj.matrix_world
|
||||||
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
|
v0_global = matrix_world @ obj.data.vertices[0].co.xyz
|
||||||
v1_global = matrix_world @ obj.data.vertices[1].co.xyz
|
v1_global = matrix_world @ obj.data.vertices[1].co.xyz
|
||||||
v0 = self.project_point_onto_camera(v0_global)
|
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))
|
self.svg.add(self.svg.polyline(points=points, class_=" ".join(classes), style=polyline_style))
|
||||||
|
|
||||||
else:
|
elif predefined_type == "SECTION":
|
||||||
x_offset = self.raw_width / 2
|
section_pset_data = DecoratorData.get_section_pset_data(obj)
|
||||||
y_offset = self.raw_height / 2
|
connect_markers = section_pset_data["HasConnectedSectionLine"]
|
||||||
matrix_world = obj.matrix_world
|
if connect_markers:
|
||||||
for edge in obj.data.edges:
|
for edge in obj.data.edges:
|
||||||
v0_global = matrix_world @ obj.data.vertices[edge.vertices[0]].co.xyz
|
draw_simple_edge_annotation(*edge.vertices[:])
|
||||||
v1_global = matrix_world @ obj.data.vertices[edge.vertices[1]].co.xyz
|
else:
|
||||||
v0 = self.project_point_onto_camera(v0_global)
|
for edge in obj.data.edges:
|
||||||
v1 = self.project_point_onto_camera(v1_global)
|
v0_global = matrix_world @ obj.data.vertices[edge.vertices[0]].co.xyz
|
||||||
start = Vector(((x_offset + v0.x), (y_offset - v0.y)))
|
v1_global = matrix_world @ obj.data.vertices[edge.vertices[1]].co.xyz
|
||||||
end = Vector(((x_offset + v1.x), (y_offset - v1.y)))
|
v0 = self.project_point_onto_camera(v0_global)
|
||||||
vector = end - start
|
v1 = self.project_point_onto_camera(v1_global)
|
||||||
line = self.svg.add(
|
start = Vector(((x_offset + v0.x), (y_offset - v0.y)))
|
||||||
self.svg.line(
|
end = Vector(((x_offset + v1.x), (y_offset - v1.y)))
|
||||||
start=tuple(start * self.svg_scale), end=tuple(end * self.svg_scale), class_=" ".join(classes)
|
|
||||||
|
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):
|
def draw_leader_annotation(self, obj):
|
||||||
self.draw_line_annotation(obj)
|
self.draw_line_annotation(obj)
|
||||||
|
|||||||
Reference in New Issue
Block a user