mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-17 02:49:12 +00:00
Added option for oblique style for viewport dimension annotations
It's available after adding "oblique" to EPset_Annotation classes of the annotaiton. Examples with and without it: - https://i.imgur.com/JtgSeUK.png - https://i.imgur.com/H7TPnfo.png
This commit is contained in:
@@ -115,6 +115,7 @@ class DecoratorData:
|
||||
# stores 1 type of data per object
|
||||
data = {}
|
||||
|
||||
# used by Ifc Annotations with ObjectType = "BATTING"
|
||||
@classmethod
|
||||
def get_batting_thickness(cls, obj):
|
||||
result = cls.data.get(obj.name, None)
|
||||
@@ -128,6 +129,7 @@ class DecoratorData:
|
||||
cls.data[obj.name] = thickness
|
||||
return thickness
|
||||
|
||||
# used by Ifc Annotations with ObjectType = "SECTION"
|
||||
@classmethod
|
||||
def get_section_markers_display_data(cls, obj):
|
||||
result = cls.data.get(obj.name, None)
|
||||
@@ -169,6 +171,7 @@ class DecoratorData:
|
||||
cls.data[obj.name] = display_data
|
||||
return display_data
|
||||
|
||||
# used by Ifc Annotations with ObjectType = "TEXT"
|
||||
@classmethod
|
||||
def get_ifc_text_data(cls, obj):
|
||||
"""returns font size in mm for current ifc text object"""
|
||||
@@ -214,3 +217,22 @@ class DecoratorData:
|
||||
text_data = {"Literals": literals_data, "FontSize": font_size}
|
||||
cls.data[obj.name] = text_data
|
||||
return text_data
|
||||
|
||||
# used by Ifc Annotations with ObjectType = "DIMENSION"
|
||||
@classmethod
|
||||
def get_dimension_style(cls, obj):
|
||||
result = cls.data.get(obj.name, None)
|
||||
if result is not None:
|
||||
return result
|
||||
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element or not element.is_a("IfcAnnotation") or element.ObjectType != "DIMENSION":
|
||||
return None
|
||||
|
||||
dimension_style = "arrow"
|
||||
classes = ifcopenshell.util.element.get_pset(element, "EPset_Annotation", "Classes")
|
||||
if classes and "oblique" in classes.lower().split():
|
||||
dimension_style = "oblique"
|
||||
|
||||
cls.data[obj.name] = dimension_style
|
||||
return dimension_style
|
||||
|
||||
@@ -442,7 +442,7 @@ class BaseDecorator:
|
||||
box_alignment_offset += Vector((0, h))
|
||||
else:
|
||||
# middle / center
|
||||
box_alignment_offset += Vector((0, h / 2))
|
||||
box_alignment_offset += Vector((0, h / 2))
|
||||
|
||||
if "left" in box_alignment:
|
||||
pass
|
||||
@@ -451,7 +451,7 @@ class BaseDecorator:
|
||||
else:
|
||||
# middle / center
|
||||
box_alignment_offset += Vector((w / 2, 0))
|
||||
|
||||
|
||||
pos -= rotation_matrix.transposed() @ box_alignment_offset
|
||||
else:
|
||||
if center:
|
||||
@@ -506,6 +506,10 @@ class DimensionDecorator(BaseDecorator):
|
||||
DEF_GLSL = (
|
||||
BaseDecorator.DEF_GLSL
|
||||
+ """
|
||||
#define OBLIQUE_SYMBOL_ANGLE PI / 4.0
|
||||
#define OLBIQUE_SYMBOL_SIZE 10.0
|
||||
#define OBLIQUE_HEAD_VERTS 7
|
||||
|
||||
#define ARROW_ANGLE PI / 12.0
|
||||
#define ARROW_SIZE 16.0
|
||||
"""
|
||||
@@ -514,10 +518,23 @@ class DimensionDecorator(BaseDecorator):
|
||||
GEOM_GLSL = """
|
||||
uniform vec2 winsize;
|
||||
uniform float viewportDrawingScale;
|
||||
uniform float use_oblique_style;
|
||||
|
||||
layout(lines) in;
|
||||
layout(line_strip, max_vertices=MAX_POINTS) out;
|
||||
|
||||
void oblique_dimension_head(in vec4 dir, in float size, in float angle, out vec4 head[OBLIQUE_HEAD_VERTS]) {
|
||||
float c = cos(angle), s = sin(angle);
|
||||
vec4 ortho = vec4(-dir.y, dir.x, 0, 0);
|
||||
head[0] = -dir * size*0.66;
|
||||
head[1] = vec4(0);
|
||||
head[2] = ortho * size;
|
||||
head[3] = -ortho * size;
|
||||
head[4] = vec4(0);
|
||||
head[5] = vec4((mat2(c, +s, -s, c) * dir.xy) * size * 0.47, 0, 0);
|
||||
head[6] = -head[5];
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 clip2win = matCLIP2WIN();
|
||||
vec4 win2clip = matWIN2CLIP();
|
||||
@@ -529,49 +546,78 @@ class DimensionDecorator(BaseDecorator):
|
||||
|
||||
vec4 p;
|
||||
|
||||
vec4 head[3];
|
||||
arrow_head(dir, viewportDrawingScale * ARROW_SIZE, ARROW_ANGLE, head);
|
||||
if (use_oblique_style > 0) {
|
||||
vec4 head[OBLIQUE_HEAD_VERTS];
|
||||
oblique_dimension_head(dir, viewportDrawingScale * OLBIQUE_SYMBOL_SIZE, OBLIQUE_SYMBOL_ANGLE, head);
|
||||
|
||||
// start edge arrow
|
||||
gl_Position = p0;
|
||||
EmitVertex();
|
||||
p = p0w + head[1];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w + head[2];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
gl_Position = p0;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
// start edge arrow
|
||||
for (int i = 0; i < OBLIQUE_HEAD_VERTS; i++) {
|
||||
gl_Position = WIN2CLIP((p0w + head[i]));
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
|
||||
// end edge arrow
|
||||
gl_Position = p1;
|
||||
EmitVertex();
|
||||
p = p1w - head[1];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w - head[2];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
gl_Position = p1;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
// end edge arrow
|
||||
for (int i = 0; i < OBLIQUE_HEAD_VERTS; i++) {
|
||||
gl_Position = WIN2CLIP((p1w - head[i]));
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
|
||||
// stem, with gaps for arrows
|
||||
p = p0w + head[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w - head[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
// stem
|
||||
gl_Position = p0;
|
||||
EmitVertex();
|
||||
gl_Position = p1;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
} else {
|
||||
vec4 head[3];
|
||||
arrow_head(dir, viewportDrawingScale * ARROW_SIZE, ARROW_ANGLE, head);
|
||||
|
||||
// start edge arrow
|
||||
gl_Position = p0;
|
||||
EmitVertex();
|
||||
p = p0w + head[1];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p0w + head[2];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
gl_Position = p0;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
|
||||
// end edge arrow
|
||||
gl_Position = p1;
|
||||
EmitVertex();
|
||||
p = p1w - head[1];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w - head[2];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
gl_Position = p1;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
|
||||
// stem, with gaps for arrows
|
||||
p = p0w + head[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
p = p1w - head[0];
|
||||
gl_Position = WIN2CLIP(p);
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
def decorate(self, context, obj):
|
||||
verts, idxs, _ = self.get_path_geom(obj, topo=False)
|
||||
self.draw_lines(context, obj, verts, idxs)
|
||||
dimension_style = DecoratorData.get_dimension_style(obj)
|
||||
self.draw_lines(
|
||||
context, obj, verts, idxs, extra_float_kwargs={"use_oblique_style": float(dimension_style == "oblique")}
|
||||
)
|
||||
self.draw_labels(context, obj, verts, idxs)
|
||||
|
||||
def draw_labels(self, context, obj, vertices, indices):
|
||||
@@ -806,7 +852,7 @@ class LeaderDecorator(BaseDecorator):
|
||||
|
||||
props = obj.BIMTextProperties
|
||||
text_data = props.get_text_edited_data() if props.is_editing else DecoratorData.get_ifc_text_data(obj)
|
||||
text = text_data["Literals"][0]['CurrentValue']
|
||||
text = text_data["Literals"][0]["CurrentValue"]
|
||||
|
||||
self.draw_label(context, text, pos, dir, gap=0, center=False, vcenter=False)
|
||||
|
||||
@@ -1336,11 +1382,11 @@ class PlanLevelDecorator(LevelDecorator):
|
||||
dir = p1 - p0
|
||||
if dir.length < 1:
|
||||
continue
|
||||
|
||||
|
||||
if dir.x > 0:
|
||||
box_alignment = "bottom-left"
|
||||
else:
|
||||
box_alignment = 'bottom-right'
|
||||
box_alignment = "bottom-right"
|
||||
dir *= -1
|
||||
|
||||
z = verts[-1].z / unit_scale
|
||||
@@ -2098,7 +2144,7 @@ class TextDecorator(BaseDecorator):
|
||||
def matrix_only_rotation(m):
|
||||
return m.to_3x3().normalized().to_4x4()
|
||||
|
||||
text_dir = Vector((1,0))
|
||||
text_dir = Vector((1, 0))
|
||||
text_dir_world = matrix_only_rotation(region3d.perspective_matrix.inverted()) @ text_dir.to_3d()
|
||||
text_dir_world_rotated = matrix_only_rotation(obj.matrix_world) @ text_dir_world
|
||||
text_dir = (matrix_only_rotation(region3d.perspective_matrix) @ text_dir_world_rotated).to_2d().normalized()
|
||||
|
||||
Reference in New Issue
Block a user