@@ -46,7 +46,9 @@ def __init__(self, playground: Playground):
4646 self .elements : list = []
4747 self .ps_summary : dict = {}
4848 self .ifc_units : dict = {}
49- self .sub_inst_cls = None # uses for filerting prepare check
49+ # TODO maybe not needed her, because set in logic class
50+ # uses for filerting prepare check
51+ self .sub_inst_cls = None
5052 self .plugin = None
5153
5254 def run (self , ifc_files : [IfcFileClass ]):
@@ -93,34 +95,6 @@ def run(self, ifc_files: [IfcFileClass]):
9395 # checks are domain specific
9496 # Reset class based on domain to run the right check.
9597 # 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)
12498
12599 # check uniqueness of GUIDs
126100 self .all_guids_unique , self .double_guids = CheckLogicBase .run_check_guid_unique (ifc_file )
@@ -141,55 +115,40 @@ def run(self, ifc_files: [IfcFileClass]):
141115 # critical: if loaded IFC is not IFC4
142116 if self .version_error :
143117 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 )
148-
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).
156118
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
119+ if ifc_file .domain == IFCDomain .hydraulic :
120+ self .logger .info (f"Processing HVAC-IfcCheck" ) # todo
121+ elif ifc_file .domain == IFCDomain .arch :
122+ self .logger .info (f"Processing BPS-IfcCheck" ) # todo
123+ # checking itself
124+ chlb = CheckLogicBase ()
125+ # prepare data for checking (filering)
126+ self .sub_inst = ifc_file .file .by_type (chlb .sub_inst_cls )
127+ self .error_summary_sub_inst = chlb .check_inst (
128+ chlb .validate_sub_inst , self .sub_inst )
129+ self .paths = paths # TODO needed in if loop, here need better solution
130+ elif ifc_file .domain == IFCDomain .unknown :
131+ self .logger .info (f"No domain specified for ifc file "
132+ f"{ ifc_file .ifc_file_name } , not processing "
133+ f"any checks" )
134+ return
135+ else :
136+ self .logger .info (
137+ f"For the Domain { ifc_file .domain } no specific checks are"
138+ f" implemented currently. Just running the basic checks."
139+ f"" )
160140
161- Returns:
162- summary: summarized dictionary of errors, where the key is the
163- GUID + the ifc_type
141+ ## begin copy form old ifc check (only tempory until new structure is working)
164142
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
176143
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.
182144
183- Args:
184- fct: validation function to be applied
185- err_name: string that define the error
186- error: list of errors
145+ ## end copy form old ifc check (only tempory until new structure is working)
187146
188- """
189- if not fct :
190- error .append (err_name )
147+ # write reportes self made checks
148+ base_name = f"/{ ifc_file .domain .name .upper ()} _" \
149+ f"{ ifc_file .ifc_file_name [:- 4 ]} "
150+ self ._write_errors_to_html_table (base_name , ifc_file .domain )
191151
192- ###### old ifc check, maybe stay here
193152
194153 def validate_sub_inst (self , sub_inst : list ) -> list :
195154 raise NotImplementedError
@@ -370,7 +329,6 @@ def _write_errors_to_html_table(self, base_name: str, domain: IFCDomain):
370329 webbrowser .open (f"file://{ out_file .buffer .name } " )
371330
372331
373-
374332class CheckIfcBPS (CheckIfc ):
375333 """
376334 Check an IFC file, for a number of conditions (missing information,
@@ -449,6 +407,12 @@ class CheckLogicBase():
449407 useful for all checking use cases.
450408 """
451409
410+ def __init__ (self ):
411+ # used for preparing data for checking, is filder keyword
412+ self .sub_inst_cls = 'IfcRelSpaceBoundary'
413+ self .plugin = bps
414+ self .space_ndicator = True
415+
452416 def run_check_guid_unique (ifc_file ) -> (bool , dict ):
453417 """check the uniqueness of the guids of the IFC file
454418
@@ -541,6 +505,108 @@ def run_check_ifc_version(ifc: ifcos.file) -> (bool, str):
541505 return (version_error , schema )
542506
543507
508+ ###### old ifc check, maybe stay here
509+ @staticmethod
510+ def check_inst (validation_function : Callable , elements : list ):
511+ """Uses sb_validation/ports/elements functions in order to check each
512+ one and adds error to dictionary if object has errors. Combines the
513+ (error) return of the specific validation function with the key (mostly
514+ the GlobalID).
515+
516+ Args: validation_function: function that compiles all the
517+ validations to be performed on the object (sb/port/instance) elements:
518+ list containing all objects to be evaluates
519+
520+ Returns:
521+ summary: summarized dictionary of errors, where the key is the
522+ GUID + the ifc_type
523+
524+ """
525+ summary = {}
526+ for inst in elements :
527+ error = validation_function (inst )
528+ if len (error ) > 0 :
529+ if hasattr (inst , 'GlobalId' ):
530+ key = inst .GlobalId + ' ' + inst .is_a ()
531+ else :
532+ key = inst .is_a ()
533+ summary .update ({key : error })
534+ return summary
535+
536+ @staticmethod
537+ def apply_validation_function (fct : bool , err_name : str , error : list ):
538+ """
539+ Function to apply a validation to an instance, space boundary or
540+ port, it stores the error to the list of errors.
541+
542+ Args:
543+ fct: validation function to be applied
544+ err_name: string that define the error
545+ error: list of errors
546+
547+ """
548+ if not fct :
549+ error .append (err_name )
550+
551+ ###### old ifc check, maybe stay here
552+
553+ @staticmethod
554+ def _check_rel_space (bound : entity_instance ):
555+ """
556+ Check that the space boundary relating space exists and has the
557+ correct class.
558+
559+ Args:
560+ bound: Space boundary IFC instance
561+
562+ Returns:
563+ True: if check succeeds
564+ False: if check fails
565+ """
566+ return any (
567+ [bound .RelatingSpace .is_a ('IfcSpace' ) or
568+ bound .RelatingSpace .is_a ('IfcExternalSpatialElement' )])
569+
570+ @staticmethod
571+ def _check_rel_building_elem (bound : entity_instance ):
572+ """
573+ Check that the space boundary related building element exists and has
574+ the correct class.
575+
576+ Args:
577+ bound: Space boundary IFC instance
578+
579+ Returns:
580+ True: if check succeeds
581+ False: if check fails
582+ """
583+ if bound .RelatedBuildingElement is not None :
584+ return bound .RelatedBuildingElement .is_a ('IfcElement' )
585+
586+ def validate_sub_inst (self , bound : entity_instance ) -> list :
587+ """
588+ Validation function for a space boundary that compiles all validation
589+ functions.
590+
591+ Args:
592+ bound: ifc space boundary entity
593+
594+ Returns:
595+ error: list of errors found in the ifc space boundaries
596+ """
597+ error = []
598+ self .apply_validation_function (self ._check_rel_space (bound ),
599+ 'RelatingSpace - '
600+ 'The space boundary does not have a '
601+ 'relating space associated' , error )
602+ self .apply_validation_function (self ._check_rel_building_elem (bound ),
603+ 'RelatedBuildingElement - '
604+ 'The space boundary does not have a '
605+ 'related building element associated' ,
606+ error )
607+ return error
608+
609+
544610class CheckLogicBPS (CheckLogicBase ):
545611 """Provides additional logic for ifc files checking regarding BPS."""
546612
0 commit comments