Implement cache updating for drawings. See #1153.

This commit is contained in:
Dion Moult
2021-11-08 21:00:10 +11:00
parent 7ccb6ee110
commit bf134eb0f4
2 changed files with 33 additions and 6 deletions
+15 -1
View File
@@ -85,25 +85,34 @@ class IfcExporter:
) )
def sync_deletions(self): def sync_deletions(self):
results = []
for ifc_definition_id in IfcStore.deleted_ids: for ifc_definition_id in IfcStore.deleted_ids:
try: try:
product = self.file.by_id(ifc_definition_id) product = self.file.by_id(ifc_definition_id)
if hasattr(product, "GlobalId"):
results.append(product.GlobalId)
except: except:
continue continue
ifcopenshell.api.run("root.remove_product", self.file, **{"product": product}) ifcopenshell.api.run("root.remove_product", self.file, **{"product": product})
return results
def sync_object_placements(self): def sync_object_placements(self):
results = []
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file) self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(self.file)
for ifc_definition_id, obj in IfcStore.id_map.items(): for ifc_definition_id, obj in IfcStore.id_map.items():
try: try:
if isinstance(obj, bpy.types.Material): if isinstance(obj, bpy.types.Material):
continue continue
tool.Collector.sync(obj) tool.Collector.sync(obj)
self.sync_object_placement(obj) result = self.sync_object_placement(obj)
if result:
results.append(result)
except ReferenceError: except ReferenceError:
pass # The object is likely deleted pass # The object is likely deleted
return results
def sync_edited_objects(self): def sync_edited_objects(self):
results = []
for obj in IfcStore.edited_objs.copy(): for obj in IfcStore.edited_objs.copy():
if not obj: if not obj:
continue continue
@@ -111,10 +120,14 @@ class IfcExporter:
if isinstance(obj, bpy.types.Material): if isinstance(obj, bpy.types.Material):
blenderbim.core.style.update_style_colours(tool.Ifc, tool.Style, obj=obj) blenderbim.core.style.update_style_colours(tool.Ifc, tool.Style, obj=obj)
else: else:
element = tool.Ifc.get_entity(obj)
if element:
results.append(element)
bpy.ops.bim.update_representation(obj=obj.name) bpy.ops.bim.update_representation(obj=obj.name)
except ReferenceError: except ReferenceError:
pass # The object is likely deleted pass # The object is likely deleted
IfcStore.edited_objs.clear() IfcStore.edited_objs.clear()
return results
def sync_object_placement(self, obj): def sync_object_placement(self, obj):
blender_matrix = np.array(obj.matrix_world) blender_matrix = np.array(obj.matrix_world)
@@ -140,6 +153,7 @@ class IfcExporter:
) )
if not np.allclose(ifc_matrix, blender_matrix, atol=0.0001): if not np.allclose(ifc_matrix, blender_matrix, atol=0.0001):
blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Surveyor, obj=obj) blenderbim.core.geometry.edit_object_placement(tool.Ifc, tool.Surveyor, obj=obj)
return element
def sync_grid_axis_object_placement(self, obj, element): def sync_grid_axis_object_placement(self, obj, element):
grid = (element.PartOfU or element.PartOfV or element.PartOfW)[0] grid = (element.PartOfU or element.PartOfV or element.PartOfW)[0]
@@ -37,6 +37,7 @@ import blenderbim.bim.module.drawing.annotation as annotation
import blenderbim.bim.module.drawing.sheeter as sheeter import blenderbim.bim.module.drawing.sheeter as sheeter
import blenderbim.bim.module.drawing.scheduler as scheduler import blenderbim.bim.module.drawing.scheduler as scheduler
import blenderbim.bim.module.drawing.helper as helper import blenderbim.bim.module.drawing.helper as helper
import blenderbim.bim.export_ifc
from lxml import etree from lxml import etree
from mathutils import Vector, Matrix, Euler, geometry from mathutils import Vector, Matrix, Euler, geometry
from blenderbim.bim.module.drawing.prop import RasterStyleProperty from blenderbim.bim.module.drawing.prop import RasterStyleProperty
@@ -281,6 +282,14 @@ 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
# All very hackish whilst prototyping
exporter = blenderbim.bim.export_ifc.IfcExporter(None)
exporter.file = tool.Ifc.get()
invalidated_guids = exporter.sync_deletions()
invalidated_elements = exporter.sync_object_placements()
invalidated_elements += exporter.sync_edited_objects()
[invalidated_guids.append(e.GlobalId) for e in invalidated_elements if hasattr(e, "GlobalId")]
# If we have already calculated it in the SVG in the past, don't recalculate # If we have already calculated it in the SVG in the past, don't recalculate
edited_guids = set() edited_guids = set()
for obj in IfcStore.edited_objs: for obj in IfcStore.edited_objs:
@@ -324,15 +333,15 @@ class CreateDrawing(bpy.types.Operator):
continue continue
elements = set(ifc.by_type("IfcElement")) - set(ifc.by_type("IfcOpeningElement")) elements = set(ifc.by_type("IfcElement")) - set(ifc.by_type("IfcOpeningElement"))
# elements = set([tool.Ifc.get_entity(o) for o in bpy.context.visible_objects if tool.Ifc.get_entity(o).is_a("IfcProduct")])
self.setup_serialiser(ifc) self.setup_serialiser(ifc)
cache_settings = ifcopenshell.geom.settings( cache_settings = ifcopenshell.geom.settings(
APPLY_DEFAULT_MATERIALS=True, DISABLE_TRIANGULATION=True, SEW_SHELLS=True APPLY_DEFAULT_MATERIALS=True, DISABLE_TRIANGULATION=True, SEW_SHELLS=True
) )
cache = ifcopenshell.geom.serializers.hdf5(ifc_cache_path, cache_settings) cache = ifcopenshell.geom.serializers.hdf5(ifc_cache_path, cache_settings)
[cache.remove(guid) for guid in invalidated_guids]
if target_view_contexts: if target_view_contexts and elements:
geom_settings = ifcopenshell.geom.settings( geom_settings = ifcopenshell.geom.settings(
APPLY_DEFAULT_MATERIALS=True, DISABLE_TRIANGULATION=True, SEW_SHELLS=True, INCLUDE_CURVES=True APPLY_DEFAULT_MATERIALS=True, DISABLE_TRIANGULATION=True, SEW_SHELLS=True, INCLUDE_CURVES=True
) )
@@ -341,11 +350,11 @@ class CreateDrawing(bpy.types.Operator):
it.set_cache(cache) it.set_cache(cache)
processed = set() processed = set()
for elem in self.yield_from_iterator(it): for elem in self.yield_from_iterator(it):
processed.add(ifc.by_guid(elem.guid)) processed.add(ifc.by_id(elem.id))
self.serialiser.write(elem) self.serialiser.write(elem)
elements -= processed elements -= processed
if body_contexts: if body_contexts and elements:
geom_settings = ifcopenshell.geom.settings( geom_settings = ifcopenshell.geom.settings(
APPLY_DEFAULT_MATERIALS=True, DISABLE_TRIANGULATION=True, SEW_SHELLS=True APPLY_DEFAULT_MATERIALS=True, DISABLE_TRIANGULATION=True, SEW_SHELLS=True
) )
@@ -409,7 +418,11 @@ class CreateDrawing(bpy.types.Operator):
ifc = tool.Ifc.get() ifc = tool.Ifc.get()
for el in root.findall(".//{http://www.w3.org/2000/svg}g[@{http://www.ifcopenshell.org/ns}guid]"): for el in root.findall(".//{http://www.w3.org/2000/svg}g[@{http://www.ifcopenshell.org/ns}guid]"):
classes = ["cut"] classes = ["cut"]
element = ifc.by_guid(el.get("{http://www.ifcopenshell.org/ns}guid")) try:
element = ifc.by_guid(el.get("{http://www.ifcopenshell.org/ns}guid"))
except:
# See #1861 - freshly created guids cannot be extracted unfortunately
continue
material = ifcopenshell.util.element.get_material(element, should_skip_usage=True) material = ifcopenshell.util.element.get_material(element, should_skip_usage=True)
if material: if material:
if material.is_a("IfcMaterialLayerSet"): if material.is_a("IfcMaterialLayerSet"):