mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-17 02:49:12 +00:00
90 lines
3.6 KiB
Python
90 lines
3.6 KiB
Python
# The code in this file originally comes from the following article:
|
|
#
|
|
# IFC-graph for facilitating building information access and query
|
|
#
|
|
# Junxiang Zhu, Peng Wu *, Xiang Lei
|
|
#
|
|
# School of Design and the Built Environment, Curtin University,
|
|
# Bentley 6102, Western Australia, Australia
|
|
#
|
|
# The article was made available online 13 February 2023 in the journal
|
|
# Automation in Construction 148 (2023) 104778
|
|
#
|
|
# 0926-5805/© 2023 The Authors.
|
|
# Published by Elsevier B.V.
|
|
#
|
|
# This is an open access article under the CC BY license (http://creativecommons.org/licenses/by/4.0/).
|
|
#
|
|
# Some modifications have been made to the code.
|
|
#
|
|
|
|
from py2neo.data import Node, Relationship
|
|
from uuid import uuid4
|
|
import ifcopenshell
|
|
from py2neo import Graph
|
|
|
|
|
|
# Create the basic node with literal attributes and the class hierarchy
|
|
def create_pure_node_from_ifc_entity(ifc_entity, ifc_file, hierarchy=True):
|
|
node = Node()
|
|
if ifc_entity.id() != 0:
|
|
node['id'] = ifc_entity.id()
|
|
else:
|
|
node['id'] = str(uuid4())
|
|
node['name'] = ifc_entity.is_a()
|
|
if hierarchy:
|
|
for label in ifc_file.wrapped_data.types_with_super():
|
|
if ifc_entity.is_a(label):
|
|
node.add_label(label)
|
|
else:
|
|
node.add_label(ifc_entity.is_a())
|
|
attributes_type = ['ENTITY INSTANCE', 'AGGREGATE OF ENTITY INSTANCE', 'DERIVED']
|
|
for i in range(ifc_entity.__len__()):
|
|
if not ifc_entity.wrapped_data.get_argument_type(i) in attributes_type:
|
|
name = ifc_entity.wrapped_data.get_argument_name(i)
|
|
name_value = ifc_entity.wrapped_data.get_argument(i)
|
|
node[name]= name_value
|
|
node.__primarylabel__ = 'Root'
|
|
node.__primarykey__ = 'id'
|
|
return node
|
|
|
|
|
|
# Process literal attributes, entity attributes, and relationship attributes
|
|
def create_graph_from_ifc_entity_all(graph, ifc_entity, ifc_file):
|
|
node = create_pure_node_from_ifc_entity(ifc_entity, ifc_file)
|
|
graph.merge(node)
|
|
for i in range(ifc_entity.__len__()):
|
|
if ifc_entity[i]:
|
|
if ifc_entity.wrapped_data.get_argument_type(i) == 'ENTITY INSTANCE':
|
|
if ifc_entity[i].is_a() in ['IfcOwnerHistory'] and ifc_entity.is_a() != 'IfcProject':
|
|
continue
|
|
else:
|
|
sub_node = create_pure_node_from_ifc_entity(ifc_entity[i], ifc_file)
|
|
REL = Relationship(node, ifc_entity.wrapped_data.get_argument_name(i), sub_node)
|
|
graph.merge(REL)
|
|
elif ifc_entity.wrapped_data.get_argument_type(i) == 'AGGREGATE OF ENTITY INSTANCE':
|
|
for sub_entity in ifc_entity[i]:
|
|
sub_node = create_pure_node_from_ifc_entity(sub_entity, ifc_file)
|
|
REL = Relationship(node, ifc_entity.wrapped_data.get_argument_name(i), sub_node)
|
|
graph.merge(REL)
|
|
for rel_name in ifc_entity.wrapped_data.get_inverse_attribute_names():
|
|
if ifc_entity.wrapped_data.get_inverse(rel_name):
|
|
inverse_relations = ifc_entity.wrapped_data.get_inverse(rel_name)
|
|
for wrapped_rel_entity in inverse_relations:
|
|
rel_entity = ifc_file.by_id(wrapped_rel_entity.id())
|
|
sub_node = create_pure_node_from_ifc_entity(rel_entity, ifc_file)
|
|
REL = Relationship(node, rel_name, sub_node)
|
|
graph.merge(REL)
|
|
return
|
|
|
|
|
|
def create_full_graph(graph, ifc_file):
|
|
idx = 1
|
|
length = len(ifc_file.wrapped_data.entity_names())
|
|
for entity_id in ifc_file.wrapped_data.entity_names():
|
|
entity = ifc_file.by_id(entity_id)
|
|
print(idx, '/', length, entity)
|
|
create_graph_from_ifc_entity_all(graph, entity, ifc_file)
|
|
idx += 1
|
|
return
|