Created
July 5, 2017 13:29
-
-
Save ysangkok/8aa7ab1c3207536518f3c3bf5f664880 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
import sys | |
import os.path | |
import ifcopenshell | |
import itertools | |
import json | |
def chunks2(iterable,size,filler=None): | |
it = itertools.chain(iterable,itertools.repeat(filler,size-1)) | |
chunk = tuple(itertools.islice(it,size)) | |
while len(chunk) == size: | |
yield chunk | |
chunk = tuple(itertools.islice(it,size)) | |
class IfcTypeDict(dict): | |
def __missing__(self, key): | |
value = self[key] = ifcopenshell.create_entity(key).wrapped_data.get_attribute_names() | |
return value | |
typeDict = IfcTypeDict() | |
assert typeDict["IfcWall"] == ('GlobalId', 'OwnerHistory', 'Name', 'Description', 'ObjectType', 'ObjectPlacement', 'Representation', 'Tag') | |
nodes = [] | |
edges = [] | |
#wallid = None | |
ourLabel = sys.argv[2] | |
f = ifcopenshell.open(sys.argv[1]) | |
for el in f: | |
tid = el.id() | |
cls = el.is_a() | |
pairs = [] | |
keys = [] | |
try: | |
keys = [x for x in el.get_info() if x not in ["type", "id"]] | |
except RuntimeError: | |
# we actually can't catch this, but try anyway | |
pass | |
for key in keys: | |
val = el[key] | |
if any(hasattr(val,"is_a") and val.is_a(thisTyp) for thisTyp in ["IfcBoolean", "IfcLabel", "IfcText", "IfcReal"]): | |
val = val.wrappedValue | |
if type(val) not in (str, bool, float): | |
continue | |
pairs.append((key, val)) | |
nodes.append((tid, cls, pairs)) | |
for i in range(len(el)): | |
try: | |
el[i] | |
except RuntimeError as e: | |
if str(e) != "Entity not found": | |
print("ID", tid, e, file=sys.stderr) | |
continue | |
if isinstance(el[i], ifcopenshell.entity_instance): | |
if el[i].id() != 0: | |
edges.append((tid, el[i].id(), typeDict[cls][i])) | |
continue | |
else: | |
print("attribute " + typeDict[cls][i] + " of " + str(tid) + " is zero", file=sys.stderr) | |
try: | |
iter(el[i]) | |
except TypeError: | |
continue | |
destinations = [x.id() for x in el[i] if isinstance(x, ifcopenshell.entity_instance)] | |
for connectedTo in destinations: | |
edges.append((tid, connectedTo, typeDict[cls][i])) | |
if len(nodes) == 0: | |
print("no nodes in file", file=sys.stderr) | |
sys.exit(1) | |
indexes = set(["nid", "cls"]) | |
for chunk in chunks2(nodes, 100): | |
idx = 0 | |
print("CREATE ", end="") | |
for i in chunk: | |
if i is None: continue | |
nId, cls, pairs = i | |
if idx != 0: print(",",end="") | |
idx = idx + 1 | |
pairsStr = "" | |
for k,v in pairs: | |
indexes.add(k) | |
pairsStr += ", " + k + ": " + json.dumps(v) | |
print("(a" + str(idx) + ":" + ourLabel + " { nid: " + str(nId) + ",cls: '" + cls + "'" + pairsStr + " })", end="") | |
print(";") | |
for idxName in indexes: | |
print("CREATE INDEX on :" + ourLabel + "(" + idxName + ");") | |
for (nId1, nId2, relType) in edges: | |
print(""" MATCH (a:{:s}),(b:{:s}) WHERE a.nid = {:d} AND b.nid = {:d} CREATE (a)-[r:{:s}]->(b) RETURN r; """.format(ourLabel, ourLabel, nId1, nId2, relType)) | |
#print("MATCH a=(first:IfcNode {nid: " + str(wallid) + "})-[:RELTYPE*1..2]-(other {cls: \"IFCWINDOW\"}) RETURN distinct other;") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment