From 8439e5b46df0cae214614912fd8ffd2356fc38a9 Mon Sep 17 00:00:00 2001 From: thorade Date: Mon, 6 Nov 2017 09:10:28 +0100 Subject: [PATCH] autopep8 autopep8 --in-place --recursive --max-line-length=200 ifcopenshell --- .../ifcopenshell/__init__.py | 17 +- .../ifcopenshell/entity_instance.py | 29 +-- src/ifcopenshell-python/ifcopenshell/file.py | 24 ++- .../ifcopenshell/geom/app.py | 177 ++++++++++-------- .../ifcopenshell/geom/code_editor_pane.py | 34 ++-- .../ifcopenshell/geom/main.py | 54 ++++-- .../ifcopenshell/geom/occ_utils.py | 130 +++++++------ src/ifcopenshell-python/ifcopenshell/guid.py | 21 ++- .../ifcopenshell/template.py | 10 +- 9 files changed, 285 insertions(+), 211 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/__init__.py b/src/ifcopenshell-python/ifcopenshell/__init__.py index 98fc5e0f29..231eb26f5b 100644 --- a/src/ifcopenshell-python/ifcopenshell/__init__.py +++ b/src/ifcopenshell-python/ifcopenshell/__init__.py @@ -28,17 +28,17 @@ if hasattr(os, 'uname'): platform_system = os.uname()[0].lower() else: platform_system = 'windows' - + if sys.maxsize == (1 << 31) - 1: platform_architecture = '32bit' else: platform_architecture = '64bit' - + python_version_tuple = tuple(sys.version.split(' ')[0].split('.')) python_distribution = os.path.join(platform_system, - platform_architecture, - 'python%s.%s' % python_version_tuple[:2]) + platform_architecture, + 'python%s.%s' % python_version_tuple[:2]) sys.path.append(os.path.abspath(os.path.join( os.path.dirname(__file__), 'lib', python_distribution))) @@ -52,20 +52,23 @@ except Exception as e: traceback.print_exc() print('-' * 64) raise ImportError("IfcOpenShell not built for '%s'" % python_distribution) - + from . import guid from .file import file from .entity_instance import entity_instance + def open(fn=None): return file(ifcopenshell_wrapper.open(os.path.abspath(fn))) if fn else file() -def create_entity(type,*args,**kwargs): +def create_entity(type, *args, **kwargs): e = entity_instance(type) attrs = list(enumerate(args)) + \ [(e.wrapped_data.get_argument_index(name), arg) for name, arg in kwargs.items()] - for idx, arg in attrs: e[idx] = arg + for idx, arg in attrs: + e[idx] = arg return e + from .main import * diff --git a/src/ifcopenshell-python/ifcopenshell/entity_instance.py b/src/ifcopenshell-python/ifcopenshell/entity_instance.py index 04c6f9f012..5cde924d33 100644 --- a/src/ifcopenshell-python/ifcopenshell/entity_instance.py +++ b/src/ifcopenshell-python/ifcopenshell/entity_instance.py @@ -62,14 +62,16 @@ class entity_instance(object): @staticmethod def wrap_value(v): - wrap = lambda e: entity_instance(e) - is_instance = lambda e: isinstance(e, ifcopenshell_wrapper.entity_instance) + def wrap(e): return entity_instance(e) + + def is_instance(e): return isinstance(e, ifcopenshell_wrapper.entity_instance) return entity_instance.walk(is_instance, wrap, v) @staticmethod def unwrap_value(v): - unwrap = lambda e: e.wrapped_data - is_instance = lambda e: isinstance(e, entity_instance) + def unwrap(e): return e.wrapped_data + + def is_instance(e): return isinstance(e, entity_instance) return entity_instance.walk(is_instance, unwrap, v) def attribute_type(self, attr): @@ -95,7 +97,8 @@ class entity_instance(object): attr_type = attr_type.replace('Binary', 'String') attr_type = attr_type.replace('Enumeration', 'String') try: - if isinstance(value, unicode): value = value.encode("utf-8") + if isinstance(value, unicode): + value = value.encode("utf-8") except: pass try: @@ -117,7 +120,8 @@ class entity_instance(object): return self.wrapped_data.id() def __eq__(self, other): - if type(self) != type(other): return False + if type(self) != type(other): + return False return self.wrapped_data == other.wrapped_data def __hash__(self): @@ -144,17 +148,18 @@ class entity_instance(object): continue attr_value = self[i] if recursive: - is_instance = lambda e: isinstance(e, entity_instance) + def is_instance(e): return isinstance(e, entity_instance) + def get_info_(inst): # for ty in ignore: # if inst.is_a(ty): # return None return entity_instance.get_info(inst, - include_identifier=include_identifier, - recursive=recursive, - return_type=return_type, - ignore=ignore - ) + include_identifier=include_identifier, + recursive=recursive, + return_type=return_type, + ignore=ignore + ) attr_value = entity_instance.walk(is_instance, get_info_, attr_value) yield self.attribute_name(i), attr_value except: diff --git a/src/ifcopenshell-python/ifcopenshell/file.py b/src/ifcopenshell-python/ifcopenshell/file.py index 1c9132c110..73009b1b62 100644 --- a/src/ifcopenshell-python/ifcopenshell/file.py +++ b/src/ifcopenshell-python/ifcopenshell/file.py @@ -34,42 +34,58 @@ except NameError: # Python 3 or newer basestring = (str, bytes) + class file(object): def __init__(self, f=None): self.wrapped_data = f or ifcopenshell_wrapper.file() - def create_entity(self,type,*args,**kwargs): + + def create_entity(self, type, *args, **kwargs): e = entity_instance(type) self.wrapped_data.add(e.wrapped_data) e.wrapped_data.this.disown() attrs = list(enumerate(args)) + \ [(e.wrapped_data.get_argument_index(name), arg) for name, arg in kwargs.items()] - for idx, arg in attrs: e[idx] = arg + for idx, arg in attrs: + e[idx] = arg return e + def __getattr__(self, attr): - if attr[0:6] == 'create': return functools.partial(self.create_entity,attr[6:]) - else: return getattr(self.wrapped_data, attr) + if attr[0:6] == 'create': + return functools.partial(self.create_entity, attr[6:]) + else: + return getattr(self.wrapped_data, attr) + def __getitem__(self, key): if isinstance(key, numbers.Integral): return entity_instance(self.wrapped_data.by_id(key)) elif isinstance(key, basestring): return entity_instance(self.wrapped_data.by_guid(str(key))) + def by_id(self, id): return self[id] + def by_guid(self, guid): return self[guid] + def add(self, inst): inst.wrapped_data.this.disown() return entity_instance(self.wrapped_data.add(inst.wrapped_data)) + def by_type(self, type): return [entity_instance(e) for e in self.wrapped_data.by_type(type)] + def traverse(self, inst, max_levels=None): if max_levels is None: max_levels = -1 return [entity_instance(e) for e in self.wrapped_data.traverse(inst.wrapped_data, max_levels)] + def get_inverse(self, inst): return [entity_instance(e) for e in self.wrapped_data.get_inverse(inst.wrapped_data)] + def remove(self, inst): return self.wrapped_data.remove(inst.wrapped_data) + def __iter__(self): return iter(self[id] for id in self.wrapped_data.entity_names()) + @staticmethod def from_string(s): return file(ifcopenshell_wrapper.read(s)) diff --git a/src/ifcopenshell-python/ifcopenshell/geom/app.py b/src/ifcopenshell-python/ifcopenshell/geom/app.py index 27490ba176..7a1cea1355 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/app.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/app.py @@ -15,21 +15,27 @@ from collections import defaultdict, Iterable, OrderedDict os.environ['QT_API'] = 'pyqt4' try: from pyqode.qt import QtCore -except: pass +except: + pass from PyQt4 import QtGui, QtCore from .code_editor_pane import code_edit -try: from OCC.Display.pyqt4Display import qtViewer3d -except: +try: + from OCC.Display.pyqt4Display import qtViewer3d +except: import OCC.Display - try: import OCC.Display.backend - except: pass + try: + import OCC.Display.backend + except: + pass - try: OCC.Display.backend.get_backend("qt-pyqt4") - except: OCC.Display.backend.load_backend("qt-pyqt4") + try: + OCC.Display.backend.get_backend("qt-pyqt4") + except: + OCC.Display.backend.load_backend("qt-pyqt4") from OCC.Display.qtDisplay import qtViewer3d @@ -45,7 +51,8 @@ try: from PyQt4.QtCore import QString except ImportError: QString = str - + + class configuration(object): def __init__(self): try: @@ -53,19 +60,20 @@ class configuration(object): Cfg = ConfigParser.RawConfigParser except: import configparser - Cfg = lambda: configparser.ConfigParser(interpolation=None) - + + def Cfg(): return configparser.ConfigParser(interpolation=None) + conf_file = os.path.expanduser(os.path.join("~", ".ifcopenshell", "app", "snippets.conf")) if conf_file.startswith("~"): conf_file = None return - + self.config_encode = lambda s: s.replace("\\", "\\\\").replace("\n", "\n|") self.config_decode = lambda s: s.replace("\n|", "\n").replace("\\\\", "\\") - + if not os.path.exists(os.path.dirname(conf_file)): os.makedirs(os.path.dirname(conf_file)) - + if not os.path.exists(conf_file): config = Cfg() config.add_section("snippets") @@ -78,7 +86,7 @@ class configuration(object): for wall in model.by_type("IfcWall"): print ("wall with global id: "+str(wall.GlobalId)) """.lstrip())) - + config.set("snippets", "print properties of current selection", self.config_encode(""" ########################################################################### # A simple script that iterates over all IfcPropertySets of the currently # @@ -97,13 +105,13 @@ if selection: """.lstrip())) with open(conf_file, 'w') as configfile: config.write(configfile) - + self.config = Cfg() self.config.read(conf_file) - + def options(self, s): return OrderedDict([(k, self.config_decode(self.config.get(s, k))) for k in self.config.options(s)]) - + class application(QtGui.QApplication): @@ -111,19 +119,19 @@ class application(QtGui.QApplication): with two tree views and a graphical 3d view""" class abstract_treeview(QtGui.QTreeWidget): - + """Base class for the two treeview controls""" - + instanceSelected = QtCore.pyqtSignal([object]) instanceVisibilityChanged = QtCore.pyqtSignal([object, int]) instanceDisplayModeChanged = QtCore.pyqtSignal([object, int]) - + def __init__(self): QtGui.QTreeView.__init__(self) self.setColumnCount(len(self.ATTRIBUTES)) self.setHeaderLabels(self.ATTRIBUTES) self.children = defaultdict(list) - + def get_children(self, inst): c = [inst] i = 0 @@ -131,7 +139,7 @@ class application(QtGui.QApplication): c.extend(self.children[c[i]]) i += 1 return c - + def contextMenuEvent(self, event): menu = QtGui.QMenu(self) visibility = [menu.addAction("Show"), menu.addAction("Hide")] @@ -145,25 +153,26 @@ class application(QtGui.QApplication): self.instanceVisibilityChanged.emit(inst, visibility.index(action)) elif action in displaymode: self.instanceDisplayModeChanged.emit(inst, displaymode.index(action)) - + def clicked(self, index): inst = index.data(QtCore.Qt.UserRole) if hasattr(inst, 'toPyObject'): inst = inst.toPyObject() if inst: self.instanceSelected.emit(inst) - + def select(self, product): itm = self.product_to_item.get(product) - if itm is None: return - self.selectionModel().setCurrentIndex(itm, QtGui.QItemSelectionModel.SelectCurrent | QtGui.QItemSelectionModel.Rows); - + if itm is None: + return + self.selectionModel().setCurrentIndex(itm, QtGui.QItemSelectionModel.SelectCurrent | QtGui.QItemSelectionModel.Rows) + class decomposition_treeview(abstract_treeview): - + """Treeview with typical IFC decomposition relationships""" - + ATTRIBUTES = ['Entity', 'GlobalId', 'Name'] - + def parent(self, instance): if instance.is_a("IfcOpeningElement"): return instance.VoidsElements[0].RelatingBuildingElement @@ -178,7 +187,7 @@ class application(QtGui.QApplication): decompositions = instance.Decomposes if len(decompositions): return decompositions[0].RelatingObject - + def load_file(self, f, **kwargs): products = list(f.by_type("IfcProduct")) + list(f.by_type("IfcProject")) parents = list(map(self.parent, products)) @@ -203,13 +212,13 @@ class application(QtGui.QApplication): self.product_to_item = dict(zip(items.keys(), map(self.indexFromItem, items.values()))) self.connect(self, QtCore.SIGNAL("clicked(const QModelIndex &)"), self.clicked) self.expandAll() - + class type_treeview(abstract_treeview): - + """Treeview with typical IFC decomposition relationships""" - + ATTRIBUTES = ['Name'] - + def load_file(self, f, **kwargs): products = list(f.by_type("IfcProduct")) types = set(map(lambda i: i.is_a(), products)) @@ -217,31 +226,30 @@ class application(QtGui.QApplication): for t in types: def add(t): s = get_supertype(t) - if s: add(s) - s2, t2 = map(QString, (s,t)) + if s: + add(s) + s2, t2 = map(QString, (s, t)) if t2 not in items: itm = items[t2] = QtGui.QTreeWidgetItem(items.get(s2, self), [t2]) itm.setData(0, QtCore.Qt.UserRole, t2) self.children[s2].append(t2) add(t) - + for p in products: t = QString(p.is_a()) itm = items[p] = QtGui.QTreeWidgetItem(items.get(t, self), [p.Name or '']) itm.setData(0, QtCore.Qt.UserRole, t) self.children[t].append(p) - + self.product_to_item = dict(zip(items.keys(), map(self.indexFromItem, items.values()))) self.connect(self, QtCore.SIGNAL("clicked(const QModelIndex &)"), self.clicked) self.expandAll() - - class property_table(QtGui.QWidget): def __init__(self): QtGui.QWidget.__init__(self) - self.layout= QtGui.QVBoxLayout(self) + self.layout = QtGui.QVBoxLayout(self) self.setLayout(self.layout) self.scroll = QtGui.QScrollArea(self) self.layout.addWidget(self.scroll) @@ -252,9 +260,9 @@ class application(QtGui.QApplication): self.scroll.setWidget(self.scrollContent) self.prop_dict = {} - #triggered by selection event in either component of parent + # triggered by selection event in either component of parent def select(self, product): - + # Clear the old contents if any while self.scrollLayout.count(): child = self.scrollLayout.takeAt(0) @@ -266,47 +274,46 @@ class application(QtGui.QApplication): self.scroll.setWidgetResizable(True) prop_sets = self.prop_dict.get(str(product)) - + if prop_sets is not None: - for k,v in prop_sets: + for k, v in prop_sets: group_box = QtGui.QGroupBox() group_box.setTitle(k) group_layout = QtGui.QVBoxLayout() group_box.setLayout(group_layout) - + for name, value in v.items(): prop_name = str(name) - + value_str = value if hasattr(value_str, "wrappedValue"): value_str = value_str.wrappedValue - + if isinstance(value_str, unicode): value_str = value_str.encode('utf-8') else: value_str = str(value_str) - + if hasattr(value, "is_a"): type_str = " (%s)" % value.is_a() else: type_str = "" label = QtGui.QLabel("%s: %s%s" % (prop_name, value_str, type_str)) group_layout.addWidget(label) - + group_layout.addStretch() self.scrollLayout.addWidget(group_box) self.scrollLayout.addStretch() else: - label = QtGui.QLabel("No IfcPropertySets asscociated with selected entity instance" ) + label = QtGui.QLabel("No IfcPropertySets asscociated with selected entity instance") self.scrollLayout.addWidget(label) - def load_file(self, f, **kwargs): for p in f.by_type("IfcProduct"): propsets = [] - + def process_pset(prop_def): if prop_def is not None: prop_set_name = prop_def.Name @@ -314,36 +321,37 @@ class application(QtGui.QApplication): if prop_def.is_a("IfcElementQuantity"): for q in prop_def.Quantities: if q.is_a("IfcPhysicalSimpleQuantity"): - props[q.Name]=q[3] + props[q.Name] = q[3] elif prop_def.is_a("IfcPropertySet"): for prop in prop_def.HasProperties: if prop.is_a("IfcPropertySingleValue"): - props[prop.Name]=prop.NominalValue + props[prop.Name] = prop.NominalValue else: # Entity introduced in IFC4 # prop_def.is_a("IfcPreDefinedPropertySet"): for prop in range(4, len(prop_def)): - props[prop_def.attribute_name(prop)]=prop_def[prop] + props[prop_def.attribute_name(prop)] = prop_def[prop] return prop_set_name, props - + try: for is_def_by in p.IsDefinedBy: if is_def_by.is_a("IfcRelDefinesByProperties"): propsets.append(process_pset(is_def_by.RelatingPropertyDefinition)) elif is_def_by.is_a("IfcRelDefinesByType"): type_psets = is_def_by.RelatingType.HasPropertySets - if type_psets is None: continue + if type_psets is None: + continue for propset in type_psets: propsets.append(process_pset(propset)) except Exception as e: import traceback print("failed to load properties: {}".format(e)) traceback.print_exc() - + if len(propsets): self.prop_dict[str(p)] = propsets - - print ("property set dictionary has {} entries".format(len(self.prop_dict))) + + print("property set dictionary has {} entries".format(len(self.prop_dict))) class viewer(qtViewer3d): @@ -357,17 +365,20 @@ class application(QtGui.QApplication): yield ais.Shape() return shp = OCC.AIS.Handle_AIS_Shape.DownCast(ais_handle) - if not shp.IsNull(): yield shp.Shape() + if not shp.IsNull(): + yield shp.Shape() return mult = ais_handle if mult.IsNull(): shp = OCC.AIS.Handle_AIS_Shape.DownCast(ais_handle) - if not shp.IsNull(): yield shp + if not shp.IsNull(): + yield shp else: li = mult.GetObject().ConnectedTo() for i in range(li.Length()): - shp = OCC.AIS.Handle_AIS_Shape.DownCast(li.Value(i+1)) - if not shp.IsNull(): yield shp + shp = OCC.AIS.Handle_AIS_Shape.DownCast(li.Value(i + 1)) + if not shp.IsNull(): + yield shp return tuple(shp.HashCode(1 << 24) for shp in yield_shapes()) def __init__(self, widget): @@ -390,7 +401,8 @@ class application(QtGui.QApplication): v = self._display t = {0: time.time()} - def update(dt = None): + + def update(dt=None): t1 = time.time() if t1 - t[0] > (dt or -1): v.FitAll() @@ -408,7 +420,8 @@ class application(QtGui.QApplication): old_progress = -1 while True: - if terminate[0]: break + if terminate[0]: + break shape = it.get() product = f[shape.data.id] ais = display_shape(shape, viewer_handle=v) @@ -427,13 +440,14 @@ class application(QtGui.QApplication): break update(0.2) - print("\rOpened file in %.2f seconds%s" % (time.time() - t0, " "*25)) + print("\rOpened file in %.2f seconds%s" % (time.time() - t0, " " * 25)) update() def select(self, product): ais = self.product_to_ais.get(product) - if ais is None: return + if ais is None: + return v = self._display.Context v.ClearSelected(False) v.SetSelected(ais, True) @@ -509,7 +523,6 @@ class application(QtGui.QApplication): a.triggered.connect(callback) m.addAction(a) - def makeSelectionHandler(self, component): def handler(inst): for c in self.components: @@ -536,8 +549,8 @@ class application(QtGui.QApplication): self.editor = code_edit(self.canvas, configuration().options('snippets')) splitter2.addWidget(self.editor) splitter.addWidget(splitter2) - splitter.setSizes([200,600]) - splitter2.setSizes([400,200]) + splitter.setSizes([200, 600]) + splitter2.setSizes([400, 200]) self.window.setCentralWidget(splitter) self.canvas.initialize() self.components = [self.tree, self.tree2, self.canvas, self.propview, self.editor] @@ -562,27 +575,29 @@ class application(QtGui.QApplication): def change_displaymode(self, tree, inst, flag): insts = tree.get_children(inst) - self.canvas.toggle_wireframe(insts, flag) - + self.canvas.toggle_wireframe(insts, flag) + def start(self): self.window.show() sys.exit(self.exec_()) - + def browse(self): - filename = QtGui.QFileDialog.getOpenFileName(self.window, 'Open file',".","Industry Foundation Classes (*.ifc)") + filename = QtGui.QFileDialog.getOpenFileName(self.window, 'Open file', ".", "Industry Foundation Classes (*.ifc)") self.load(filename) - + def clear(self): self.canvas._display.Context.RemoveAll() self.tree.clear() self.files.clear() - + def load(self, fn): - if fn in self.files: return + if fn in self.files: + return f = open_ifc_file(str(fn)) self.files[fn] = f for c in self.components: c.load_file(f, setting=self.settings) - + + if __name__ == "__main__": application().start() diff --git a/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py b/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py index 7f28675ac3..b1fa4ffc15 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/code_editor_pane.py @@ -28,17 +28,17 @@ try: except: has_pyqode = False CodeEdit = QtWidgets.QPlainTextEdit - - + + class StdoutRedirector(object): '''A class for redirecting stdout to this Text widget.''' def __init__(self, widget): - self.widget=widget - self.isError = False + self.widget = widget + self.isError = False - def write(self,str): + def write(self, str): self.widget.moveCursor(QtGui.QTextCursor.End) if self.isError: self.widget.setTextColor(QtCore.Qt.red) @@ -60,37 +60,37 @@ class code_edit(QtGui.QWidget): def runCode(self): sys.stdout = StdoutRedirector(self.output) sys.stderr = StdoutRedirector(self.output) - sys.stderr.isError=True + sys.stderr.isError = True if not self.model: print("please load a model first", file=sys.stderr) else: self.c.enter(str(self.editor.toPlainText())) - + sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ - def select(self,product): - self.c = self.Console({'model':self.model, 'viewer':self.viewer, 'selection':product}) + def select(self, product): + self.c = self.Console({'model': self.model, 'viewer': self.viewer, 'selection': product}) - def __init__(self,viewer,snippets=None): - - self.model=None + def __init__(self, viewer, snippets=None): + + self.model = None self.viewer = viewer QtGui.QWidget.__init__(self) - self.layout= QtGui.QVBoxLayout(self) + self.layout = QtGui.QVBoxLayout(self) self.setLayout(self.layout) self.c = None - + self.tools = QtGui.QHBoxLayout(self) self.layout.addLayout(self.tools) - + self.runbutton = QtGui.QPushButton("Run") width = self.runbutton.fontMetrics().boundingRect("Run").width() + 20 self.runbutton.setMaximumWidth(width) self.tools.addWidget(self.runbutton) self.runbutton.clicked.connect(self.runCode) - + editor = CodeEdit() if has_pyqode: editor.backend.start(server.__file__) @@ -150,5 +150,5 @@ class code_edit(QtGui.QWidget): output = [] sys.stdout = StdoutRedirector(self.output) self.model = f - self.c = self.Console({'model':self.model, 'selection':None, 'viewer':self.viewer}) + self.c = self.Console({'model': self.model, 'selection': None, 'viewer': self.viewer}) sys.stdout = sys.__stdout__ diff --git a/src/ifcopenshell-python/ifcopenshell/geom/main.py b/src/ifcopenshell-python/ifcopenshell/geom/main.py index a542216a41..bb97ec96d3 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/main.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/main.py @@ -28,23 +28,34 @@ from .. import ifcopenshell_wrapper from ..file import file from ..entity_instance import entity_instance + def has_occ(): - try: import OCC.BRepTools - except: return False + try: + import OCC.BRepTools + except: + return False return True has_occ = has_occ() -wrap_shape_creation = lambda settings, shape: shape + + +def wrap_shape_creation(settings, shape): return shape + + if has_occ: from . import occ_utils as utils - wrap_shape_creation = lambda settings, shape: utils.create_shape_from_serialization(shape) if getattr(settings, 'use_python_opencascade', False) else shape + + def wrap_shape_creation(settings, shape): return utils.create_shape_from_serialization(shape) if getattr(settings, 'use_python_opencascade', False) else shape # Subclass the settings module to provide an additional # setting to enable pythonOCC when available + + class settings(ifcopenshell_wrapper.settings): if has_occ: USE_PYTHON_OPENCASCADE = -1 + def set(self, *args): setting, value = args if setting == settings.USE_PYTHON_OPENCASCADE: @@ -54,11 +65,12 @@ class settings(ifcopenshell_wrapper.settings): self.use_python_opencascade = value else: ifcopenshell_wrapper.settings.set(self, *args) - -# Hide templating precision to the user by choosing based on Python's + + +# Hide templating precision to the user by choosing based on Python's # internal float type. This is probably always going to be a double. for ty in (ifcopenshell_wrapper.iterator_single_precision, ifcopenshell_wrapper.iterator_double_precision): - if ty.mantissa_size() == sys.float_info.mant_dig: + if ty.mantissa_size() == sys.float_info.mant_dig: _iterator = ty @@ -77,18 +89,18 @@ class iterator(_iterator): class tree(ifcopenshell_wrapper.tree): - + def __init__(self, file=None, settings=None): args = [self] - if file is not None: + if file is not None: args.append(file.wrapped_data) if settings is not None: args.append(settings) ifcopenshell_wrapper.tree.__init__(*args) - + def add_file(self, file, settings): ifcopenshell_wrapper.tree.add_file(self, file.wrapped_data, settings) - + def select(self, value, **kwargs): def unwrap(value): if isinstance(value, entity_instance): @@ -104,7 +116,7 @@ class tree(ifcopenshell_wrapper.tree): if isinstance(value, OCC.TopoDS.TopoDS_Shape): args[1] = utils.serialize_shape(value) return [entity_instance(e) for e in ifcopenshell_wrapper.tree.select(*args)] - + def select_box(self, value, **kwargs): def unwrap(value): if isinstance(value, entity_instance): @@ -120,14 +132,14 @@ class tree(ifcopenshell_wrapper.tree): return [entity_instance(e) for e in ifcopenshell_wrapper.tree.select_box(*args)] -def create_shape(settings, inst, repr=None): +def create_shape(settings, inst, repr=None): return wrap_shape_creation( settings, ifcopenshell_wrapper.create_shape( - settings, + settings, inst.wrapped_data, repr.wrapped_data if repr is not None else None - )) + )) def iterate(settings, filename): @@ -135,12 +147,15 @@ def iterate(settings, filename): if it.initialize(): while True: yield it.get() - if not it.next(): break - + if not it.next(): + break + + def make_shape_function(fn): - entity_instance_or_none = lambda e: None if e is None else entity_instance(e) + def entity_instance_or_none(e): return None if e is None else entity_instance(e) if has_occ: import OCC.TopoDS + def _(string_or_shape, *args): if isinstance(string_or_shape, OCC.TopoDS.TopoDS_Shape): string_or_shape = utils.serialize_shape(string_or_shape) @@ -149,6 +164,7 @@ def make_shape_function(fn): def _(string, *args): return entity_instance_or_none(fn(string, *args)) return _ - + + serialise = make_shape_function(ifcopenshell_wrapper.serialise) tesselate = make_shape_function(ifcopenshell_wrapper.tesselate) diff --git a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py index 33c1e00b5d..a5ed911b97 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py @@ -30,44 +30,47 @@ shape_tuple = namedtuple('shape_tuple', ('data', 'geometry', 'styles')) handle, main_loop, add_menu, add_function_to_menu = None, None, None, None DEFAULT_STYLES = { - "DEFAULT" : (.7 , .7, .7 ), - "IfcWall" : (.8 , .8, .8 ), - "IfcSite" : (.75, .8, .65 ), - "IfcSlab" : (.4 , .4, .4 ), - "IfcWallStandardCase": (.9 , .9, .9 ), - "IfcWall" : (.9 , .9, .9 ), - "IfcWindow" : (.75, .8, .75, .3), - "IfcDoor" : (.55, .3, .15 ), - "IfcBeam" : (.75, .7, .7 ), - "IfcRailing" : (.65, .6, .6 ), - "IfcMember" : (.65, .6, .6 ), - "IfcPlate" : (.8 , .8, .8 ) + "DEFAULT": (.7, .7, .7), + "IfcWall": (.8, .8, .8), + "IfcSite": (.75, .8, .65), + "IfcSlab": (.4, .4, .4), + "IfcWallStandardCase": (.9, .9, .9), + "IfcWall": (.9, .9, .9), + "IfcWindow": (.75, .8, .75, .3), + "IfcDoor": (.55, .3, .15), + "IfcBeam": (.75, .7, .7), + "IfcRailing": (.65, .6, .6), + "IfcMember": (.65, .6, .6), + "IfcPlate": (.8, .8, .8) } + def initialize_display(): import OCC.V3d import OCC.Display.SimpleGui - + global handle, main_loop, add_menu, add_function_to_menu handle, main_loop, add_menu, add_function_to_menu = OCC.Display.SimpleGui.init_display() def setup(): viewer_handle = handle.GetViewer() viewer = viewer_handle.GetObject() - + def lights(): viewer.InitActiveLights() while True: - try: active_light = viewer.ActiveLight() - except: break + try: + active_light = viewer.ActiveLight() + except: + break yield active_light viewer.NextActiveLights() - + lights = list(lights()) for l in lights: viewer.DelLight(l) - - for dir in [(3,2,1), (-1,-2,-3)]: + + for dir in [(3, 2, 1), (-1, -2, -3)]: light = OCC.V3d.V3d_DirectionalLight(viewer_handle) light.SetDirection(*dir) viewer.SetLightOn(light.GetHandle()) @@ -75,38 +78,42 @@ def initialize_display(): setup() return handle + def yield_subshapes(shape): import OCC.TopoDS - + it = OCC.TopoDS.TopoDS_Iterator(shape) while it.More(): yield it.Value() it.Next() - + + def display_shape(shape, clr=None, viewer_handle=None): import OCC.gp import OCC.AIS import OCC.Quantity - - if viewer_handle is None: viewer_handle = handle - if isinstance(shape, shape_tuple): + if viewer_handle is None: + viewer_handle = handle + + if isinstance(shape, shape_tuple): shape, representation = shape.geometry, shape - else: representation = None - + else: + representation = None + material = OCC.Graphic3d.Graphic3d_MaterialAspect(OCC.Graphic3d.Graphic3d_NOM_PLASTER) material.SetDiffuse(1) - + if representation and not clr: if len(set(representation.styles)) == 1: clr = representation.styles[0] if min(clr) < 0. or max(clr) > 1.: clr = DEFAULT_STYLES.get(representation.data.type, DEFAULT_STYLES["DEFAULT"]) - + if clr: ais = OCC.AIS.AIS_Shape(shape) ais.SetMaterial(material) - + if isinstance(clr, str): qclr = getattr(OCC.Quantity, "Quantity_NOC_%s" % clr.upper(), getattr(OCC.Quantity, "Quantity_NOC_%s1" % clr.upper(), None)) if qclr is None: @@ -120,16 +127,16 @@ def display_shape(shape, clr=None, viewer_handle=None): qclr = clr else: raise Exception("Object of type %r cannot be used as a color." % type(clr)) - + ais.SetColor(qclr) if isinstance(clr, tuple) and len(clr) == 4 and clr[3] < 1.: ais.SetTransparency(1. - clr[3]) elif representation: default_style_applied = None - + ais = OCC.AIS.AIS_MultipleConnectedShape(shape) - + subshapes = list(yield_subshapes(shape)) lens = len(representation.styles), len(subshapes) if lens[0] != lens[1]: @@ -145,14 +152,15 @@ def display_shape(shape, clr=None, viewer_handle=None): if len(stl) == 4 and stl[3] < 1.: subshape.SetTransparency(1. - stl[3]) ais.Connect(subshape.GetHandle()) - + # For some reason it is necessary to set transparency here again # in order for transparency to be rendered on the subshape. applied_styles = representation.styles if default_style_applied: - if len(default_style_applied) == 3: default_style_applied += (1.,) + if len(default_style_applied) == 3: + default_style_applied += (1.,) applied_styles += (default_style_applied,) - + if len(applied_styles): # The only way for this not to be true if is the entire shape is NULL min_transp = min(map(operator.itemgetter(3), applied_styles)) @@ -162,14 +170,14 @@ def display_shape(shape, clr=None, viewer_handle=None): else: ais = OCC.AIS.AIS_Shape(shape) ais.SetMaterial(material) - - r = lambda: random.random() * 0.3 + 0.7 + + def r(): return random.random() * 0.3 + 0.7 clr = OCC.Quantity.Quantity_Color(r(), r(), r(), OCC.Quantity.Quantity_TOC_RGB) ais.SetColor(clr) - + ais_handle = ais.GetHandle() viewer_handle.Context.Display(ais_handle, False) - + return ais_handle @@ -179,47 +187,51 @@ def set_shape_transparency(ais, t): def get_bounding_box_center(bbox): import OCC.gp - - bbmin = [0.]*3; bbmax = [0.]*3 - bbmin[0], bbmin[1], bbmin[2], bbmax[0], bbmax[1], bbmax[2] = bbox.Get() - return OCC.gp.gp_Pnt(*map(lambda xy: (xy[0]+xy[1])/2., zip(bbmin, bbmax))) - + bbmin = [0.] * 3 + bbmax = [0.] * 3 + bbmin[0], bbmin[1], bbmin[2], bbmax[0], bbmax[1], bbmax[2] = bbox.Get() + return OCC.gp.gp_Pnt(*map(lambda xy: (xy[0] + xy[1]) / 2., zip(bbmin, bbmax))) + + def serialize_shape(shape): import OCC.BRepTools - + shapes = OCC.BRepTools.BRepTools_ShapeSet() shapes.Add(shape) return shapes.WriteToString() - + + def create_shape_from_serialization(brep_object): import OCC.BRepTools - + brep_data, occ_shape, styles = None, None, () - + is_product_shape = True try: brep_data = brep_object.geometry.brep_data styles = brep_object.geometry.surface_styles - except: - try: + except: + try: brep_data = brep_object.brep_data styles = brep_object.surface_styles is_product_shape = False - except: pass - - styles = tuple(styles[i:i+4] for i in range(0, len(styles), 4)) - - if not brep_data: return shape_tuple(brep_object, None, styles) - + except: + pass + + styles = tuple(styles[i:i + 4] for i in range(0, len(styles), 4)) + + if not brep_data: + return shape_tuple(brep_object, None, styles) + try: ss = OCC.BRepTools.BRepTools_ShapeSet() ss.ReadFromString(brep_data) occ_shape = ss.Shape(ss.NbShapes()) - except: pass - + except: + pass + if is_product_shape: return shape_tuple(brep_object, occ_shape, styles) else: return occ_shape - diff --git a/src/ifcopenshell-python/ifcopenshell/guid.py b/src/ifcopenshell-python/ifcopenshell/guid.py index c768a2cf81..2bbafb6eb8 100644 --- a/src/ifcopenshell-python/ifcopenshell/guid.py +++ b/src/ifcopenshell-python/ifcopenshell/guid.py @@ -28,23 +28,28 @@ from functools import reduce chars = string.digits + string.ascii_uppercase + string.ascii_lowercase + '_$' + def compress(g): - bs = [int(g[i:i+2], 16) for i in range(0, len(g), 2)] + bs = [int(g[i:i + 2], 16) for i in range(0, len(g), 2)] + def b64(v, l=4): - return ''.join([chars[(v // (64**i))%64] for i in range(l)][::-1]) - return ''.join([b64(bs[0], 2)] + [b64((bs[i] << 16) + (bs[i+1] << 8) + bs[i+2]) for i in range(1,16,3)]) + return ''.join([chars[(v // (64**i)) % 64] for i in range(l)][::-1]) + return ''.join([b64(bs[0], 2)] + [b64((bs[i] << 16) + (bs[i + 1] << 8) + bs[i + 2]) for i in range(1, 16, 3)]) + def expand(g): def b64(v): return reduce(lambda a, b: a * 64 + b, map(lambda c: chars.index(c), v)) bs = [b64(g[0:2])] for i in range(5): - d = b64(g[2+4*i:6+4*i]) - bs += [(d >> (8*(2-j)))%256 for j in range(3)] - return ''.join(['%02x'%b for b in bs]) + d = b64(g[2 + 4 * i:6 + 4 * i]) + bs += [(d >> (8 * (2 - j))) % 256 for j in range(3)] + return ''.join(['%02x' % b for b in bs]) + def split(g): - return '{%s-%s-%s-%s-%s}'%(g[:8], g[8:12], g[12:16], g[16:20], g[20:]) - + return '{%s-%s-%s-%s-%s}' % (g[:8], g[8:12], g[12:16], g[16:20], g[20:]) + + def new(): return compress(uuid.uuid4().hex) diff --git a/src/ifcopenshell-python/ifcopenshell/template.py b/src/ifcopenshell-python/ifcopenshell/template.py index 84d647c0fb..7e1dfa329a 100644 --- a/src/ifcopenshell-python/ifcopenshell/template.py +++ b/src/ifcopenshell-python/ifcopenshell/template.py @@ -70,15 +70,17 @@ DEFAULTS = { "timestring": lambda d: time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(d.get('timestamp') or time.time())) } -def create(filename=None, timestring=None, organization=None, creator=None,\ - schema_identifier=None, application_version=None, timestamp=None,\ + +def create(filename=None, timestring=None, organization=None, creator=None, + schema_identifier=None, application_version=None, timestamp=None, application=None, project_globalid=None, project_name=None): - + d = dict(locals()) + def _(): for var, value in d.items(): if value is None: yield var, DEFAULTS.get(var, lambda *args: '')(d) d.update(dict(_())) - + return file.from_string(TEMPLATE % d)