Files
IfcOpenShell/src/exterior-shell-extractor/utils.py
T

117 lines
3.0 KiB
Python

import time
import operator
import datetime
import itertools
import functools
from functools import reduce
import ifcopenshell
def get_mem():
try:
import psutil
except:
return None
process = psutil.Process()
return process.memory_info().rss // 1024 // 1024
def trace(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
print(f"Function {func.__name__} started at {datetime.datetime.fromtimestamp(start_time)}")
if get_mem():
print(f"Process using {get_mem()} MB")
result = func(*args, **kwargs)
end_time = time.time()
print(f"Function {func.__name__} finished in {end_time - start_time}")
if get_mem():
print(f"Process using {get_mem()} MB")
return result
return wrapper
def to_tuple(eq):
try:
n = len(eq)
except:
n = oc_len(eq)
eq = [eq.get(i) for i in range(n)]
return tuple(eq)
to_double = lambda n: tuple(v.to_double() for v in to_tuple(n))
def oc_len(tup):
# @todo implement in C++
return int(type(tup).__name__.split("_")[-1])
make_default = lambda pairs: dict((k, [v[1] for v in vs]) for k, vs in itertools.groupby(pairs, key=operator.itemgetter(0)))
def dot(a, b):
a, b = to_tuple(a), to_tuple(b)
return reduce(operator.add, map(operator.mul, a, b))
def negate(sign):
def iden(tup):
return tup
def neg(tup):
return tuple(-v for v in to_tuple(tup))
return neg if sign == -1 else iden
def to_opaque(tup):
if len(tup) == 3:
v = ifcopenshell.ifcopenshell_wrapper.OpaqueCoordinate_3()
if len(tup) == 4:
v = ifcopenshell.ifcopenshell_wrapper.OpaqueCoordinate_4()
for i, vv in enumerate(tup):
v.set(i, vv)
return v
create_epeck = ifcopenshell.ifcopenshell_wrapper.create_epeck
epeck_cache = {}
double_cache = {}
def reserialize(v, to_double=False):
"""
Copy an arbitrarily precise rational from CGAL by serializing and
deserializing to string or double. Can be useful to flatten the
depth of operands, trim away precision or create non-reference counted
copies for use in multi-threaded contexts.
"""
st = v.to_string()
if to_double:
val = double_cache.get(st)
if val is not None:
return val
# @todo can we do this on the str?
stn = (-v).to_string()
val = double_cache.get(stn)
if val is not None:
return -val
d = create_epeck(v.to_double())
double_cache[st] = d
return d
else:
# this does seem to shave off a bit of RAM usage, but even better
# would be to not compute the result altogether, so cache tuples of
# operation and operands prior to evaluating. But we don't know
# how expensive the serialization to str is...
val = epeck_cache.get(st)
if val:
return val
ep = create_epeck(st)
epeck_cache[st] = ep
return ep