diff --git a/src/blenderbim/blenderbim/bim/module/drawing/decoration.py b/src/blenderbim/blenderbim/bim/module/drawing/decoration.py index 94ab57d4e3..3660275a5e 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/decoration.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/decoration.py @@ -1125,6 +1125,101 @@ class GridDecorator(BaseDecorator): self.draw_label(context, text, p1, dir, vcenter=True, gap=0) +class ElevationDecorator(LevelDecorator): + objecttype = "ELEVATION" + + DEF_GLSL = ( + BaseDecorator.DEF_GLSL + + """ + #define CIRCLE_SIZE 8.0 + #define TRIANGLE_L 22.63 + #define TRIANGLE_W 11.31 + """ + ) + + GEOM_GLSL = """ + uniform vec2 winsize; + uniform float viewportDrawingScale; + + layout(lines) in; + layout(line_strip, max_vertices=MAX_POINTS) out; + + void triangle_head(in vec4 side, in vec4 dir, in float length, in float width, in float radius, out vec4 head[5]) { + vec4 nose = side * length; + vec4 ear = dir * width; + head[0] = side * -radius; + head[1] = nose * -.5; + head[2] = vec4(0) + ear; + head[3] = nose * .5; + head[4] = side * radius; + } + + void main() { + vec4 clip2win = matCLIP2WIN(); + vec4 win2clip = matWIN2CLIP(); + + vec4 p0 = gl_in[0].gl_Position, p1 = gl_in[1].gl_Position; + + vec4 p0w = CLIP2WIN(p0), p1w = CLIP2WIN(p1); + vec4 edge = p1w - p0w, dir = normalize(edge); + // vec4 dir = normalize(vec4(1, 0, 0, 0)); + vec4 gap = dir * viewportDrawingScale * TRIANGLE_L * .5; + vec4 side = vec4(cross(vec3(dir.xy, 0), vec3(0, 0, 1)).xy, 0, 0); + vec4 p; + + vec4 head[CIRCLE_SEGS]; + circle_head(viewportDrawingScale * CIRCLE_SIZE, head); + + vec4 head3[5]; + + // start edge circle + for(int i=0; i raster_y: + width = obj.data.ortho_scale + height = width / raster_x * raster_y + else: + height = obj.data.ortho_scale + width = height / raster_y * raster_x + depth = obj.data.clip_end + + verts = ( + obj.matrix_world @ mathutils.Vector((-width / 2, -height /2, -depth)), + obj.matrix_world @ mathutils.Vector((-width / 2, -height /2, 0)), + obj.matrix_world @ mathutils.Vector((-width / 2, height /2, -depth)), + obj.matrix_world @ mathutils.Vector((-width / 2, height /2, 0)), + obj.matrix_world @ mathutils.Vector((width / 2, -height /2, -depth)), + obj.matrix_world @ mathutils.Vector((width / 2, -height /2, 0)), + obj.matrix_world @ mathutils.Vector((width / 2, height /2, -depth)), + obj.matrix_world @ mathutils.Vector((width / 2, height /2, 0)) + ) + faces = [ + [0, 1, 3, 2], + [2, 3, 7, 6], + [6, 7, 5, 4], + [4, 5, 1, 0], + [2, 6, 4, 0], + [7, 3, 1, 5], + ] + return {"verts": verts, "faces": faces} + + def is_intersecting(a, b): + a_block = get_camera_block(a) + a_tree = mathutils.bvhtree.BVHTree.FromPolygons(a_block["verts"], a_block["faces"]) + b_block = get_camera_block(b) + b_tree = mathutils.bvhtree.BVHTree.FromPolygons(b_block["verts"], b_block["faces"]) + return bool(a_tree.overlap(b_tree)) + + def to_camera_coords(camera, reference_obj): + mat = reference_obj.matrix_world.copy() + xyz = camera.matrix_world.inverted() @ reference_obj.matrix_world.translation + xyz[2] = 0 + xyz = camera.matrix_world @ xyz + mat[0][3] = xyz[0] + mat[1][3] = xyz[1] + mat[2][3] = xyz[2] + annotation_offset = mathutils.Vector((0, 0, -camera.data.clip_start)) + annotation_offset = camera.matrix_world.to_quaternion() @ annotation_offset + mat[0][3] += annotation_offset[0] + mat[1][3] += annotation_offset[1] + mat[2][3] += annotation_offset[2] + return mat + + if is_perpendicular(camera, reference_obj) and is_intersecting(camera, reference_obj): + obj = bpy.data.objects.new(reference_obj.name, None) + obj.empty_display_size = 0.1 + obj.matrix_world = to_camera_coords(camera, reference_obj) + + element = cls.run_root_assign_class( + obj=obj, + ifc_class="IfcAnnotation", + predefined_type="ELEVATION", + should_add_representation=False, + context=context, + ifc_representation_class=None, + ) + return element @classmethod def generate_grid_axis_reference_annotation(cls, drawing, reference_element, context):