mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-10-02 13:04:49 +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
|
# stores 1 type of data per object
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
|
# used by Ifc Annotations with ObjectType = "BATTING"
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_batting_thickness(cls, obj):
|
def get_batting_thickness(cls, obj):
|
||||||
result = cls.data.get(obj.name, None)
|
result = cls.data.get(obj.name, None)
|
||||||
@@ -128,6 +129,7 @@ class DecoratorData:
|
|||||||
cls.data[obj.name] = thickness
|
cls.data[obj.name] = thickness
|
||||||
return thickness
|
return thickness
|
||||||
|
|
||||||
|
# used by Ifc Annotations with ObjectType = "SECTION"
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_section_markers_display_data(cls, obj):
|
def get_section_markers_display_data(cls, obj):
|
||||||
result = cls.data.get(obj.name, None)
|
result = cls.data.get(obj.name, None)
|
||||||
@@ -169,6 +171,7 @@ class DecoratorData:
|
|||||||
cls.data[obj.name] = display_data
|
cls.data[obj.name] = display_data
|
||||||
return display_data
|
return display_data
|
||||||
|
|
||||||
|
# used by Ifc Annotations with ObjectType = "TEXT"
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_ifc_text_data(cls, obj):
|
def get_ifc_text_data(cls, obj):
|
||||||
"""returns font size in mm for current ifc text object"""
|
"""returns font size in mm for current ifc text object"""
|
||||||
@@ -214,3 +217,22 @@ class DecoratorData:
|
|||||||
text_data = {"Literals": literals_data, "FontSize": font_size}
|
text_data = {"Literals": literals_data, "FontSize": font_size}
|
||||||
cls.data[obj.name] = text_data
|
cls.data[obj.name] = text_data
|
||||||
return 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))
|
box_alignment_offset += Vector((0, h))
|
||||||
else:
|
else:
|
||||||
# middle / center
|
# middle / center
|
||||||
box_alignment_offset += Vector((0, h / 2))
|
box_alignment_offset += Vector((0, h / 2))
|
||||||
|
|
||||||
if "left" in box_alignment:
|
if "left" in box_alignment:
|
||||||
pass
|
pass
|
||||||
@@ -451,7 +451,7 @@ class BaseDecorator:
|
|||||||
else:
|
else:
|
||||||
# middle / center
|
# middle / center
|
||||||
box_alignment_offset += Vector((w / 2, 0))
|
box_alignment_offset += Vector((w / 2, 0))
|
||||||
|
|
||||||
pos -= rotation_matrix.transposed() @ box_alignment_offset
|
pos -= rotation_matrix.transposed() @ box_alignment_offset
|
||||||
else:
|
else:
|
||||||
if center:
|
if center:
|
||||||
@@ -506,6 +506,10 @@ class DimensionDecorator(BaseDecorator):
|
|||||||
DEF_GLSL = (
|
DEF_GLSL = (
|
||||||
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_ANGLE PI / 12.0
|
||||||
#define ARROW_SIZE 16.0
|
#define ARROW_SIZE 16.0
|
||||||
"""
|
"""
|
||||||
@@ -514,10 +518,23 @@ class DimensionDecorator(BaseDecorator):
|
|||||||
GEOM_GLSL = """
|
GEOM_GLSL = """
|
||||||
uniform vec2 winsize;
|
uniform vec2 winsize;
|
||||||
uniform float viewportDrawingScale;
|
uniform float viewportDrawingScale;
|
||||||
|
uniform float use_oblique_style;
|
||||||
|
|
||||||
layout(lines) in;
|
layout(lines) in;
|
||||||
layout(line_strip, max_vertices=MAX_POINTS) out;
|
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() {
|
void main() {
|
||||||
vec4 clip2win = matCLIP2WIN();
|
vec4 clip2win = matCLIP2WIN();
|
||||||
vec4 win2clip = matWIN2CLIP();
|
vec4 win2clip = matWIN2CLIP();
|
||||||
@@ -529,49 +546,78 @@ class DimensionDecorator(BaseDecorator):
|
|||||||
|
|
||||||
vec4 p;
|
vec4 p;
|
||||||
|
|
||||||
vec4 head[3];
|
if (use_oblique_style > 0) {
|
||||||
arrow_head(dir, viewportDrawingScale * ARROW_SIZE, ARROW_ANGLE, head);
|
vec4 head[OBLIQUE_HEAD_VERTS];
|
||||||
|
oblique_dimension_head(dir, viewportDrawingScale * OLBIQUE_SYMBOL_SIZE, OBLIQUE_SYMBOL_ANGLE, head);
|
||||||
|
|
||||||
// start edge arrow
|
// start edge arrow
|
||||||
gl_Position = p0;
|
for (int i = 0; i < OBLIQUE_HEAD_VERTS; i++) {
|
||||||
EmitVertex();
|
gl_Position = WIN2CLIP((p0w + head[i]));
|
||||||
p = p0w + head[1];
|
EmitVertex();
|
||||||
gl_Position = WIN2CLIP(p);
|
}
|
||||||
EmitVertex();
|
EndPrimitive();
|
||||||
p = p0w + head[2];
|
|
||||||
gl_Position = WIN2CLIP(p);
|
|
||||||
EmitVertex();
|
|
||||||
gl_Position = p0;
|
|
||||||
EmitVertex();
|
|
||||||
EndPrimitive();
|
|
||||||
|
|
||||||
// end edge arrow
|
// end edge arrow
|
||||||
gl_Position = p1;
|
for (int i = 0; i < OBLIQUE_HEAD_VERTS; i++) {
|
||||||
EmitVertex();
|
gl_Position = WIN2CLIP((p1w - head[i]));
|
||||||
p = p1w - head[1];
|
EmitVertex();
|
||||||
gl_Position = WIN2CLIP(p);
|
}
|
||||||
EmitVertex();
|
EndPrimitive();
|
||||||
p = p1w - head[2];
|
|
||||||
gl_Position = WIN2CLIP(p);
|
|
||||||
EmitVertex();
|
|
||||||
gl_Position = p1;
|
|
||||||
EmitVertex();
|
|
||||||
EndPrimitive();
|
|
||||||
|
|
||||||
// stem, with gaps for arrows
|
// stem
|
||||||
p = p0w + head[0];
|
gl_Position = p0;
|
||||||
gl_Position = WIN2CLIP(p);
|
EmitVertex();
|
||||||
EmitVertex();
|
gl_Position = p1;
|
||||||
p = p1w - head[0];
|
EmitVertex();
|
||||||
gl_Position = WIN2CLIP(p);
|
EndPrimitive();
|
||||||
EmitVertex();
|
} else {
|
||||||
EndPrimitive();
|
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):
|
def decorate(self, context, obj):
|
||||||
verts, idxs, _ = self.get_path_geom(obj, topo=False)
|
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)
|
self.draw_labels(context, obj, verts, idxs)
|
||||||
|
|
||||||
def draw_labels(self, context, obj, vertices, indices):
|
def draw_labels(self, context, obj, vertices, indices):
|
||||||
@@ -806,7 +852,7 @@ class LeaderDecorator(BaseDecorator):
|
|||||||
|
|
||||||
props = obj.BIMTextProperties
|
props = obj.BIMTextProperties
|
||||||
text_data = props.get_text_edited_data() if props.is_editing else DecoratorData.get_ifc_text_data(obj)
|
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)
|
self.draw_label(context, text, pos, dir, gap=0, center=False, vcenter=False)
|
||||||
|
|
||||||
@@ -1336,11 +1382,11 @@ class PlanLevelDecorator(LevelDecorator):
|
|||||||
dir = p1 - p0
|
dir = p1 - p0
|
||||||
if dir.length < 1:
|
if dir.length < 1:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if dir.x > 0:
|
if dir.x > 0:
|
||||||
box_alignment = "bottom-left"
|
box_alignment = "bottom-left"
|
||||||
else:
|
else:
|
||||||
box_alignment = 'bottom-right'
|
box_alignment = "bottom-right"
|
||||||
dir *= -1
|
dir *= -1
|
||||||
|
|
||||||
z = verts[-1].z / unit_scale
|
z = verts[-1].z / unit_scale
|
||||||
@@ -2098,7 +2144,7 @@ class TextDecorator(BaseDecorator):
|
|||||||
def matrix_only_rotation(m):
|
def matrix_only_rotation(m):
|
||||||
return m.to_3x3().normalized().to_4x4()
|
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 = 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_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()
|
text_dir = (matrix_only_rotation(region3d.perspective_matrix) @ text_dir_world_rotated).to_2d().normalized()
|
||||||
|
|||||||
Reference in New Issue
Block a user