forked from marwiss/IFC-graph
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathp2n.py
86 lines (80 loc) · 3.59 KB
/
p2n.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# 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
# 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