Arch: import IFC, split relation table method

This commit is contained in:
Bernd Hahnebach
2019-08-21 07:17:58 +02:00
parent 658a29fd12
commit df4ee8f25d
2 changed files with 104 additions and 64 deletions

View File

@@ -291,10 +291,21 @@ def insert(filename,docname,skip=[],only=[],root=None):
# build all needed tables
if DEBUG: print("Building relationships table...",end="")
objects,prodrepr,additions,groups,subtractions,colors,shapes, \
structshapes,mattable,sharedobjects,parametrics,profiles, \
sites,buildings,floors,products,openings,annotations,materials, \
style_material_id = importIFCHelper.buildRelationships(ifcfile,ROOT_ELEMENT)
objects, shapes, structshapes, sharedobjects, parametrics, profiles = {}, {}, {}, {}, {}, {}
sites = ifcfile.by_type("IfcSite")
buildings = ifcfile.by_type("IfcBuilding")
floors = ifcfile.by_type("IfcBuildingStorey")
openings = ifcfile.by_type("IfcOpeningElement")
materials = ifcfile.by_type("IfcMaterial")
products, annotations = importIFCHelper.buildRelProductsAnnotations(ifcfile, ROOT_ELEMENT)
# TODO for the following tables might be better use inverse attributes, done for properties
# see https://forum.freecadweb.org/viewtopic.php?f=39&t=37892
prodrepr = importIFCHelper.buildRelProductRepresentation(ifcfile)
additions = importIFCHelper.buildRelAdditions(ifcfile)
groups = importIFCHelper.buildRelGroups(ifcfile)
subtractions = importIFCHelper.buildRelSubtractions(ifcfile)
mattable = importIFCHelper.buildRelMattable(ifcfile)
colors, style_material_id = importIFCHelper.buildRelColors(ifcfile, prodrepr)
if DEBUG: print("done.")
# only import a list of IDs and their children, if defined

View File

@@ -77,55 +77,33 @@ class ProjectImporter:
return round(math.degrees(math.atan2(y, x)) - 90, 6)
# relation tables
def buildRelProductsAnnotations(ifcfile, root_element):
"""build the products and annotations relation table and"""
def buildRelationships(ifcfile,root_element):
"""Builds different tables from an IFC file"""
# building relations tables
# TODO use inverse attributes, see https://forum.freecadweb.org/viewtopic.php?f=39&t=37892
# done for properties
objects = {} # { id:object, ... }
prodrepr = {} # product/representations table
additions = {} # { host:[child,...], ... }
groups = {} # { host:[child,...], ... } # used in structural IFC
subtractions = [] # [ [opening,host], ... ]
colors = {} # { id:(r,g,b) }
shapes = {} # { id:shaoe } only used for merge mode
structshapes = {} # { id:shaoe } only used for merge mode
mattable = {} # { objid:matid }
sharedobjects = {} # { representationmapid:object }
parametrics = [] # a list of imported objects whose parametric relationships need processing after all objects have been created
profiles = {} # to store reused extrusion profiles {ifcid:fcobj,...}
style_material_id = {} # { style_entity_id: material_id) }
# gather easy entity types
sites = ifcfile.by_type("IfcSite")
buildings = ifcfile.by_type("IfcBuilding")
floors = ifcfile.by_type("IfcBuildingStorey")
# products
products = ifcfile.by_type(root_element)
openings = ifcfile.by_type("IfcOpeningElement")
annotations = ifcfile.by_type("IfcAnnotation")
materials = ifcfile.by_type("IfcMaterial")
for r in ifcfile.by_type("IfcRelContainedInSpatialStructure"):
additions.setdefault(r.RelatingStructure.id(),[]).extend([e.id() for e in r.RelatedElements])
for r in ifcfile.by_type("IfcRelAggregates"):
additions.setdefault(r.RelatingObject.id(),[]).extend([e.id() for e in r.RelatedObjects])
for r in ifcfile.by_type("IfcRelAssignsToGroup"):
groups.setdefault(r.RelatingGroup.id(),[]).extend([e.id() for e in r.RelatedObjects])
for r in ifcfile.by_type("IfcRelVoidsElement"):
subtractions.append([r.RelatedOpeningElement.id(), r.RelatingBuildingElement.id()])
for r in ifcfile.by_type("IfcRelAssociatesMaterial"):
for o in r.RelatedObjects:
if r.RelatingMaterial.is_a("IfcMaterial"):
mattable[o.id()] = r.RelatingMaterial.id()
elif r.RelatingMaterial.is_a("IfcMaterialLayer"):
mattable[o.id()] = r.RelatingMaterial.Material.id()
elif r.RelatingMaterial.is_a("IfcMaterialLayerSet"):
mattable[o.id()] = r.RelatingMaterial.MaterialLayers[0].Material.id()
elif r.RelatingMaterial.is_a("IfcMaterialLayerSetUsage"):
mattable[o.id()] = r.RelatingMaterial.ForLayerSet.MaterialLayers[0].Material.id()
# annotations
annotations = ifcfile.by_type("IfcAnnotation")
tp = []
for product in products:
if product.is_a("IfcGrid") and not (product in annotations):
annotations.append(product)
elif not (product in annotations):
tp.append(product)
# remove any leftover annotations from products
products = sorted(tp,key=lambda prod: prod.id())
return products, annotations
def buildRelProductRepresentation(ifcfile):
"""build the product/representations relation table"""
prodrepr = {} # product/representations table
for p in ifcfile.by_type("IfcProduct"):
if hasattr(p,"Representation"):
if p.Representation:
@@ -139,7 +117,70 @@ def buildRelationships(ifcfile,root_element):
if it1.MappingSource.MappedRepresentation.is_a("IfcShapeRepresentation"):
for it2 in it1.MappingSource.MappedRepresentation.Items:
prodrepr.setdefault(p.id(),[]).append(it2.id())
# colors
return prodrepr
def buildRelAdditions(ifcfile):
"""build the additions relation table"""
additions = {} # { host:[child,...], ... }
for r in ifcfile.by_type("IfcRelContainedInSpatialStructure"):
additions.setdefault(r.RelatingStructure.id(),[]).extend([e.id() for e in r.RelatedElements])
for r in ifcfile.by_type("IfcRelAggregates"):
additions.setdefault(r.RelatingObject.id(),[]).extend([e.id() for e in r.RelatedObjects])
return additions
def buildRelGroups(ifcfile):
"""build the groups relation table"""
groups = {} # { host:[child,...], ... } # used in structural IFC
for r in ifcfile.by_type("IfcRelAssignsToGroup"):
groups.setdefault(r.RelatingGroup.id(),[]).extend([e.id() for e in r.RelatedObjects])
return groups
def buildRelSubtractions(ifcfile):
"""build the subtractions relation table"""
subtractions = [] # [ [opening,host], ... ]
for r in ifcfile.by_type("IfcRelVoidsElement"):
subtractions.append([r.RelatedOpeningElement.id(), r.RelatingBuildingElement.id()])
return subtractions
def buildRelMattable(ifcfile):
"""build the mattable relation table"""
mattable = {} # { objid:matid }
for r in ifcfile.by_type("IfcRelAssociatesMaterial"):
for o in r.RelatedObjects:
if r.RelatingMaterial.is_a("IfcMaterial"):
mattable[o.id()] = r.RelatingMaterial.id()
elif r.RelatingMaterial.is_a("IfcMaterialLayer"):
mattable[o.id()] = r.RelatingMaterial.Material.id()
elif r.RelatingMaterial.is_a("IfcMaterialLayerSet"):
mattable[o.id()] = r.RelatingMaterial.MaterialLayers[0].Material.id()
elif r.RelatingMaterial.is_a("IfcMaterialLayerSetUsage"):
mattable[o.id()] = r.RelatingMaterial.ForLayerSet.MaterialLayers[0].Material.id()
return mattable
def buildRelColors(ifcfile, prodrepr):
"""build the colors relation table and"""
colors = {} # { id:(r,g,b) }
style_material_id = {} # { style_entity_id: material_id) }
style_color_rgb = {} # { style_entity_id: (r,g,b) }
for r in ifcfile.by_type("IfcStyledItem"):
if r.Styles:
@@ -168,19 +209,7 @@ def buildRelationships(ifcfile,root_element):
if k in style_color_rgb:
colors[style_material_id[k]] = style_color_rgb[k]
# remove any leftover annotations from products
tp = []
for product in products:
if product.is_a("IfcGrid") and not (product in annotations):
annotations.append(product)
elif not (product in annotations):
tp.append(product)
products = sorted(tp,key=lambda prod: prod.id())
return objects,prodrepr,additions,groups,subtractions,colors,shapes, \
structshapes,mattable,sharedobjects,parametrics,profiles, \
sites,buildings,floors,products,openings,annotations,materials, \
style_material_id
return colors, style_material_id
def getRelProperties(ifcfile):