mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 19:07:57 +00:00
Geometry caching is now enabled for model importing
This commit is contained in:
@@ -41,6 +41,7 @@ class IfcExporter:
|
||||
def export(self):
|
||||
self.file = IfcStore.get_file()
|
||||
self.set_header()
|
||||
IfcStore.update_cache()
|
||||
if bpy.context.scene.BIMProjectProperties.is_authoring:
|
||||
self.sync_deletions()
|
||||
self.sync_object_placements()
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import os
|
||||
import bpy
|
||||
import uuid
|
||||
import hashlib
|
||||
import zipfile
|
||||
import tempfile
|
||||
import ifcopenshell
|
||||
@@ -30,6 +31,8 @@ class IfcStore:
|
||||
path = ""
|
||||
file = None
|
||||
schema = None
|
||||
cache = None
|
||||
cache_path = None
|
||||
id_map = {}
|
||||
guid_map = {}
|
||||
deleted_ids = set()
|
||||
@@ -50,6 +53,8 @@ class IfcStore:
|
||||
IfcStore.path = ""
|
||||
IfcStore.file = None
|
||||
IfcStore.schema = None
|
||||
IfcStore.cache = None
|
||||
IfcStore.cache_path = None
|
||||
IfcStore.id_map = {}
|
||||
IfcStore.guid_map = {}
|
||||
IfcStore.deleted_ids = set()
|
||||
@@ -72,6 +77,27 @@ class IfcStore:
|
||||
pass
|
||||
return IfcStore.file
|
||||
|
||||
@staticmethod
|
||||
def get_cache():
|
||||
if IfcStore.cache is None and IfcStore.path:
|
||||
ifc_key = IfcStore.path + IfcStore.file.wrapped_data.header.file_name.time_stamp
|
||||
ifc_hash = hashlib.md5(ifc_key.encode("utf-8")).hexdigest()
|
||||
IfcStore.cache_path = os.path.join(bpy.context.scene.BIMProperties.data_dir, "cache", f"{ifc_hash}.h5")
|
||||
cache_settings = ifcopenshell.geom.settings()
|
||||
IfcStore.cache = ifcopenshell.geom.serializers.hdf5(IfcStore.cache_path, cache_settings)
|
||||
return IfcStore.cache
|
||||
|
||||
@staticmethod
|
||||
def update_cache():
|
||||
if not IfcStore.cache:
|
||||
return
|
||||
ifc_key = IfcStore.path + IfcStore.file.wrapped_data.header.file_name.time_stamp
|
||||
ifc_hash = hashlib.md5(ifc_key.encode("utf-8")).hexdigest()
|
||||
new_cache_path = os.path.join(bpy.context.scene.BIMProperties.data_dir, "cache", f"{ifc_hash}.h5")
|
||||
os.replace(IfcStore.cache_path, new_cache_path)
|
||||
IfcStore.cache = None
|
||||
IfcStore.get_cache()
|
||||
|
||||
@staticmethod
|
||||
def load_file(path):
|
||||
extension = path.split(".")[-1]
|
||||
|
||||
@@ -625,6 +625,7 @@ class IfcImporter:
|
||||
)
|
||||
else:
|
||||
iterator = ifcopenshell.geom.iterator(self.settings, self.file, include=products)
|
||||
iterator.set_cache(IfcStore.get_cache())
|
||||
valid_file = iterator.initialize()
|
||||
if not valid_file:
|
||||
return results
|
||||
@@ -770,6 +771,7 @@ class IfcImporter:
|
||||
)
|
||||
else:
|
||||
iterator = ifcopenshell.geom.iterator(self.settings_2d, self.file, include=products)
|
||||
iterator.set_cache(IfcStore.get_cache())
|
||||
valid_file = iterator.initialize()
|
||||
if not valid_file:
|
||||
return results
|
||||
|
||||
@@ -335,16 +335,12 @@ class CreateDrawing(bpy.types.Operator):
|
||||
elements = set(ifc.by_type("IfcElement")) - set(ifc.by_type("IfcOpeningElement"))
|
||||
|
||||
self.setup_serialiser(ifc)
|
||||
cache_settings = ifcopenshell.geom.settings(
|
||||
APPLY_DEFAULT_MATERIALS=True, DISABLE_TRIANGULATION=True, SEW_SHELLS=True
|
||||
)
|
||||
cache = ifcopenshell.geom.serializers.hdf5(ifc_cache_path, cache_settings)
|
||||
cache_settings = ifcopenshell.geom.settings(DISABLE_TRIANGULATION=True)
|
||||
cache = IfcStore.get_cache()
|
||||
[cache.remove(guid) for guid in invalidated_guids]
|
||||
|
||||
if target_view_contexts and elements:
|
||||
geom_settings = ifcopenshell.geom.settings(
|
||||
APPLY_DEFAULT_MATERIALS=True, DISABLE_TRIANGULATION=True, SEW_SHELLS=True, INCLUDE_CURVES=True
|
||||
)
|
||||
geom_settings = ifcopenshell.geom.settings(DISABLE_TRIANGULATION=True, INCLUDE_CURVES=True)
|
||||
geom_settings.set_context_ids(target_view_contexts)
|
||||
it = ifcopenshell.geom.iterator(geom_settings, ifc, multiprocessing.cpu_count(), include=elements)
|
||||
it.set_cache(cache)
|
||||
@@ -356,7 +352,7 @@ class CreateDrawing(bpy.types.Operator):
|
||||
|
||||
if body_contexts and elements:
|
||||
geom_settings = ifcopenshell.geom.settings(
|
||||
APPLY_DEFAULT_MATERIALS=True, DISABLE_TRIANGULATION=True, SEW_SHELLS=True
|
||||
DISABLE_TRIANGULATION=True,
|
||||
)
|
||||
geom_settings.set_context_ids(body_contexts)
|
||||
it = ifcopenshell.geom.iterator(geom_settings, ifc, multiprocessing.cpu_count(), include=elements)
|
||||
@@ -365,7 +361,7 @@ class CreateDrawing(bpy.types.Operator):
|
||||
self.serialiser.write(elem)
|
||||
|
||||
geom_settings = ifcopenshell.geom.settings(
|
||||
APPLY_DEFAULT_MATERIALS=True, DISABLE_TRIANGULATION=True, SEW_SHELLS=True
|
||||
DISABLE_TRIANGULATION=True,
|
||||
)
|
||||
it = ifcopenshell.geom.iterator(geom_settings, ifc, include=[self.camera_element])
|
||||
for elem in self.yield_from_iterator(it):
|
||||
@@ -383,9 +379,7 @@ class CreateDrawing(bpy.types.Operator):
|
||||
return svg_path
|
||||
|
||||
def setup_serialiser(self, ifc):
|
||||
self.svg_settings = ifcopenshell.geom.settings(
|
||||
APPLY_DEFAULT_MATERIALS=True, DISABLE_TRIANGULATION=True, INCLUDE_CURVES=True
|
||||
)
|
||||
self.svg_settings = ifcopenshell.geom.settings(DISABLE_TRIANGULATION=True, INCLUDE_CURVES=True)
|
||||
self.svg_buffer = ifcopenshell.geom.serializers.buffer()
|
||||
self.serialiser = ifcopenshell.geom.serializers.svg(self.svg_buffer, self.svg_settings)
|
||||
self.serialiser.setFile(ifc)
|
||||
|
||||
@@ -45,10 +45,13 @@ class AuthoringData:
|
||||
|
||||
@classmethod
|
||||
def relating_types(cls):
|
||||
if not cls.ifc_classes():
|
||||
ifc_classes = cls.ifc_classes()
|
||||
if not ifc_classes:
|
||||
return []
|
||||
results = []
|
||||
ifc_class = bpy.context.scene.BIMModelProperties.ifc_class
|
||||
if not ifc_class and ifc_classes:
|
||||
ifc_class = ifc_classes[0][0]
|
||||
if ifc_class:
|
||||
elements = [(str(e.id()), e.Name, "") for e in tool.Ifc.get().by_type(ifc_class)]
|
||||
results.extend(sorted(elements, key=lambda s: s[1]))
|
||||
|
||||
@@ -22,6 +22,7 @@ import blenderbim.core.style
|
||||
def edit_object_placement(ifc, geometry, surveyor, obj=None):
|
||||
element = ifc.get_entity(obj)
|
||||
if element:
|
||||
geometry.clear_cache(element)
|
||||
geometry.clear_scale(obj)
|
||||
ifc.run("geometry.edit_object_placement", product=element, matrix=surveyor.get_absolute_matrix(obj))
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ class Context:
|
||||
@interface
|
||||
class Geometry:
|
||||
def change_object_data(cls, obj, data, is_global=False): pass
|
||||
def clear_cache(cls, element): pass
|
||||
def clear_modifiers(cls, obj): pass
|
||||
def clear_scale(cls, obj): pass
|
||||
def create_dynamic_voids(cls, obj): pass
|
||||
|
||||
@@ -34,6 +34,10 @@ class Geometry(blenderbim.core.tool.Geometry):
|
||||
else:
|
||||
obj.data = data
|
||||
|
||||
@classmethod
|
||||
def clear_cache(cls, element):
|
||||
IfcStore.get_cache().remove(element.GlobalId)
|
||||
|
||||
@classmethod
|
||||
def clear_modifiers(cls, obj):
|
||||
for modifier in obj.modifiers:
|
||||
|
||||
@@ -24,6 +24,7 @@ from test.core.bootstrap import ifc, surveyor, geometry, style
|
||||
class TestEditObjectPlacement:
|
||||
def predict(self, ifc, geometry, surveyor):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
geometry.clear_cache("element").should_be_called()
|
||||
geometry.clear_scale("obj").should_be_called()
|
||||
surveyor.get_absolute_matrix("obj").should_be_called().will_return("matrix")
|
||||
ifc.run("geometry.edit_object_placement", product="element", matrix="matrix").should_be_called()
|
||||
|
||||
@@ -53,6 +53,11 @@ class TestChangeObjectData(NewFile):
|
||||
assert obj2.data == data2
|
||||
|
||||
|
||||
class TestClearCache(NewFile):
|
||||
def test_nothing(self):
|
||||
pass # TODO I don't know how to test this
|
||||
|
||||
|
||||
class TestClearModifiers(NewFile):
|
||||
def test_run(self):
|
||||
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
||||
|
||||
Reference in New Issue
Block a user