For an IFC population model `f` (or filepath to such a file) validate whether the entity attribute values are correctly supplied. As this is a function that is applied after a file has been parsed, certain types of errors in syntax, duplicate numeric identifiers or invalidate entity nam
(f: Union[ifcopenshell.file, str], logger: Union[Logger, json_logger], express_rules=False)
| 399 | |
| 400 | |
| 401 | def validate(f: Union[ifcopenshell.file, str], logger: Union[Logger, json_logger], express_rules=False) -> None: |
| 402 | """ |
| 403 | For an IFC population model `f` (or filepath to such a file) validate whether the entity attribute values are correctly supplied. As this |
| 404 | is a function that is applied after a file has been parsed, certain types of errors in syntax, duplicate |
| 405 | numeric identifiers or invalidate entity names are not caught by this function. Some of these might have been |
| 406 | logged and can be retrieved by calling `ifcopenshell.get_log()`. A verification of the type, entity and global |
| 407 | WHERE rules is also not implemented. |
| 408 | |
| 409 | For every entity instance in the model, it is checked that the entity is not abstract that every attribute value |
| 410 | is of the correct type and that the inverse attributes are of the correct cardinality. |
| 411 | |
| 412 | Express simple types are checked for their valuation type. For select types it is asserted that the value conforms |
| 413 | to one of the leaves. For enumerations it is checked that the value is indeed on of the items. For aggregations it |
| 414 | is checked that the elements and the cardinality conforms. Type declarations (IfcInteger which is an integer) are |
| 415 | unpacked until one of the above cases is reached. |
| 416 | |
| 417 | It is recommended to supply the path to the file, so that internal C++ errors reported during the parse stage |
| 418 | are also captured. |
| 419 | |
| 420 | Example: |
| 421 | |
| 422 | .. code:: python |
| 423 | |
| 424 | logger = ifcopenshell.validate.json_logger() |
| 425 | ifcopenshell.validate.validate("/path/to/model.ifc", logger, express_rules=True) |
| 426 | from pprint import pprint |
| 427 | pprint(logger.statements) |
| 428 | """ |
| 429 | |
| 430 | # Originally there was no way in Python to distinguish on an entity instance attribute value whether the |
| 431 | # value supplied in the model was NIL ($) or 'missing because derived in subtype' (*). For validation this |
| 432 | # however this may be important, and hence a feature switch has been implemented to return *-values as |
| 433 | # instances of a dedicated type `ifcopenshell.ifcopenshell_wrapper.attribute_value_derived`. |
| 434 | attribute_value_derived_org = ifcopenshell.ifcopenshell_wrapper.get_feature("use_attribute_value_derived") |
| 435 | ifcopenshell.ifcopenshell_wrapper.set_feature("use_attribute_value_derived", True) |
| 436 | |
| 437 | filename = None |
| 438 | |
| 439 | if isinstance(logger, json_logger): |
| 440 | logger.set_state("type", "schema") |
| 441 | |
| 442 | if not isinstance(f, ifcopenshell.file): |
| 443 | # get_log() clears log existing output |
| 444 | ifcopenshell.get_log() |
| 445 | # @todo restore log format |
| 446 | ifcopenshell.ifcopenshell_wrapper.set_log_format_json() |
| 447 | |
| 448 | filename = f |
| 449 | try: |
| 450 | f = ifcopenshell.open(f, readonly=True) |
| 451 | except ifcopenshell.SchemaError as e: |
| 452 | current_dir_files = {fn.lower(): fn for fn in os.listdir(".")} |
| 453 | schema_name = str(e).split(" ")[-1].lower() |
| 454 | exists = current_dir_files.get(schema_name + ".exp") |
| 455 | if exists: |
| 456 | schema = ifcopenshell.express.parse(exists) |
| 457 | ifcopenshell.register_schema(schema) |
| 458 |
no test coverage detected