Skip to content

Instantly share code, notes, and snippets.

@ysangkok
Created July 5, 2017 13:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save ysangkok/8aa7ab1c3207536518f3c3bf5f664880 to your computer and use it in GitHub Desktop.
Save ysangkok/8aa7ab1c3207536518f3c3bf5f664880 to your computer and use it in GitHub Desktop.
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