#1153 Storey level annotations are now automatically generated for sections and elevations

This commit is contained in:
Dion Moult
2022-04-22 12:41:21 +10:00
parent a66ba6a6f9
commit 0c06c67f2d
4 changed files with 70 additions and 65 deletions
@@ -47,7 +47,6 @@ classes = (
operator.EnableEditingText,
operator.EnableEditingTextProduct,
operator.ExpandSheet,
operator.GenerateReferences,
operator.LoadDrawings,
operator.LoadSheets,
operator.OpenSheet,
@@ -738,68 +738,6 @@ class SelectDocIfcFile(bpy.types.Operator):
return {"RUNNING_MODAL"}
class GenerateReferences(bpy.types.Operator):
bl_idname = "bim.generate_references"
bl_label = "Generate References"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
self.camera = context.scene.camera
self.filter_potential_references()
if self.camera.data.BIMCameraProperties.target_view == "PLAN_VIEW":
self.generate_grids()
if self.camera.data.BIMCameraProperties.target_view == "ELEVATION_VIEW":
self.generate_grids()
self.generate_levels(context)
if self.camera.data.BIMCameraProperties.target_view == "SECTION_VIEW":
self.generate_grids()
self.generate_levels(context)
return {"FINISHED"}
def filter_potential_references(self):
for name in ["grids", "levels"]:
setattr(self, name, [])
for obj in bpy.data.objects:
if "IfcGridAxis/" in obj.name:
self.grids.append(obj)
if "IfcBuildingStorey/" in obj.name:
self.levels.append(obj)
def generate_grids(self):
# TODO
pass
def generate_levels(self, context):
if self.camera.data.BIMCameraProperties.raster_x > self.camera.data.BIMCameraProperties.raster_y:
width = self.camera.data.ortho_scale
height = (
width / self.camera.data.BIMCameraProperties.raster_x * self.camera.data.BIMCameraProperties.raster_y
)
else:
height = self.camera.data.ortho_scale
width = (
height / self.camera.data.BIMCameraProperties.raster_y * self.camera.data.BIMCameraProperties.raster_x
)
level_obj = annotation.Annotator.get_annotation_obj("Section Level", "curve", context)
width_in_mm = width * 1000
real_world_width_in_mm = width_in_mm * scale
offset_in_mm = 20
offset_percentage = offset_in_mm / real_world_width_in_mm
for obj in self.levels:
projection = self.project_point_onto_camera(obj.location)
co1 = self.camera.matrix_world @ Vector((width / 2 - (offset_percentage * width), projection[1], -1))
co2 = self.camera.matrix_world @ Vector((-(width / 2), projection[1], -1))
annotation.Annotator.add_line_to_annotation(level_obj, context, co1, co2)
def project_point_onto_camera(self, point):
projection = self.camera.matrix_world.to_quaternion() @ Vector((0, 0, -1))
return self.camera.matrix_world.inverted() @ geometry.intersect_line_plane(
point.xyz, point.xyz - projection, self.camera.location, projection
)
class ResizeText(bpy.types.Operator):
bl_idname = "bim.resize_text"
bl_label = "Resize Text"
@@ -62,8 +62,6 @@ class BIM_PT_camera(Panel):
row = layout.row()
row.prop(props, "is_nts")
row = layout.row()
row.operator("bim.generate_references")
row = layout.row()
row.operator("bim.resize_text")
+70
View File
@@ -408,6 +408,10 @@ class Drawing(blenderbim.core.tool.Drawing):
elements.append(element)
for element in tool.Ifc.get().by_type("IfcGridAxis"):
elements.append(element)
target_view = tool.Drawing.get_drawing_target_view(drawing)
if target_view in ("SECTION_VIEW", "ELEVATION_VIEW"):
for element in tool.Ifc.get().by_type("IfcBuildingStorey"):
elements.append(element)
return elements
@classmethod
@@ -437,6 +441,72 @@ class Drawing(blenderbim.core.tool.Drawing):
return cls.generate_elevation_reference_annotation(drawing, reference_element, context)
elif target_view == "SECTION_VIEW":
return cls.generate_section_reference_annotation(drawing, reference_element, context)
elif reference_element.is_a("IfcBuildingStorey"):
return cls.generate_storey_annotation(drawing, reference_element, context)
@classmethod
def generate_storey_annotation(cls, drawing, reference_element, context):
camera = tool.Ifc.get_object(drawing)
bounds = helper.ortho_view_frame(camera.data) if camera.data.type == "ORTHO" else None
reference_obj = tool.Ifc.get_object(reference_element)
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 - 0.05))
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
def project_point_onto_camera(point, camera):
projection = camera.matrix_world.to_quaternion() @ mathutils.Vector((0, 0, -1))
return camera.matrix_world.inverted() @ mathutils.geometry.intersect_line_plane(
point.xyz, point.xyz - projection, camera.location, projection
)
obj_matrix = to_camera_coords(camera, reference_obj)
if camera.data.BIMCameraProperties.raster_x > camera.data.BIMCameraProperties.raster_y:
width = camera.data.ortho_scale
height = width / camera.data.BIMCameraProperties.raster_x * camera.data.BIMCameraProperties.raster_y
else:
height = camera.data.ortho_scale
width = height / camera.data.BIMCameraProperties.raster_y * camera.data.BIMCameraProperties.raster_x
projection = project_point_onto_camera(reference_obj.location, camera)
co1 = camera.matrix_world @ mathutils.Vector((width / 2, projection[1], -1))
co2 = camera.matrix_world @ mathutils.Vector((-(width / 2), projection[1], -1))
co1 = obj_matrix.inverted() @ co1
co2 = obj_matrix.inverted() @ co2
data = bpy.data.curves.new("Annotation", type="CURVE")
data.dimensions = "3D"
data.resolution_u = 2
polyline = data.splines.new("POLY")
polyline.points.add(1)
polyline.points[-2].co = list(co1) + [1]
polyline.points[-1].co = list(co2) + [1]
obj = bpy.data.objects.new(reference_obj.name, data)
obj.matrix_world = obj_matrix
element = cls.run_root_assign_class(
obj=obj,
ifc_class="IfcAnnotation",
predefined_type="SECTION_LEVEL",
should_add_representation=True,
context=context,
ifc_representation_class=None,
)
return element
@classmethod
def generate_section_reference_annotation(cls, drawing, reference_element, context):