Minor things for drawing profiling and a warning

This commit is contained in:
Thomas Krijnen
2022-06-21 12:14:15 +02:00
committed by Dion Moult
parent 4978a67e19
commit 104cabfb67
2 changed files with 92 additions and 67 deletions
@@ -41,6 +41,7 @@ import blenderbim.bim.module.drawing.helper as helper
import blenderbim.bim.export_ifc import blenderbim.bim.export_ifc
from lxml import etree from lxml import etree
from mathutils import Vector from mathutils import Vector
from timeit import default_timer as timer
from blenderbim.bim.module.drawing.prop import RasterStyleProperty from blenderbim.bim.module.drawing.prop import RasterStyleProperty
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.group.data import Data as GroupData from ifcopenshell.api.group.data import Data as GroupData
@@ -49,6 +50,21 @@ from ifcopenshell.api.pset.data import Data as PsetData
cwd = os.path.dirname(os.path.realpath(__file__)) cwd = os.path.dirname(os.path.realpath(__file__))
class profile:
"""
A python context manager timing utility
"""
def __init__(self, task):
self.task = task
def __enter__(self):
self.start = timer()
def __exit__(self, *args):
print(self.task, timer() - self.start)
def open_with_user_command(user_command, path): def open_with_user_command(user_command, path):
if user_command: if user_command:
commands = eval(user_command) commands = eval(user_command)
@@ -115,9 +131,10 @@ class CreateDrawing(bpy.types.Operator):
self.camera = context.scene.camera self.camera = context.scene.camera
self.camera_element = tool.Ifc.get_entity(self.camera) self.camera_element = tool.Ifc.get_entity(self.camera)
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
self.time = None
start = time.time() with profile("Drawing generation process"):
self.profile_code("Start drawing generation process")
with profile("Initialize drawing generation process"):
self.props = context.scene.DocProperties self.props = context.scene.DocProperties
self.cprops = self.camera.data.BIMCameraProperties self.cprops = self.camera.data.BIMCameraProperties
self.drawing_name = self.file.by_id(self.camera.BIMObjectProperties.ifc_definition_id).Name self.drawing_name = self.file.by_id(self.camera.BIMObjectProperties.ifc_definition_id).Name
@@ -133,16 +150,20 @@ class CreateDrawing(bpy.types.Operator):
self.svg_writer.camera_width, self.svg_writer.camera_height = self.get_camera_dimensions() self.svg_writer.camera_width, self.svg_writer.camera_height = self.get_camera_dimensions()
self.svg_writer.camera_projection = tuple(self.camera.matrix_world.to_quaternion() @ Vector((0, 0, -1))) self.svg_writer.camera_projection = tuple(self.camera.matrix_world.to_quaternion() @ Vector((0, 0, -1)))
with profile("Generate underlay"):
underlay_svg = self.generate_underlay(context) underlay_svg = self.generate_underlay(context)
self.profile_code("Generate underlay")
with profile("Generate linework"):
linework_svg = self.generate_linework(context) linework_svg = self.generate_linework(context)
self.profile_code("Generate linework")
with profile("Generate annotation"):
annotation_svg = self.generate_annotation(context) annotation_svg = self.generate_annotation(context)
self.profile_code("Generate annotation")
with profile("Combine SVG layers"):
svg_path = self.combine_svgs(context, underlay_svg, linework_svg, annotation_svg) svg_path = self.combine_svgs(context, underlay_svg, linework_svg, annotation_svg)
self.profile_code("Combine SVG layers")
open_with_user_command(context.preferences.addons["blenderbim"].preferences.svg_command, svg_path) open_with_user_command(context.preferences.addons["blenderbim"].preferences.svg_command, svg_path)
print("Total Time: {:.2f}".format(time.time() - start))
return {"FINISHED"} return {"FINISHED"}
def get_camera_dimensions(self): def get_camera_dimensions(self):
@@ -155,12 +176,6 @@ class CreateDrawing(bpy.types.Operator):
width = height / render.resolution_y * render.resolution_x width = height / render.resolution_y * render.resolution_x
return width, height return width, height
def profile_code(self, message):
if not self.time:
self.time = time.time()
print("{} :: {:.2f}".format(message, time.time() - self.time))
self.time = time.time()
def combine_svgs(self, context, underlay, linework, annotation): def combine_svgs(self, context, underlay, linework, annotation):
# Hacky :) # Hacky :)
svg_path = os.path.join(context.scene.BIMProperties.data_dir, "diagrams", self.drawing_name + ".svg") svg_path = os.path.join(context.scene.BIMProperties.data_dir, "diagrams", self.drawing_name + ".svg")
@@ -255,6 +270,7 @@ class CreateDrawing(bpy.types.Operator):
if os.path.isfile(svg_path) and self.props.should_use_linework_cache: if os.path.isfile(svg_path) and self.props.should_use_linework_cache:
return svg_path return svg_path
with profile("sync"):
# All very hackish whilst prototyping # All very hackish whilst prototyping
exporter = blenderbim.bim.export_ifc.IfcExporter(None) exporter = blenderbim.bim.export_ifc.IfcExporter(None)
exporter.file = tool.Ifc.get() exporter.file = tool.Ifc.get()
@@ -312,6 +328,7 @@ class CreateDrawing(bpy.types.Operator):
cache = IfcStore.get_cache() cache = IfcStore.get_cache()
[cache.remove(guid) for guid in invalidated_guids] [cache.remove(guid) for guid in invalidated_guids]
with profile("Processing target view context"):
if target_view_contexts and elements: if target_view_contexts and elements:
geom_settings = ifcopenshell.geom.settings( geom_settings = ifcopenshell.geom.settings(
DISABLE_TRIANGULATION=True, STRICT_TOLERANCE=True, INCLUDE_CURVES=True DISABLE_TRIANGULATION=True, STRICT_TOLERANCE=True, INCLUDE_CURVES=True
@@ -325,6 +342,7 @@ class CreateDrawing(bpy.types.Operator):
self.serialiser.write(elem) self.serialiser.write(elem)
elements -= processed elements -= processed
with profile("Processing body context"):
if body_contexts and elements: if body_contexts and elements:
geom_settings = ifcopenshell.geom.settings(DISABLE_TRIANGULATION=True, STRICT_TOLERANCE=True) geom_settings = ifcopenshell.geom.settings(DISABLE_TRIANGULATION=True, STRICT_TOLERANCE=True)
geom_settings.set_context_ids(body_contexts) geom_settings.set_context_ids(body_contexts)
@@ -333,14 +351,18 @@ class CreateDrawing(bpy.types.Operator):
for elem in self.yield_from_iterator(it): for elem in self.yield_from_iterator(it):
self.serialiser.write(elem) self.serialiser.write(elem)
with profile("Camera element"):
# @todo tfk: is this needed?
geom_settings = ifcopenshell.geom.settings(DISABLE_TRIANGULATION=True, STRICT_TOLERANCE=True) geom_settings = ifcopenshell.geom.settings(DISABLE_TRIANGULATION=True, STRICT_TOLERANCE=True)
it = ifcopenshell.geom.iterator(geom_settings, ifc, include=[self.camera_element]) it = ifcopenshell.geom.iterator(geom_settings, ifc, include=[self.camera_element])
for elem in self.yield_from_iterator(it): for elem in self.yield_from_iterator(it):
self.serialiser.write(elem) self.serialiser.write(elem)
with profile("Finalizing"):
self.serialiser.finalize() self.serialiser.finalize()
results = self.svg_buffer.get_value() results = self.svg_buffer.get_value()
with profile("Post processing"):
root = etree.fromstring(results) root = etree.fromstring(results)
self.enrich_linework_with_metadata(root) self.enrich_linework_with_metadata(root)
self.move_projection_to_bottom(root) self.move_projection_to_bottom(root)
@@ -487,8 +509,11 @@ class AddAnnotation(bpy.types.Operator, Operator):
def _execute(self, context): def _execute(self, context):
drawing = tool.Ifc.get_entity(context.scene.camera) drawing = tool.Ifc.get_entity(context.scene.camera)
if not drawing: if not drawing:
self.report({"WARNING"}, "Not a BIM camera")
return return
core.add_annotation(tool.Ifc, tool.Collector, tool.Drawing, drawing=drawing, object_type=self.object_type) r = core.add_annotation(tool.Ifc, tool.Collector, tool.Drawing, drawing=drawing, object_type=self.object_type)
if isinstance(r, str):
self.report({"WARNING"}, r)
class AddSheet(bpy.types.Operator, Operator): class AddSheet(bpy.types.Operator, Operator):
+1 -1
View File
@@ -190,7 +190,7 @@ def update_drawing_name(ifc, drawing_tool, drawing=None, name=None):
def add_annotation(ifc, collector, drawing_tool, drawing=None, object_type=None): def add_annotation(ifc, collector, drawing_tool, drawing=None, object_type=None):
context = drawing_tool.get_annotation_context(drawing_tool.get_drawing_target_view(drawing)) context = drawing_tool.get_annotation_context(drawing_tool.get_drawing_target_view(drawing))
if not context: if not context:
return return "No annotation context for drawing"
drawing_tool.show_decorations() drawing_tool.show_decorations()
obj = drawing_tool.create_annotation_object(drawing, object_type) obj = drawing_tool.create_annotation_object(drawing, object_type)
element = ifc.get_entity(obj) element = ifc.get_entity(obj)