@@ -93,34 +93,6 @@ def run(self, ifc_files: [IfcFileClass]):
9393 # checks are domain specific
9494 # Reset class based on domain to run the right check.
9595 # Not pretty but works. This might be refactored in #170
96- if ifc_file .domain == IFCDomain .hydraulic :
97- self .logger .info (f"Processing HVAC-IfcCheck" ) # todo
98- elif ifc_file .domain == IFCDomain .arch :
99- self .logger .info (f"Processing BPS-IfcCheck" ) # todo
100- self .__class__ = CheckIfcBPS
101- self .__class__ .__init__ (self , self .playground )
102- self .paths = paths # TODO needed in if loop, here need better solution
103- elif ifc_file .domain == IFCDomain .unknown :
104- self .logger .info (f"No domain specified for ifc file "
105- f"{ ifc_file .ifc_file_name } , not processing "
106- f"any checks" )
107- return
108- else :
109- self .logger .info (
110- f"For the Domain { ifc_file .domain } no specific checks are"
111- f" implemented currently. Just running the basic checks."
112- f"" )
113-
114- ## begin copy form old ifc check (only tempory until new structure is working)
115- # prepare data for checking (filering)
116-
117- self .sub_inst = ifc_file .file .by_type (self .sub_inst_cls )
118-
119- # checking itself
120- self .error_summary_sub_inst = self .check_inst (
121- self .validate_sub_inst , self .sub_inst )
122-
123- ## end copy form old ifc check (only tempory until new structure is working)
12496
12597 # check uniqueness of GUIDs
12698 self .all_guids_unique , self .double_guids = CheckLogicBase .run_check_guid_unique (ifc_file )
@@ -141,55 +113,41 @@ def run(self, ifc_files: [IfcFileClass]):
141113 # critical: if loaded IFC is not IFC4
142114 if self .version_error :
143115 self .logger .critical (f"ifc Version is not fitting. Should be IFC4, but here: " + self .ifc_version )
144- # write reportes self made checks
145- base_name = f"/{ ifc_file .domain .name .upper ()} _" \
146- f"{ ifc_file .ifc_file_name [:- 4 ]} "
147- self ._write_errors_to_html_table (base_name , ifc_file .domain )
148116
149- ###### old ifc check, maybe stay here
150- @staticmethod
151- def check_inst (validation_function : Callable , elements : list ):
152- """Uses sb_validation/ports/elements functions in order to check each
153- one and adds error to dictionary if object has errors. Combines the
154- (error) return of the specific validation function with the key (mostly
155- the GlobalID).
117+ # prepare data for checking (filering)
118+ self .sub_inst = ifc_file .file .by_type (self .sub_inst_cls )
156119
157- Args: validation_function: function that compiles all the
158- validations to be performed on the object (sb/port/instance) elements:
159- list containing all objects to be evaluates
120+ if ifc_file .domain == IFCDomain .hydraulic :
121+ self .logger .info (f"Processing HVAC-IfcCheck" ) # todo
122+ elif ifc_file .domain == IFCDomain .arch :
123+ self .logger .info (f"Processing BPS-IfcCheck" ) # todo
124+ # checking itself
125+ chlb = CheckLogicBase ()
126+ self .error_summary_sub_inst = chlb .check_inst (
127+ chlb .validate_sub_inst , self .sub_inst )
128+ self .paths = paths # TODO needed in if loop, here need better solution
129+ elif ifc_file .domain == IFCDomain .unknown :
130+ self .logger .info (f"No domain specified for ifc file "
131+ f"{ ifc_file .ifc_file_name } , not processing "
132+ f"any checks" )
133+ return
134+ else :
135+ self .logger .info (
136+ f"For the Domain { ifc_file .domain } no specific checks are"
137+ f" implemented currently. Just running the basic checks."
138+ f"" )
160139
161- Returns:
162- summary: summarized dictionary of errors, where the key is the
163- GUID + the ifc_type
140+ ## begin copy form old ifc check (only tempory until new structure is working)
164141
165- """
166- summary = {}
167- for inst in elements :
168- error = validation_function (inst )
169- if len (error ) > 0 :
170- if hasattr (inst , 'GlobalId' ):
171- key = inst .GlobalId + ' ' + inst .is_a ()
172- else :
173- key = inst .is_a ()
174- summary .update ({key : error })
175- return summary
176142
177- @staticmethod
178- def apply_validation_function (fct : bool , err_name : str , error : list ):
179- """
180- Function to apply a validation to an instance, space boundary or
181- port, it stores the error to the list of errors.
182143
183- Args:
184- fct: validation function to be applied
185- err_name: string that define the error
186- error: list of errors
144+ ## end copy form old ifc check (only tempory until new structure is working)
187145
188- """
189- if not fct :
190- error .append (err_name )
146+ # write reportes self made checks
147+ base_name = f"/{ ifc_file .domain .name .upper ()} _" \
148+ f"{ ifc_file .ifc_file_name [:- 4 ]} "
149+ self ._write_errors_to_html_table (base_name , ifc_file .domain )
191150
192- ###### old ifc check, maybe stay here
193151
194152 def validate_sub_inst (self , sub_inst : list ) -> list :
195153 raise NotImplementedError
@@ -370,7 +328,6 @@ def _write_errors_to_html_table(self, base_name: str, domain: IFCDomain):
370328 webbrowser .open (f"file://{ out_file .buffer .name } " )
371329
372330
373-
374331class CheckIfcBPS (CheckIfc ):
375332 """
376333 Check an IFC file, for a number of conditions (missing information,
@@ -449,6 +406,12 @@ class CheckLogicBase():
449406 useful for all checking use cases.
450407 """
451408
409+ def __init__ (self ):
410+ # used for preparing data for checking, is filder keyword
411+ self .sub_inst_cls = 'IfcRelSpaceBoundary'
412+ self .plugin = bps
413+ self .space_ndicator = True
414+
452415 def run_check_guid_unique (ifc_file ) -> (bool , dict ):
453416 """check the uniqueness of the guids of the IFC file
454417
@@ -541,6 +504,108 @@ def run_check_ifc_version(ifc: ifcos.file) -> (bool, str):
541504 return (version_error , schema )
542505
543506
507+ ###### old ifc check, maybe stay here
508+ @staticmethod
509+ def check_inst (validation_function : Callable , elements : list ):
510+ """Uses sb_validation/ports/elements functions in order to check each
511+ one and adds error to dictionary if object has errors. Combines the
512+ (error) return of the specific validation function with the key (mostly
513+ the GlobalID).
514+
515+ Args: validation_function: function that compiles all the
516+ validations to be performed on the object (sb/port/instance) elements:
517+ list containing all objects to be evaluates
518+
519+ Returns:
520+ summary: summarized dictionary of errors, where the key is the
521+ GUID + the ifc_type
522+
523+ """
524+ summary = {}
525+ for inst in elements :
526+ error = validation_function (inst )
527+ if len (error ) > 0 :
528+ if hasattr (inst , 'GlobalId' ):
529+ key = inst .GlobalId + ' ' + inst .is_a ()
530+ else :
531+ key = inst .is_a ()
532+ summary .update ({key : error })
533+ return summary
534+
535+ @staticmethod
536+ def apply_validation_function (fct : bool , err_name : str , error : list ):
537+ """
538+ Function to apply a validation to an instance, space boundary or
539+ port, it stores the error to the list of errors.
540+
541+ Args:
542+ fct: validation function to be applied
543+ err_name: string that define the error
544+ error: list of errors
545+
546+ """
547+ if not fct :
548+ error .append (err_name )
549+
550+ ###### old ifc check, maybe stay here
551+
552+ @staticmethod
553+ def _check_rel_space (bound : entity_instance ):
554+ """
555+ Check that the space boundary relating space exists and has the
556+ correct class.
557+
558+ Args:
559+ bound: Space boundary IFC instance
560+
561+ Returns:
562+ True: if check succeeds
563+ False: if check fails
564+ """
565+ return any (
566+ [bound .RelatingSpace .is_a ('IfcSpace' ) or
567+ bound .RelatingSpace .is_a ('IfcExternalSpatialElement' )])
568+
569+ @staticmethod
570+ def _check_rel_building_elem (bound : entity_instance ):
571+ """
572+ Check that the space boundary related building element exists and has
573+ the correct class.
574+
575+ Args:
576+ bound: Space boundary IFC instance
577+
578+ Returns:
579+ True: if check succeeds
580+ False: if check fails
581+ """
582+ if bound .RelatedBuildingElement is not None :
583+ return bound .RelatedBuildingElement .is_a ('IfcElement' )
584+
585+ def validate_sub_inst (self , bound : entity_instance ) -> list :
586+ """
587+ Validation function for a space boundary that compiles all validation
588+ functions.
589+
590+ Args:
591+ bound: ifc space boundary entity
592+
593+ Returns:
594+ error: list of errors found in the ifc space boundaries
595+ """
596+ error = []
597+ self .apply_validation_function (self ._check_rel_space (bound ),
598+ 'RelatingSpace - '
599+ 'The space boundary does not have a '
600+ 'relating space associated' , error )
601+ self .apply_validation_function (self ._check_rel_building_elem (bound ),
602+ 'RelatedBuildingElement - '
603+ 'The space boundary does not have a '
604+ 'related building element associated' ,
605+ error )
606+ return error
607+
608+
544609class CheckLogicBPS (CheckLogicBase ):
545610 """Provides additional logic for ifc files checking regarding BPS."""
546611
0 commit comments