mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 05:52:33 +00:00
Fix #1300. New IfcOpenShell.util.type module for checking applicable type classes.
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# See bug #1300. Dodgy quick results that we should rebuild later.
|
||||
import json
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.schema
|
||||
|
||||
|
||||
filepath = "IFC4.exp"
|
||||
schema2x3 = ifcopenshell.ifcopenshell_wrapper.schema_by_name("IFC2X3")
|
||||
schema4 = ifcopenshell.ifcopenshell_wrapper.schema_by_name("IFC4")
|
||||
|
||||
entity_to_type_map = {}
|
||||
|
||||
entity = None
|
||||
is_in_where_rule = False
|
||||
|
||||
with open(filepath) as fp:
|
||||
line = fp.readline()
|
||||
while line:
|
||||
if "ENTITY " in line:
|
||||
entity = line[len("ENTITY ") : -1]
|
||||
elif "END_ENTITY" in line:
|
||||
is_in_where_rule = False
|
||||
elif entity and "CorrectTypeAssigned" in line:
|
||||
is_in_where_rule = True
|
||||
elif entity and is_in_where_rule and "IN TYPEOF" in line and "RelatingType" in line:
|
||||
type_class = line.split("'")[1].split(".")[1]
|
||||
entity_to_type_map.setdefault(entity, []).append(type_class)
|
||||
line = fp.readline()
|
||||
|
||||
# This type of hacky express parsing doesn't accomodate subtypes, so...
|
||||
|
||||
|
||||
def get_inherited_map(declaration):
|
||||
if not ifcopenshell.util.schema.is_a(declaration, "IfcObject"):
|
||||
return
|
||||
if declaration.supertype().name() in entity_to_type_map:
|
||||
return entity_to_type_map[declaration.supertype().name()]
|
||||
return get_inherited_map(declaration.supertype())
|
||||
|
||||
|
||||
for declaration in schema4.declarations():
|
||||
if not hasattr(declaration, "supertype"):
|
||||
continue
|
||||
if not ifcopenshell.util.schema.is_a(declaration, "IfcObject"):
|
||||
continue
|
||||
if declaration.is_abstract():
|
||||
continue
|
||||
if declaration.name() in entity_to_type_map:
|
||||
continue
|
||||
inherited_map = get_inherited_map(declaration)
|
||||
if inherited_map:
|
||||
entity_to_type_map[declaration.name()] = inherited_map
|
||||
|
||||
type_to_entity_map = {value: [key] for key in entity_to_type_map for value in entity_to_type_map[key]}
|
||||
|
||||
# IFC2X3 doesn't seem to define this in EXPRESS, so let's just guess
|
||||
|
||||
entity_to_type_map2x3 = {}
|
||||
|
||||
|
||||
def guess_type_declaration(declaration):
|
||||
if not ifcopenshell.util.schema.is_a(declaration, "IfcObject"):
|
||||
return
|
||||
|
||||
try:
|
||||
type_declaration = schema2x3.declaration_by_name(declaration.name() + "Type")
|
||||
return type_declaration
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
type_declaration = schema2x3.declaration_by_name(declaration.name() + "Style")
|
||||
return type_declaration
|
||||
except:
|
||||
pass
|
||||
|
||||
return guess_type_declaration(declaration.supertype())
|
||||
|
||||
|
||||
for declaration in schema2x3.declarations():
|
||||
if not hasattr(declaration, "supertype"):
|
||||
continue
|
||||
type_declaration = guess_type_declaration(declaration)
|
||||
if not type_declaration:
|
||||
continue
|
||||
if not type_declaration.is_abstract():
|
||||
entity_to_type_map2x3.setdefault(declaration.name(), []).append(type_declaration.name())
|
||||
for subtype in type_declaration.subtypes():
|
||||
if not subtype.is_abstract():
|
||||
entity_to_type_map2x3.setdefault(declaration.name(), []).append(subtype.name())
|
||||
|
||||
type_to_entity_map2x3 = {value: [key] for key in entity_to_type_map2x3 for value in entity_to_type_map2x3[key]}
|
||||
|
||||
|
||||
with open("entity_to_type_map_4.json", "w") as f:
|
||||
json.dump(entity_to_type_map, f, indent=4)
|
||||
|
||||
|
||||
with open("entity_to_type_map_2x3.json", "w") as f:
|
||||
json.dump(entity_to_type_map2x3, f, indent=4)
|
||||
Reference in New Issue
Block a user