mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 14:07:43 +00:00
Backspace everything regarding HDF5
This commit is contained in:
-1
@@ -1 +0,0 @@
|
||||
This cache folder contains .h5 files. These files cache IFC geometry for performance only. You may safely clear the contents of this cache folder without losing data.
|
||||
@@ -43,7 +43,6 @@ class IfcExporter:
|
||||
def export(self):
|
||||
self.file = tool.Ifc.get()
|
||||
self.set_header()
|
||||
IfcStore.update_cache()
|
||||
self.sync_all_objects()
|
||||
extension = self.ifc_export_settings.output_file.split(".")[-1].lower()
|
||||
if extension == "ifczip":
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import traceback
|
||||
import uuid
|
||||
@@ -31,7 +29,6 @@ from typing import Literal, NotRequired, Optional, TypedDict, Union
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.geom
|
||||
import ifcopenshell.ifcopenshell_wrapper
|
||||
from ifcopenshell.file import UndoSystemError
|
||||
|
||||
@@ -72,8 +69,6 @@ class IfcStore:
|
||||
"""Should be set only using ``tool.Ifc.set``."""
|
||||
|
||||
schema: Optional[ifcopenshell.ifcopenshell_wrapper.schema_definition] = None
|
||||
cache: Optional[ifcopenshell.ifcopenshell_wrapper.HdfSerializer] = None
|
||||
cache_path: Optional[str] = None
|
||||
id_map: dict[int, IFC_CONNECTED_TYPE] = {}
|
||||
guid_map: dict[str, IFC_CONNECTED_TYPE] = {}
|
||||
edited_objs: set[bpy.types.Object] = set()
|
||||
@@ -95,8 +90,6 @@ class IfcStore:
|
||||
IfcStore.path = ""
|
||||
IfcStore.file = None
|
||||
IfcStore.schema = None
|
||||
IfcStore.cache = None
|
||||
IfcStore.cache_path = None
|
||||
IfcStore.id_map = {}
|
||||
IfcStore.guid_map = {}
|
||||
IfcStore.edited_objs = set()
|
||||
@@ -130,74 +123,6 @@ class IfcStore:
|
||||
if IfcStore.path and not os.path.isabs(IfcStore.path):
|
||||
IfcStore.path = os.path.abspath(os.path.join(bpy.path.abspath("//"), IfcStore.path))
|
||||
|
||||
@staticmethod
|
||||
def generate_cache_path() -> str:
|
||||
"""Generate cache path based on the active file and it's path."""
|
||||
assert IfcStore.file
|
||||
ifc_key = IfcStore.path + IfcStore.file.header.file_name.time_stamp
|
||||
ifc_hash = hashlib.md5(ifc_key.encode("utf-8")).hexdigest()
|
||||
prefs = tool.Blender.get_addon_preferences()
|
||||
cache_path = os.path.join(prefs.cache_dir, f"{ifc_hash}.h5")
|
||||
return cache_path
|
||||
|
||||
@staticmethod
|
||||
def get_cache() -> ifcopenshell.geom.serializers.hdf5 | None:
|
||||
"""Get existing cache for the current file or create a new one.
|
||||
|
||||
.h5 cache name reflects IFC filepath and it's current header's timestamp.
|
||||
"""
|
||||
if IfcStore.cache is None and IfcStore.path:
|
||||
cache_path = IfcStore.generate_cache_path()
|
||||
os.makedirs(os.path.dirname(cache_path), exist_ok=True)
|
||||
IfcStore.cache_path = cache_path
|
||||
cache_path = Path(IfcStore.cache_path)
|
||||
cache_settings = ifcopenshell.geom.settings()
|
||||
serializer_settings = ifcopenshell.geom.serializer_settings()
|
||||
cache_preexists = cache_path.exists()
|
||||
try:
|
||||
IfcStore.cache = ifcopenshell.geom.serializers.hdf5(
|
||||
IfcStore.cache_path, cache_settings, serializer_settings
|
||||
)
|
||||
if cache_preexists:
|
||||
print(f"Successfully loaded existing cache: {cache_path.name}.")
|
||||
else:
|
||||
print("New cache was created.")
|
||||
except Exception as e:
|
||||
if cache_preexists:
|
||||
print(f"Failed to create a cache from existing file '{cache_path.name}': {str(e)}.")
|
||||
else:
|
||||
print(f"Failed to create a cache: {str(e)}.")
|
||||
# No point to trying again the same operation.
|
||||
return
|
||||
|
||||
os.remove(IfcStore.cache_path)
|
||||
try:
|
||||
IfcStore.cache = ifcopenshell.geom.serializers.hdf5(
|
||||
IfcStore.cache_path, cache_settings, serializer_settings
|
||||
)
|
||||
print("New cache was created.")
|
||||
except Exception as e:
|
||||
print(f"Failed to create a cache: {str(e)}.")
|
||||
return
|
||||
return IfcStore.cache
|
||||
|
||||
@staticmethod
|
||||
def update_cache() -> None:
|
||||
"""Update cache filename after timestamp was updated."""
|
||||
if not IfcStore.cache:
|
||||
return
|
||||
assert IfcStore.cache_path
|
||||
new_cache_path = IfcStore.generate_cache_path()
|
||||
IfcStore.cache = None
|
||||
try:
|
||||
shutil.move(IfcStore.cache_path, new_cache_path)
|
||||
except PermissionError:
|
||||
try:
|
||||
shutil.copy2(IfcStore.cache_path, new_cache_path)
|
||||
except PermissionError:
|
||||
pass # Well we tried. No cache for you!
|
||||
IfcStore.get_cache()
|
||||
|
||||
@staticmethod
|
||||
def load_file(path: str) -> None:
|
||||
if not os.path.isfile(path):
|
||||
|
||||
@@ -721,10 +721,6 @@ class IfcImporter:
|
||||
iterator = ifcopenshell.geom.iterator(
|
||||
settings, self.file, include=products, geometry_library=self.ifc_import_settings.geometry_library
|
||||
)
|
||||
if self.ifc_import_settings.should_cache:
|
||||
cache = IfcStore.get_cache()
|
||||
if cache:
|
||||
iterator.set_cache(cache)
|
||||
valid_file = iterator.initialize()
|
||||
if not valid_file:
|
||||
return results
|
||||
@@ -1267,7 +1263,6 @@ class IfcImportSettings:
|
||||
self.should_merge_materials_by_colour = False
|
||||
self.should_load_geometry = True
|
||||
self.should_clean_mesh = False
|
||||
self.should_cache = True
|
||||
self.deflection_tolerance = 0.05 # Default is 0.001, but I find this to be more practical
|
||||
self.angular_tolerance = 0.5
|
||||
self.void_limit = 30
|
||||
@@ -1295,7 +1290,6 @@ class IfcImportSettings:
|
||||
context=None, input_file: Optional[str] = None, logger: Optional[logging.Logger] = None
|
||||
) -> IfcImportSettings:
|
||||
scene_diff = tool.Blender.get_diff_props()
|
||||
prefs = tool.Blender.get_addon_preferences()
|
||||
props = tool.Project.get_project_props()
|
||||
settings = IfcImportSettings()
|
||||
settings.input_file = input_file
|
||||
@@ -1308,7 +1302,6 @@ class IfcImportSettings:
|
||||
settings.should_merge_materials_by_colour = props.should_merge_materials_by_colour
|
||||
settings.should_load_geometry = props.should_load_geometry
|
||||
settings.should_clean_mesh = props.should_clean_mesh
|
||||
settings.should_cache = prefs.should_always_cache or props.should_cache
|
||||
settings.deflection_tolerance = props.deflection_tolerance
|
||||
settings.angular_tolerance = props.angular_tolerance
|
||||
settings.void_limit = props.void_limit
|
||||
|
||||
@@ -37,7 +37,6 @@ classes = (
|
||||
operator.PrintObjectPlacement,
|
||||
operator.PrintUnusedElementStats,
|
||||
operator.ProfileImportIFC,
|
||||
operator.PurgeHdf5Cache,
|
||||
operator.PurgeUnusedElementsByClass,
|
||||
operator.PurgeUnusedObjects,
|
||||
operator.RestartBlender,
|
||||
|
||||
@@ -570,17 +570,6 @@ class SelectExpressFile(bpy.types.Operator, ImportHelper):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class PurgeHdf5Cache(bpy.types.Operator):
|
||||
bl_idname = "bim.purge_hdf5_cache"
|
||||
bl_label = "Purge HDF5 Cache"
|
||||
bl_description = "Clean up HDF5 cache files except the ones that currently loaded"
|
||||
|
||||
def execute(self, context):
|
||||
core.purge_hdf5_cache(tool.Debug)
|
||||
self.report({"INFO"}, "HDF5 cache purged.")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class OverrideDisplayType(bpy.types.Operator):
|
||||
bl_idname = "bim.override_display_type"
|
||||
bl_label = "Override Display Type"
|
||||
|
||||
@@ -64,9 +64,6 @@ class BIM_PT_debug(Panel):
|
||||
row = layout.row()
|
||||
row.operator("bim.copy_debug_information")
|
||||
|
||||
row = layout.row()
|
||||
row.operator("bim.purge_hdf5_cache")
|
||||
|
||||
row = layout.row()
|
||||
row.operator("bim.update_representation", text="Manually Save Representation")
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import multiprocessing
|
||||
@@ -901,10 +900,7 @@ class CreateDrawing(bpy.types.Operator):
|
||||
# All very hackish whilst prototyping
|
||||
exporter = bonsai.bim.export_ifc.IfcExporter(None)
|
||||
exporter.file = tool.Ifc.get()
|
||||
invalidated_elements = exporter.sync_all_objects()
|
||||
invalidated_guids = [e.GlobalId for e in invalidated_elements if hasattr(e, "GlobalId")]
|
||||
if cache := IfcStore.get_cache():
|
||||
[cache.remove(guid) for guid in invalidated_guids]
|
||||
exporter.sync_all_objects()
|
||||
|
||||
# If we have already calculated it in the SVG in the past, don't recalculate
|
||||
edited_guids = set()
|
||||
@@ -922,7 +918,6 @@ class CreateDrawing(bpy.types.Operator):
|
||||
cached_linework -= edited_guids
|
||||
|
||||
bim_props = tool.Blender.get_bim_props()
|
||||
prefs = tool.Blender.get_addon_preferences()
|
||||
files = {bim_props.ifc_file: tool.Ifc.get()}
|
||||
|
||||
props = tool.Project.get_project_props()
|
||||
@@ -935,12 +930,8 @@ class CreateDrawing(bpy.types.Operator):
|
||||
tree = ifcopenshell.geom.tree()
|
||||
tree.enable_face_styles(True)
|
||||
|
||||
for ifc_path, ifc in files.items():
|
||||
for ifc in files.values():
|
||||
# Don't use draw.main() just whilst we're prototyping and experimenting
|
||||
# TODO: hash paths are never used
|
||||
ifc_hash = hashlib.md5(ifc_path.encode("utf-8")).hexdigest()
|
||||
ifc_cache_path = os.path.join(prefs.cache_dir, f"{ifc_hash}.h5")
|
||||
|
||||
self.serialiser.setFile(ifc)
|
||||
drawing_elements = tool.Drawing.get_drawing_elements(self.camera_element, ifc_file=ifc)
|
||||
|
||||
|
||||
@@ -576,9 +576,6 @@ class UpdateRepresentation(bpy.types.Operator, tool.Ifc.Operator):
|
||||
self.report({"ERROR"}, f"Object '{obj.name}' has openings - representation cannot be updated.")
|
||||
return
|
||||
|
||||
if not product.is_a("IfcGridAxis"):
|
||||
tool.Geometry.clear_cache(product)
|
||||
|
||||
if product.is_a("IfcGridAxis"):
|
||||
# Grid geometry does not follow the "representation" paradigm and needs to be treated specially
|
||||
tool.Model.create_axis_curve(obj, product)
|
||||
|
||||
@@ -1488,7 +1488,6 @@ class LoadLink(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
def link_ifc(self) -> Union[set[str], None]:
|
||||
blend_filepath = self.filepath_.with_suffix(".ifc.cache.blend")
|
||||
h5_filepath = self.filepath_.with_suffix(".ifc.cache.h5")
|
||||
json_filepath = self.filepath_.with_suffix(".ifc.cache.json")
|
||||
|
||||
def should_clear_cache() -> bool:
|
||||
|
||||
@@ -345,14 +345,6 @@ class BIMProjectProperties(PropertyGroup):
|
||||
),
|
||||
default=False,
|
||||
)
|
||||
should_cache: BoolProperty(
|
||||
name="Cache",
|
||||
description=(
|
||||
"Cache loaded geometry to .h5 file in your cache directory (see in preferences) "
|
||||
"for faster imports and geometry reloads."
|
||||
),
|
||||
default=False,
|
||||
)
|
||||
deflection_tolerance: FloatProperty(name="Deflection Tolerance", default=0.05)
|
||||
angular_tolerance: FloatProperty(name="Angular Tolerance", default=0.5)
|
||||
void_limit: IntProperty(
|
||||
@@ -521,7 +513,6 @@ class BIMProjectProperties(PropertyGroup):
|
||||
should_merge_materials_by_colour: bool
|
||||
should_load_geometry: bool
|
||||
should_clean_mesh: bool
|
||||
should_cache: bool
|
||||
deflection_tolerance: float
|
||||
angular_tolerance: float
|
||||
void_limit: int
|
||||
|
||||
@@ -207,8 +207,6 @@ class BIM_PT_project(Panel):
|
||||
row = self.layout.row()
|
||||
row.prop(pprops, "should_clean_mesh")
|
||||
row = self.layout.row()
|
||||
row.prop(pprops, "should_cache")
|
||||
row = self.layout.row()
|
||||
row.prop(pprops, "should_load_geometry")
|
||||
row = self.layout.row()
|
||||
row.prop(pprops, "should_merge_materials_by_colour")
|
||||
|
||||
@@ -207,7 +207,6 @@ class RemoveOpening(bpy.types.Operator, tool.Ifc.Operator):
|
||||
representation=representation,
|
||||
)
|
||||
tool.Geometry.unlock_scale_object_with_openings(obj)
|
||||
tool.Geometry.clear_cache(element)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -665,10 +665,6 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
||||
name="Disable Undo When Saving (Faster saves, no undo for you!)", default=False
|
||||
)
|
||||
should_stream: BoolProperty(name="Stream Data From IFC-SPF (Only for advanced users)", default=False)
|
||||
should_always_cache: BoolProperty(
|
||||
name="Always Cache Geometry",
|
||||
description="Whether to always cache geometry regardless of 'Cache' setting during Advanced Project Load.",
|
||||
)
|
||||
occurrence_name_style: bpy.props.EnumProperty(
|
||||
items=[("CLASS", "By Class", ""), ("TYPE", "By Type", ""), ("CUSTOM", "Custom", "")],
|
||||
name="Occurrence Name Style",
|
||||
@@ -777,7 +773,6 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
||||
bsdd_baseurl: str
|
||||
should_disable_undo_on_save: bool
|
||||
should_stream: bool
|
||||
should_always_cache: bool
|
||||
occurrence_name_style: Literal["CLASS", "TYPE", "CUSTOM"]
|
||||
occurrence_name_function: str
|
||||
gizmos: GizmoPreferences
|
||||
@@ -976,7 +971,6 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
||||
layout.prop(self, "opening_focus_opacity")
|
||||
layout.prop(self, "should_disable_undo_on_save")
|
||||
layout.prop(self, "should_stream")
|
||||
layout.prop(self, "should_always_cache")
|
||||
layout.label(text="bSDD:")
|
||||
layout.prop(self, "bsdd_load_preview_dictionaries")
|
||||
layout.prop(self, "bsdd_load_inactive_dictionaries")
|
||||
|
||||
@@ -30,10 +30,6 @@ def parse_express(debug: type[tool.Debug], filename: str) -> None:
|
||||
debug.add_schema_identifier(debug.load_express(filename))
|
||||
|
||||
|
||||
def purge_hdf5_cache(debug: type[tool.Debug]) -> None:
|
||||
debug.purge_hdf5_cache()
|
||||
|
||||
|
||||
def purge_unused_elements(ifc: type[tool.Ifc], debug: type[tool.Debug], ifc_class: str) -> int:
|
||||
ifc_file = ifc.get()
|
||||
unused_elements = [i for i in ifc_file.by_type(ifc_class) if ifc_file.get_total_inverses(i) == 0]
|
||||
|
||||
@@ -44,7 +44,6 @@ def edit_object_placement(
|
||||
element = ifc.get_entity(obj)
|
||||
if not element:
|
||||
return
|
||||
geometry.clear_cache(element)
|
||||
if apply_scale:
|
||||
geometry.clear_scale(obj)
|
||||
geometry.get_blender_offset_type(obj)
|
||||
@@ -125,7 +124,6 @@ def switch_representation(
|
||||
|
||||
element = ifc.get_entity(obj)
|
||||
assert element
|
||||
geometry.clear_cache(element)
|
||||
geometry.reimport_element_representations(obj, representation, apply_openings=apply_openings)
|
||||
|
||||
|
||||
|
||||
@@ -283,7 +283,6 @@ class Cost:
|
||||
class Debug:
|
||||
def add_schema_identifier(cls, schema): pass
|
||||
def load_express(cls, filename): pass
|
||||
def purge_hdf5_cache(cls): pass
|
||||
|
||||
|
||||
@interface
|
||||
@@ -422,7 +421,6 @@ class Feature:
|
||||
@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 copy_data_links(cls, data, copied_entities) -> None: pass
|
||||
|
||||
@@ -59,17 +59,6 @@ class Debug(bonsai.core.tool.Debug):
|
||||
ifcopenshell.register_schema(schema)
|
||||
return schema.schema
|
||||
|
||||
@classmethod
|
||||
def purge_hdf5_cache(cls) -> None:
|
||||
prefs = tool.Blender.get_addon_preferences()
|
||||
cache_dir = prefs.cache_dir
|
||||
filelist = [f for f in os.listdir(cache_dir) if f.endswith(".h5")]
|
||||
for f in filelist:
|
||||
try:
|
||||
os.remove(os.path.join(cache_dir, f))
|
||||
except PermissionError:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def debug_bmesh(cls, bm: bmesh.types.BMesh, name: str = "Debug") -> bpy.types.Object:
|
||||
mesh = bpy.data.meshes.new("Debug")
|
||||
|
||||
@@ -73,7 +73,6 @@ import bonsai.core.style
|
||||
import bonsai.core.system
|
||||
import bonsai.core.tool
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.geometry.prop import (
|
||||
@@ -109,16 +108,6 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
raise Exception("user_remap is not supported for meshes in EDIT mode")
|
||||
old_data.user_remap(new_data)
|
||||
|
||||
@classmethod
|
||||
def get_cache(cls) -> Union[ifcopenshell.geom.serializers.hdf5, None]:
|
||||
return IfcStore.get_cache()
|
||||
|
||||
@classmethod
|
||||
def clear_cache(cls, element: ifcopenshell.entity_instance) -> None:
|
||||
cache = IfcStore.get_cache()
|
||||
if cache and hasattr(element, "GlobalId"):
|
||||
cache.remove(element.GlobalId)
|
||||
|
||||
@classmethod
|
||||
def clear_modifiers(cls, obj: bpy.types.Object) -> None:
|
||||
for modifier in obj.modifiers:
|
||||
@@ -818,7 +807,6 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
if not cls.has_data_users(old_data):
|
||||
cls.delete_data(old_data)
|
||||
cls.clear_modifiers(obj)
|
||||
cls.clear_cache(element)
|
||||
|
||||
# Import swept disk solids as Blender curves if possible.
|
||||
elements_without_openings = {e for e in elements if not getattr(e, "HasOpenings", False)}
|
||||
|
||||
@@ -22,9 +22,6 @@ props = tool.Georeference.get_georeference_props()
|
||||
|
||||
props = tool.Project.get_project_props()
|
||||
|
||||
# Generally recommended to disable caching for stability right now
|
||||
props.should_cache = False
|
||||
|
||||
# If you are not authoring, it is recommended to enable this.
|
||||
# When enabled, types, openings, and non geometric elements are not loaded.
|
||||
props.is_coordinating = True
|
||||
|
||||
@@ -9,7 +9,6 @@ class BlenderImporter:
|
||||
|
||||
def __init__(self):
|
||||
self.file = ifcopenshell.open("/home/dion/untitled.ifc")
|
||||
self.cache_path = "cache.h5"
|
||||
self.should_use_cpu_multiprocessing = True
|
||||
self.deflection_tolerance = 0.001
|
||||
self.angular_tolerance = 0.5
|
||||
@@ -82,9 +81,6 @@ class BlenderImporter:
|
||||
iterator = ifcopenshell.geom.iterator(settings, self.file, multiprocessing.cpu_count(), include=products)
|
||||
else:
|
||||
iterator = ifcopenshell.geom.iterator(settings, self.file, include=products)
|
||||
cache = self.get_cache()
|
||||
if cache:
|
||||
iterator.set_cache(cache)
|
||||
valid_file = iterator.initialize()
|
||||
if not valid_file:
|
||||
return results
|
||||
@@ -113,13 +109,4 @@ class BlenderImporter:
|
||||
print("Done creating geometry")
|
||||
return results
|
||||
|
||||
def get_cache(self):
|
||||
cache_settings = ifcopenshell.geom.settings()
|
||||
serializer_settings = ifcopenshell.geom.serializer_settings()
|
||||
try:
|
||||
return ifcopenshell.geom.serializers.hdf5(self.cache_path, cache_settings, serializer_settings)
|
||||
except:
|
||||
return
|
||||
|
||||
|
||||
BlenderImporter().execute()
|
||||
|
||||
@@ -25,9 +25,3 @@ class TestParseExpress:
|
||||
debug.load_express("filename").should_be_called().will_return("schema")
|
||||
debug.add_schema_identifier("schema").should_be_called()
|
||||
subject.parse_express(debug, "filename")
|
||||
|
||||
|
||||
class TestPurgeHdf5Cache:
|
||||
def test_run(self, debug):
|
||||
debug.purge_hdf5_cache().should_be_called()
|
||||
subject.purge_hdf5_cache(debug)
|
||||
|
||||
@@ -24,7 +24,6 @@ from test.core.bootstrap import geometry, ifc, style, surveyor
|
||||
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()
|
||||
geometry.get_blender_offset_type("obj").should_be_called()
|
||||
surveyor.get_absolute_matrix("obj").should_be_called().will_return("matrix")
|
||||
@@ -197,7 +196,6 @@ class TestSwitchRepresentation:
|
||||
def test_switching_to_a_representation(self, ifc, geometry):
|
||||
geometry.get_object_data("obj").should_be_called().will_return("current_obj_data")
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
geometry.clear_cache("element").should_be_called()
|
||||
geometry.reimport_element_representations("obj", "mapped_rep", apply_openings=True).should_be_called()
|
||||
subject.switch_representation(
|
||||
ifc,
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.style
|
||||
@@ -55,24 +53,6 @@ class TestLoadExpress(NewFile):
|
||||
os.remove(schema_path + ".cache.dat")
|
||||
|
||||
|
||||
class TestPurgeHdf5Cache(NewFile):
|
||||
def test_run(self):
|
||||
prefs = tool.Blender.get_addon_preferences()
|
||||
cache_dir = Path(prefs.cache_dir)
|
||||
test_file = cache_dir / "test.h5"
|
||||
test_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
test_file.touch()
|
||||
|
||||
# Ensure it can skip currently loaded cache.
|
||||
loaded_file_path = test_file.with_stem("test_loaded")
|
||||
loaded_file = open(loaded_file_path, "w")
|
||||
|
||||
subject.purge_hdf5_cache()
|
||||
# On Unix loaded files are not locked.
|
||||
paths = [loaded_file_path] if os.name == "nt" else []
|
||||
assert [f for f in cache_dir.iterdir() if f.suffix == ".h5"] == paths
|
||||
|
||||
|
||||
class TestMergeIdenticalObject(NewFile):
|
||||
def test_merge_identical_styles(self):
|
||||
tool.Ifc.set(ifc := ifcopenshell.file())
|
||||
|
||||
Reference in New Issue
Block a user