From ee288bf7f9ec7798d2c9dc76622cbfaa657a278a Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 6 Apr 2020 11:59:28 +1000 Subject: [PATCH] Implement Project setup MicroMVD steps in BIMTester --- src/ifcbimtester/bimtester.py | 16 ++-- src/ifcbimtester/features/steps/steps.py | 98 +++++++++++++++++++++--- src/ifcblenderexport/getIfcElements.py | 1 + 3 files changed, 100 insertions(+), 15 deletions(-) diff --git a/src/ifcbimtester/bimtester.py b/src/ifcbimtester/bimtester.py index 0c7b1acc2e..3ac4bd1650 100644 --- a/src/ifcbimtester/bimtester.py +++ b/src/ifcbimtester/bimtester.py @@ -18,12 +18,16 @@ import shutil from pathlib import Path +try: + # PyInstaller creates a temp folder and stores path in _MEIPASS + base_path = sys._MEIPASS + is_dist = True +except Exception: + base_path = os.path.abspath(".") + is_dist = False + + def get_resource_path(relative_path): - try: - # PyInstaller creates a temp folder and stores path in _MEIPASS - base_path = sys._MEIPASS - except Exception: - base_path = os.path.abspath(".") return os.path.join(base_path, relative_path) @@ -41,7 +45,7 @@ def run_tests(args): def get_features(args): has_features = False - if os.path.exists('features'): + if os.path.exists('features') and is_dist: shutil.copytree('features', get_resource_path('features')) has_features = True for f in os.listdir('.'): diff --git a/src/ifcbimtester/features/steps/steps.py b/src/ifcbimtester/features/steps/steps.py index f1604dc7bd..0d54d561de 100644 --- a/src/ifcbimtester/features/steps/steps.py +++ b/src/ifcbimtester/features/steps/steps.py @@ -11,6 +11,8 @@ class IfcFile(object): @classmethod def get(cls): + if not cls.file: + assert False, 'No file was loaded, so this requirement cannot be checked' return cls.file @classmethod @@ -31,9 +33,22 @@ class IfcFile(object): return prop +# Project setup MicroMVD + + @step('The IFC file "{file}" must be provided') def step_impl(context, file): - IfcFile.load(file) + try: + IfcFile.load(file) + except: + assert False, f'The file {file} could not be loaded' + + +@step('IFC data must use the {schema} schema') +def step_impl(context, schema): + assert IfcFile.get().schema == schema, \ + 'We expected a schema of {} but instead got {}'.format( + schema, IfcFile.get().schema) @step('The IFC file "{file}" is exempt from being provided') @@ -41,9 +56,79 @@ def step_impl(context, file): pass -@step('IFC data must use the {schema} schema') -def step_impl(context, schema): - assert IfcFile.get().schema == schema +@step('No further requirements are specified because {reason}') +def step_impl(context, reason): + pass + + +@step('The project name, code, or short identifier must be "{value}"') +def step_impl(context, value): + project_value = getattr(IfcFile.get().by_type('IfcProject')[0], 'Name') + assert project_value == value, 'We expected a value of "{}" but instead got "{}"'.format( + value, project_value) + + +@step('The project must have a longer form name of "{value}"') +def step_impl(context, value): + project_value = getattr(IfcFile.get().by_type('IfcProject')[0], 'LongName') + assert project_value == value, 'We expected a value of "{}" but instead got "{}"'.format( + value, project_value) + + +@step('The project must be described as "{value}"') +def step_impl(context, value): + project_value = getattr(IfcFile.get().by_type('IfcProject')[0], 'Description') + assert project_value == value, 'We expected a value of "{}" but instead got "{}"'.format( + value, project_value) + + +@step('The project must be categorised under "{value}"') +def step_impl(context, value): + project_value = getattr(IfcFile.get().by_type('IfcProject')[0], 'ObjectType') + assert project_value == value, 'We expected a value of "{}" but instead got "{}"'.format( + value, project_value) + + +@step('The project must contain information about the "{value}" phase') +def step_impl(context, value): + project_value = getattr(IfcFile.get().by_type('IfcProject')[0], 'Phase') + assert project_value == value, 'We expected a value of "{}" but instead got "{}"'.format( + value, project_value) + + +@step('The project must contain 3D geometry representing the shape of objects') +def step_impl(context): + assert get_subcontext('Body', 'Model', 'MODEL_VIEW') + + +@step('The project must contain 3D geometry representing clearance zones') +def step_impl(context): + assert get_subcontext('Clearance', 'Model', 'MODEL_VIEW') + + +@step('The project must contain 3D geometry representing the center of gravity of objects') +def step_impl(context): + assert get_subcontext('CoG', 'Model', 'MODEL_VIEW') + + +@step('The project must contain 3D geometry representing the object bounding boxes') +def step_impl(context): + assert get_subcontext('Box', 'Model', 'MODEL_VIEW') + + +def get_subcontext(identifier, type, target_view): + project = IfcFile.get().by_type('IfcProject')[0] + for rep_context in project.RepresentationContexts: + for subcontext in rep_context.HasSubContexts: + if subcontext.ContextIdentifier == identifier \ + and subcontext.ContextType == type \ + and subcontext.TargetView == target_view: + return True + assert False, 'The subcontext with identifier {}, type {}, and target view {} could not be found'.format( + identifier, type, target_view) + + +# Custom MicroMVD @step('the element {id} is an {ifc_class}') @@ -56,11 +141,6 @@ def step_impl(context, id, reason): assert not IfcFile.get().by_id(id) -@step('No further requirements are specified because {reason}') -def step_impl(context, reason): - pass - - @step(u'there is at least one {ifc_class} element') def step_impl(context, ifc_class): assert len(IfcFile.get().by_type(ifc_class)) >= 1 diff --git a/src/ifcblenderexport/getIfcElements.py b/src/ifcblenderexport/getIfcElements.py index bad85d2ccc..487ed288ce 100644 --- a/src/ifcblenderexport/getIfcElements.py +++ b/src/ifcblenderexport/getIfcElements.py @@ -146,6 +146,7 @@ class IFC2X3Extractor(IFC4Extractor): return [] filename_filters = { + 'IfcContext_IFC4.json': ['IfcContext'], 'IfcElement_IFC4.json': ['IfcElement'], 'IfcSpatialElement_IFC4.json': ['IfcSpatialElement'], 'IfcStructural_IFC4.json': ['IfcStructuralActivity', 'IfcStructuralItem'],