Coverage for bim2sim / tasks / common / load_ifc.py: 90%

48 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-20 13:33 +0000

1from __future__ import annotations 

2 

3import time 

4from pathlib import Path 

5 

6from bim2sim.kernel.ifc_file import IfcFileClass 

7from bim2sim.tasks.base import ITask 

8from bim2sim.utilities.types import IFCDomain 

9 

10 

11@staticmethod 

12def extract_ifc_file_names(base_path): 

13 """Extract ifc file names of a given directory. 

14 

15 Args: 

16 base_path: Pathlib path that holds the different domain folders, 

17 which hold the ifc files. 

18 Returns: 

19 list: of ifc file names 

20 """ 

21 if not base_path.is_dir(): 

22 raise AssertionError(f"Given base_path {base_path} is not a" 

23 f" directory. Please provide a directory.") 

24 ifc_file_paths = list(base_path.glob("**/*.ifc")) + list( 

25 base_path.glob("**/*.ifcxml")) + list( 

26 base_path.glob("**/*.ifczip")) 

27 

28 return ifc_file_paths 

29 

30 

31class LoadIFC(ITask): 

32 """Load all IFC files from PROJECT.ifc_base path. 

33 

34 This tasks reads the IFC files of one or multiple domains inside bim2sim. 

35 

36 Returns: 

37 ifc: list of one or multiple IfcFileClass elements 

38 """ 

39 

40 touches = ('ifc_files', ) 

41 

42 def run(self): 

43 """Run function of LoadIFC.""" 

44 self.logger.info("Loading IFC files") 

45 ifc_files = yield from self.load_ifc_files(self.paths.ifc_base) 

46 return ifc_files, 

47 

48 def load_ifc_files(self, base_path: Path): 

49 """Load all ifc files/file given in base_path. 

50 

51 Loads the ifc files inside the different domain folders in the base 

52 path, and initializes the bim2sim ifc file classes. 

53 

54 Args: 

55 base_path: Pathlib path that holds the different domain folders, 

56 which hold the ifc files. 

57 """ 

58 ifc_files_paths = extract_ifc_file_names(base_path) 

59 self.logger.info(f"Found {len(ifc_files_paths)} IFC files in project " 

60 f"directory.") 

61 ifc_files_dict = {k: [] for k in ['arch', 'hydraulic', 'ventilation']} 

62 ifc_files_unsorted = [] 

63 ifc_files = [] 

64 for i, total_ifc_path in enumerate(ifc_files_paths, start=1): 

65 self.logger.info( 

66 f"Loading IFC file {total_ifc_path.name} {i}/" 

67 "{len(ifc_files_paths)}.") 

68 ifc_domain = total_ifc_path.parent.name 

69 reset_guids = self.playground.sim_settings.reset_guids 

70 ifc_domain = IFCDomain[ifc_domain] 

71 t_load_start = time.time() 

72 ifc_file_cls = IfcFileClass( 

73 total_ifc_path, 

74 ifc_domain=ifc_domain, 

75 reset_guids=reset_guids) 

76 yield from ifc_file_cls.initialize_finder(self.paths.finder) 

77 ifc_files_unsorted.append(ifc_file_cls) 

78 t_load_end = time.time() 

79 t_loading = round(t_load_end - t_load_start, 2) 

80 self.logger.info(f"Loaded {total_ifc_path.name} for Domain " 

81 f"{ifc_domain.name}. " 

82 f"This took {t_loading} seconds") 

83 for file in ifc_files_unsorted: 

84 ifc_files_dict[file.domain.name].append(file) 

85 for domain in ('arch', 'hydraulic', 'ventilation'): 

86 ifc_files.extend(ifc_files_dict[domain]) 

87 if not ifc_files: 

88 self.logger.error("No ifc found in project folder.") 

89 raise AssertionError("No ifc found. Check '%s'" % base_path) 

90 elif len(ifc_files) < len(ifc_files_unsorted): 

91 self.logger.warning( 

92 "Not all ifc files were added for further " 

93 "processing. IFCDomain may not be recognized.") 

94 raise AssertionError("Not all ifc processed. Check '%s'" % 

95 base_path) 

96 self.logger.info(f"Loaded {len(ifc_files)} IFC-files.") 

97 return ifc_files