mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 05:52:33 +00:00
Added new angle annotations operator
New operator should be more intuitive to work with. I kept the old one too for now.
This commit is contained in:
@@ -32,6 +32,12 @@ from mathutils import Vector, Matrix
|
|||||||
from bpy_extras.view3d_utils import location_3d_to_region_2d
|
from bpy_extras.view3d_utils import location_3d_to_region_2d
|
||||||
from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertFormat
|
from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertFormat
|
||||||
from gpu_extras.batch import batch_for_shader
|
from gpu_extras.batch import batch_for_shader
|
||||||
|
from math import acos, pi
|
||||||
|
|
||||||
|
|
||||||
|
def ccw(A, B, C):
|
||||||
|
"""whether a-b-c located in counter-clockwise order in 2d space"""
|
||||||
|
return (C.y - A.y) * (B.x - A.x) > (B.y - A.y) * (C.x - A.x)
|
||||||
|
|
||||||
|
|
||||||
class BaseDecorator:
|
class BaseDecorator:
|
||||||
@@ -66,6 +72,42 @@ class BaseDecorator:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_counterclockwise(in vec4 A, in vec4 B, in vec4 C) {
|
||||||
|
return (C.y-A.y) * (B.x-A.x) > (B.y-A.y) * (C.x-A.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void angle_circle_head(
|
||||||
|
in vec4 circle_start, in float circle_angle,
|
||||||
|
in bool counterclockwise,
|
||||||
|
out vec4 head[CIRCLE_SEGS+1], out float angle_segs) {
|
||||||
|
|
||||||
|
// 1 added to CIRCLE_SEGS because we're number of vertices
|
||||||
|
// for n segments is n+1
|
||||||
|
|
||||||
|
float angle_d;
|
||||||
|
angle_d = PI * 2 / CIRCLE_SEGS; // 30d
|
||||||
|
// need to bottom clamp it to 1, otherwise it causes Blender crash at extruding the curve
|
||||||
|
angle_segs = max(1, ceil(circle_angle / angle_d));
|
||||||
|
angle_d = circle_angle / angle_segs;
|
||||||
|
|
||||||
|
for(int i = 0; i < (angle_segs + 1); i++) {
|
||||||
|
float angle = angle_d * i;
|
||||||
|
if (counterclockwise) {
|
||||||
|
head[i] = vec4(
|
||||||
|
circle_start.x * cos(-angle) + circle_start.y * sin(-angle),
|
||||||
|
circle_start.x * -sin(-angle) + circle_start.y * cos(-angle),
|
||||||
|
0, 0
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
head[i] = vec4(
|
||||||
|
circle_start.x * cos(angle) + circle_start.y * sin(angle),
|
||||||
|
circle_start.x * -sin(angle) + circle_start.y * cos(angle),
|
||||||
|
0, 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void cross_head(in vec4 dir, in float size, out vec4 head[3]) {
|
void cross_head(in vec4 dir, in float size, out vec4 head[3]) {
|
||||||
vec4 nose = dir * size;
|
vec4 nose = dir * size;
|
||||||
float c = cos(PI/2), s = sin(PI/2);
|
float c = cos(PI/2), s = sin(PI/2);
|
||||||
@@ -79,12 +121,15 @@ class BaseDecorator:
|
|||||||
uniform mat4 viewMatrix;
|
uniform mat4 viewMatrix;
|
||||||
in vec3 pos;
|
in vec3 pos;
|
||||||
in uint topo;
|
in uint topo;
|
||||||
|
in vec3 next_vert;
|
||||||
out vec4 gl_Position;
|
out vec4 gl_Position;
|
||||||
out uint type;
|
out uint type;
|
||||||
|
out vec4 v_next_vert;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = viewMatrix * vec4(pos, 1.0);
|
gl_Position = viewMatrix * vec4(pos, 1.0);
|
||||||
type = topo;
|
type = topo;
|
||||||
|
v_next_vert = viewMatrix * vec4(next_vert, 1.0);
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -267,7 +312,13 @@ class BaseDecorator:
|
|||||||
"""perform actual drawing stuff"""
|
"""perform actual drawing stuff"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def draw_lines(self, context, obj, vertices, indices, topology=None, is_scale_dependant=True):
|
def draw_lines(
|
||||||
|
self, context, obj, vertices, indices, topology=None, is_scale_dependant=True, fill_next_vertices=False
|
||||||
|
):
|
||||||
|
# use is_scale_dependant = False if shader is not using uniform viewportDrawingScale
|
||||||
|
# otherwise uniform will be discarded during the optimization process
|
||||||
|
# and you will get "ValueError: GPUShader.uniform_float: uniform viewportDrawingScale not found"
|
||||||
|
|
||||||
region = context.region
|
region = context.region
|
||||||
region3d = context.region_data
|
region3d = context.region_data
|
||||||
color = context.scene.DocProperties.decorations_colour
|
color = context.scene.DocProperties.decorations_colour
|
||||||
@@ -276,12 +327,18 @@ class BaseDecorator:
|
|||||||
fmt.attr_add(id="pos", comp_type="F32", len=3, fetch_mode="FLOAT")
|
fmt.attr_add(id="pos", comp_type="F32", len=3, fetch_mode="FLOAT")
|
||||||
if topology:
|
if topology:
|
||||||
fmt.attr_add(id="topo", comp_type="U8", len=1, fetch_mode="INT")
|
fmt.attr_add(id="topo", comp_type="U8", len=1, fetch_mode="INT")
|
||||||
|
if fill_next_vertices:
|
||||||
|
fmt.attr_add(id="next_vert", comp_type="F32", len=3, fetch_mode="FLOAT")
|
||||||
|
|
||||||
vbo = GPUVertBuf(len=len(vertices), format=fmt)
|
vbo = GPUVertBuf(len=len(vertices), format=fmt)
|
||||||
vbo.attr_fill(id="pos", data=vertices)
|
vbo.attr_fill(id="pos", data=vertices)
|
||||||
if topology:
|
if topology:
|
||||||
vbo.attr_fill(id="topo", data=topology)
|
vbo.attr_fill(id="topo", data=topology)
|
||||||
|
|
||||||
|
if fill_next_vertices:
|
||||||
|
shifted_vertices = vertices[1:] + [vertices[0]]
|
||||||
|
vbo.attr_fill(id="next_vert", data=shifted_vertices)
|
||||||
|
|
||||||
ibo = GPUIndexBuf(type="LINES", seq=indices)
|
ibo = GPUIndexBuf(type="LINES", seq=indices)
|
||||||
|
|
||||||
batch = GPUBatch(type="LINES", buf=vbo, elem=ibo)
|
batch = GPUBatch(type="LINES", buf=vbo, elem=ibo)
|
||||||
@@ -480,6 +537,132 @@ class DimensionDecorator(BaseDecorator):
|
|||||||
self.draw_label(context, text, p0 + (dir) * 0.5, dir)
|
self.draw_label(context, text, p0 + (dir) * 0.5, dir)
|
||||||
|
|
||||||
|
|
||||||
|
class AngleDecorator(BaseDecorator):
|
||||||
|
"""Decorator for angle objects
|
||||||
|
- each edge of a segment with arrow
|
||||||
|
- every non-last edge has angle circle
|
||||||
|
- every circle is labeled with angle in degrees
|
||||||
|
"""
|
||||||
|
|
||||||
|
objecttype = "ANGLE"
|
||||||
|
|
||||||
|
DEF_GLSL = (
|
||||||
|
BaseDecorator.DEF_GLSL
|
||||||
|
+ """
|
||||||
|
#define ARROW_ANGLE PI / 12.0
|
||||||
|
#define ARROW_SIZE 8.0
|
||||||
|
#define CIRCLE_SIZE 6.0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
GEOM_GLSL = """
|
||||||
|
uniform vec2 winsize;
|
||||||
|
uniform float viewportDrawingScale;
|
||||||
|
|
||||||
|
layout(lines) in;
|
||||||
|
layout(line_strip, max_vertices=MAX_POINTS) out;
|
||||||
|
in uint type[];
|
||||||
|
in vec4 v_next_vert[];
|
||||||
|
|
||||||
|
// per edge shader
|
||||||
|
void main() {
|
||||||
|
vec4 clip2win = matCLIP2WIN();
|
||||||
|
vec4 win2clip = matWIN2CLIP();
|
||||||
|
|
||||||
|
vec4 p0 = gl_in[0].gl_Position, p1 = gl_in[1].gl_Position;
|
||||||
|
vec4 p2 = v_next_vert[1];
|
||||||
|
uint t0 = type[0], t1 = type[1];
|
||||||
|
|
||||||
|
vec4 p0w = CLIP2WIN(p0), p1w = CLIP2WIN(p1);
|
||||||
|
vec4 p2w = CLIP2WIN(p2);
|
||||||
|
vec4 edge0 = p1w - p0w, dir = normalize(edge0);
|
||||||
|
|
||||||
|
vec4 p;
|
||||||
|
// draw a segment line
|
||||||
|
p = p0w;
|
||||||
|
gl_Position = WIN2CLIP(p);
|
||||||
|
EmitVertex();
|
||||||
|
p = p1w;
|
||||||
|
gl_Position = WIN2CLIP(p);
|
||||||
|
EmitVertex();
|
||||||
|
EndPrimitive();
|
||||||
|
|
||||||
|
// end edge with angle circle for the non-last segment
|
||||||
|
if (t1 == 0u) { // draws only on internal vertex
|
||||||
|
edge0 = p0w - p1w;
|
||||||
|
vec4 dir0 = normalize(edge0);
|
||||||
|
vec4 edge1 = p2w - p1w;
|
||||||
|
vec4 dir1 = normalize(edge1);
|
||||||
|
|
||||||
|
float angle_circle_size = min( length(edge0), length(edge1) );
|
||||||
|
vec4 circle_start = dir0 * angle_circle_size;
|
||||||
|
vec4 circle_end = dir1 * angle_circle_size;
|
||||||
|
|
||||||
|
float cos_a = dot( edge0, edge1 ) / ( length(edge0) * length(edge1) );
|
||||||
|
float circle_angle = acos(cos_a);
|
||||||
|
|
||||||
|
vec4 circle_head_data[CIRCLE_SEGS+1];
|
||||||
|
float angle_segs;
|
||||||
|
bool counterclockwise = check_counterclockwise(p2w, p1w, p0w);
|
||||||
|
angle_circle_head(
|
||||||
|
circle_start,
|
||||||
|
circle_angle,
|
||||||
|
counterclockwise,
|
||||||
|
circle_head_data,
|
||||||
|
angle_segs);
|
||||||
|
|
||||||
|
for(int i=0; i<angle_segs+1; i++) {
|
||||||
|
p = p1w + circle_head_data[i];
|
||||||
|
gl_Position = WIN2CLIP(p);
|
||||||
|
EmitVertex();
|
||||||
|
}
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
def decorate(self, context, obj):
|
||||||
|
verts, idxs, topo = self.get_path_geom(obj)
|
||||||
|
self.draw_lines(context, obj, verts, idxs, topo, fill_next_vertices=True, is_scale_dependant=False)
|
||||||
|
self.draw_labels(context, obj, verts, idxs)
|
||||||
|
|
||||||
|
def draw_labels(self, context, obj, vertices, indices):
|
||||||
|
region = context.region
|
||||||
|
region3d = context.region_data
|
||||||
|
|
||||||
|
last_segment_i = len(indices) - 1
|
||||||
|
for edge_i, edge_vertices in enumerate(indices):
|
||||||
|
if edge_i == last_segment_i:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# draw angle label
|
||||||
|
i0, i1 = edge_vertices
|
||||||
|
v0 = Vector(vertices[i0])
|
||||||
|
v1 = Vector(vertices[i1])
|
||||||
|
v2 = Vector(vertices[i1 + 1])
|
||||||
|
p0 = location_3d_to_region_2d(region, region3d, v0)
|
||||||
|
p1 = location_3d_to_region_2d(region, region3d, v1)
|
||||||
|
p2 = location_3d_to_region_2d(region, region3d, v2)
|
||||||
|
|
||||||
|
edge0 = p0 - p1
|
||||||
|
edge1 = p2 - p1
|
||||||
|
cos_a = edge0.dot(edge1) / (edge0.length * edge1.length)
|
||||||
|
circle_angle = acos(cos_a) / pi * 180
|
||||||
|
|
||||||
|
text = f"{int(circle_angle)}d"
|
||||||
|
|
||||||
|
# TODO: set label position pased on p1
|
||||||
|
# + y relative to p0p1 if p0p1p2 is clockwise
|
||||||
|
# - y relative to p0p1 if p0p1p2 is counter-clockwise
|
||||||
|
# counter_clockwise = ccw(p0, p1, p2)
|
||||||
|
# label_position = (p1 + Vector( (0, 10) ) * (1 if counter_clockwise else -1)) + edge1 * 0.1
|
||||||
|
label_position = p1 + edge1 * 0.1
|
||||||
|
|
||||||
|
# TODO: set label direction based on the first edge (p0, p1)
|
||||||
|
label_dir = Vector((1, 0))
|
||||||
|
self.draw_label(context, text, label_position, label_dir)
|
||||||
|
|
||||||
|
|
||||||
class DiameterDecorator(DimensionDecorator):
|
class DiameterDecorator(DimensionDecorator):
|
||||||
objecttype = "DIAMETER"
|
objecttype = "DIAMETER"
|
||||||
|
|
||||||
@@ -895,7 +1078,6 @@ class LevelDecorator(BaseDecorator):
|
|||||||
def decorate(self, context, obj):
|
def decorate(self, context, obj):
|
||||||
verts, idxs, topo = self.get_path_geom(obj)
|
verts, idxs, topo = self.get_path_geom(obj)
|
||||||
self.draw_lines(context, obj, verts, idxs, topo)
|
self.draw_lines(context, obj, verts, idxs, topo)
|
||||||
splines = self.get_splines(obj)
|
|
||||||
self.draw_labels(context, obj, splines)
|
self.draw_labels(context, obj, splines)
|
||||||
|
|
||||||
|
|
||||||
@@ -1585,6 +1767,7 @@ class TextDecorator(BaseDecorator):
|
|||||||
class DecorationsHandler:
|
class DecorationsHandler:
|
||||||
decorators_classes = [
|
decorators_classes = [
|
||||||
DimensionDecorator,
|
DimensionDecorator,
|
||||||
|
AngleDecorator,
|
||||||
GridDecorator,
|
GridDecorator,
|
||||||
HiddenDecorator,
|
HiddenDecorator,
|
||||||
LeaderDecorator,
|
LeaderDecorator,
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import blenderbim.bim.module.drawing.annotation as annotation
|
|||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
from mathutils import geometry
|
from mathutils import geometry
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
from bpy_extras import view3d_utils
|
||||||
|
|
||||||
|
|
||||||
class External(svgwrite.container.Group):
|
class External(svgwrite.container.Group):
|
||||||
@@ -140,6 +141,8 @@ class SvgWriter:
|
|||||||
self.draw_dimension_annotations(obj)
|
self.draw_dimension_annotations(obj)
|
||||||
elif element.ObjectType == "ANGLE":
|
elif element.ObjectType == "ANGLE":
|
||||||
self.draw_angle_annotations(obj)
|
self.draw_angle_annotations(obj)
|
||||||
|
elif element.ObjectType == "ANGLE_OLD":
|
||||||
|
self.draw_angle_old_annotations(obj)
|
||||||
elif element.ObjectType == "RADIUS":
|
elif element.ObjectType == "RADIUS":
|
||||||
self.draw_radius_annotations(obj)
|
self.draw_radius_annotations(obj)
|
||||||
elif element.ObjectType == "DIAMETER":
|
elif element.ObjectType == "DIAMETER":
|
||||||
@@ -619,19 +622,52 @@ class SvgWriter:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def draw_angle_annotations(self, obj):
|
def draw_angle_annotations(self, obj):
|
||||||
|
# calculate p3 which is the center of the arc
|
||||||
|
# to use draw_svg_3point_arc()
|
||||||
|
points = obj.data.splines[0].points
|
||||||
|
region = bpy.context.region
|
||||||
|
region_3d = bpy.context.area.spaces.active.region_3d
|
||||||
|
points_2d = [view3d_utils.location_3d_to_region_2d(region, region_3d, p.co.xyz) for p in points]
|
||||||
|
|
||||||
|
edge0 = points_2d[0] - points_2d[1]
|
||||||
|
edge1 = points_2d[2] - points_2d[1]
|
||||||
|
angle_radius = min(edge0.length, edge1.length)
|
||||||
|
dir0 = edge0.normalized()
|
||||||
|
dir1 = edge1.normalized()
|
||||||
|
dir2 = ((dir0 + dir1) / 2).normalized()
|
||||||
|
|
||||||
|
p3 = points_2d[1] + dir2 * angle_radius
|
||||||
|
|
||||||
|
# make all edges the same radius
|
||||||
|
p0 = points_2d[1] + dir0 * angle_radius
|
||||||
|
p2 = points_2d[1] + dir1 * angle_radius
|
||||||
|
points = [view3d_utils.region_2d_to_origin_3d(region, region_3d, p) for p in [p0, p3, p2]]
|
||||||
|
# points = [p.co.xyz for p in bpy.context.object.data.splines[0].points[:3]]
|
||||||
|
|
||||||
|
bm = bmesh.new()
|
||||||
|
bm.verts.index_update()
|
||||||
|
bm.edges.index_update()
|
||||||
|
new_verts = [bm.verts.new(p) for p in points]
|
||||||
|
new_edges = [bm.edges.new( (new_verts[e[0]], new_verts[e[1]]) ) for e in ((0, 1), (1, 2))]
|
||||||
|
self.draw_svg_3point_arc(obj, bm)
|
||||||
|
|
||||||
|
def draw_angle_old_annotations(self, obj):
|
||||||
|
bm = bmesh.new()
|
||||||
|
bm.from_mesh(obj.data)
|
||||||
|
bm.verts.ensure_lookup_table()
|
||||||
|
self.draw_svg_3point_arc(obj, bm)
|
||||||
|
|
||||||
|
def draw_svg_3point_arc(self, obj, bm):
|
||||||
# This implementation uses an SVG arc, which means that it can only draw
|
# This implementation uses an SVG arc, which means that it can only draw
|
||||||
# arcs that are orthogonal to the view (e.g. not arcs in 3D).
|
# arcs that are orthogonal to the view (e.g. not arcs in 3D).
|
||||||
# Gosh this is bad code :(
|
# Gosh this is bad code :(
|
||||||
x_offset = self.raw_width / 2
|
|
||||||
y_offset = self.raw_height / 2
|
points = [v.co for v in bm.verts][:3]
|
||||||
|
center = tool.Cad.get_center_of_arc(points, obj)
|
||||||
classes = self.get_attribute_classes(obj)
|
classes = self.get_attribute_classes(obj)
|
||||||
matrix_world = obj.matrix_world
|
matrix_world = obj.matrix_world
|
||||||
|
x_offset = self.raw_width / 2
|
||||||
points = [v.co for v in obj.data.vertices][:3]
|
y_offset = self.raw_height / 2
|
||||||
center = tool.Cad.get_center_of_arc(points, obj)
|
|
||||||
|
|
||||||
bm = bmesh.new()
|
|
||||||
bm.from_mesh(obj.data)
|
|
||||||
bm.verts.ensure_lookup_table()
|
bm.verts.ensure_lookup_table()
|
||||||
arc_end_verts = [v for v in bm.verts if len(v.link_edges) == 1]
|
arc_end_verts = [v for v in bm.verts if len(v.link_edges) == 1]
|
||||||
arc_end_pts = [matrix_world @ v.co for v in arc_end_verts]
|
arc_end_pts = [matrix_world @ v.co for v in arc_end_verts]
|
||||||
@@ -680,11 +716,11 @@ class SvgWriter:
|
|||||||
|
|
||||||
# Center of gravity of all vertices, used to help position the text
|
# Center of gravity of all vertices, used to help position the text
|
||||||
cog = Vector((0, 0, 0))
|
cog = Vector((0, 0, 0))
|
||||||
for vert in obj.data.vertices:
|
for point in points:
|
||||||
cog += vert.co
|
cog += point
|
||||||
cog = matrix_world @ (cog / len(obj.data.vertices))
|
cog = matrix_world @ (cog / len(points))
|
||||||
|
|
||||||
radius = ((matrix_world @ obj.data.vertices[0].co) - center).length
|
radius = ((matrix_world @ points[0]) - center).length
|
||||||
|
|
||||||
arc_midpoint = center + ((cog - center).normalized() * radius)
|
arc_midpoint = center + ((cog - center).normalized() * radius)
|
||||||
|
|
||||||
|
|||||||
@@ -171,10 +171,10 @@ class BIM_PT_drawings(Panel):
|
|||||||
active_drawing = self.props.drawings[self.props.active_drawing_index]
|
active_drawing = self.props.drawings[self.props.active_drawing_index]
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
col = row.column()
|
col = row.column()
|
||||||
col.alignment = 'LEFT'
|
col.alignment = "LEFT"
|
||||||
col.operator("bim.remove_drawing", icon="X", text="").drawing = active_drawing.ifc_definition_id
|
col.operator("bim.remove_drawing", icon="X", text="").drawing = active_drawing.ifc_definition_id
|
||||||
col = row.column()
|
col = row.column()
|
||||||
col.alignment = 'RIGHT'
|
col.alignment = "RIGHT"
|
||||||
op = row.operator("bim.open_view", icon="URL", text="")
|
op = row.operator("bim.open_view", icon="URL", text="")
|
||||||
op.view = active_drawing.name
|
op.view = active_drawing.name
|
||||||
op = row.operator("bim.activate_view", icon="OUTLINER_OB_CAMERA", text="")
|
op = row.operator("bim.activate_view", icon="OUTLINER_OB_CAMERA", text="")
|
||||||
@@ -376,6 +376,9 @@ class BIM_PT_annotation_utilities(Panel):
|
|||||||
op.data_type = "curve"
|
op.data_type = "curve"
|
||||||
op = row.operator("bim.add_annotation", text="Angle", icon="DRIVER_ROTATIONAL_DIFFERENCE")
|
op = row.operator("bim.add_annotation", text="Angle", icon="DRIVER_ROTATIONAL_DIFFERENCE")
|
||||||
op.object_type = "ANGLE"
|
op.object_type = "ANGLE"
|
||||||
|
op.data_type = "curve"
|
||||||
|
op = row.operator("bim.add_annotation", text="Angle (old)", icon="DRIVER_ROTATIONAL_DIFFERENCE")
|
||||||
|
op.object_type = "ANGLE_OLD"
|
||||||
op.data_type = "mesh"
|
op.data_type = "mesh"
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ class DumbSlabGenerator:
|
|||||||
matrix_world[2][3] = self.collection_obj.location[2] - self.depth
|
matrix_world[2][3] = self.collection_obj.location[2] - self.depth
|
||||||
else:
|
else:
|
||||||
matrix_world[2][3] -= self.depth
|
matrix_world[2][3] -= self.depth
|
||||||
obj.matrix_world = Matrix.Rotation(self.x_angle, 4, 'X') @ matrix_world
|
obj.matrix_world = Matrix.Rotation(self.x_angle, 4, "X") @ matrix_world
|
||||||
bpy.context.view_layer.update()
|
bpy.context.view_layer.update()
|
||||||
self.collection.objects.link(obj)
|
self.collection.objects.link(obj)
|
||||||
|
|
||||||
@@ -651,6 +651,7 @@ class EditExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
profile = tool.Model.export_profile(obj, position=position)
|
profile = tool.Model.export_profile(obj, position=position)
|
||||||
|
|
||||||
if not profile:
|
if not profile:
|
||||||
|
|
||||||
def msg(self, context):
|
def msg(self, context):
|
||||||
self.layout.label(text="INVALID PROFILE: " + indices[1])
|
self.layout.label(text="INVALID PROFILE: " + indices[1])
|
||||||
|
|
||||||
@@ -784,7 +785,7 @@ class DecorationsHandler:
|
|||||||
special_vertex_indices = {}
|
special_vertex_indices = {}
|
||||||
selected_edges = []
|
selected_edges = []
|
||||||
unselected_edges = []
|
unselected_edges = []
|
||||||
special_edges = []
|
special_edges = [] # edges that have a circle or an arc associated with them
|
||||||
|
|
||||||
arc_groups = []
|
arc_groups = []
|
||||||
circle_groups = []
|
circle_groups = []
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ class Drawing(blenderbim.core.tool.Drawing):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def create_annotation_object(cls, drawing, object_type):
|
def create_annotation_object(cls, drawing, object_type):
|
||||||
data_type = {
|
data_type = {
|
||||||
"ANGLE": "mesh",
|
"ANGLE": "curve",
|
||||||
|
"ANGLE_OLD": "mesh",
|
||||||
"BREAKLINE": "mesh",
|
"BREAKLINE": "mesh",
|
||||||
"DIAMETER": "curve",
|
"DIAMETER": "curve",
|
||||||
"DIMENSION": "curve",
|
"DIMENSION": "curve",
|
||||||
|
|||||||
Reference in New Issue
Block a user