From 088354a96b1b8b8cd02132333b0002131cc9990e Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 19 Mar 2023 22:03:45 +1100 Subject: [PATCH 01/12] Fix critical bug where copied representations would be inefficiently or incorrectly replicated. --- .../ifcopenshell/util/element.py | 24 ++++++++++++++++--- .../test/util/test_element.py | 16 +++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/util/element.py b/src/ifcopenshell-python/ifcopenshell/util/element.py index ca75d91aeb..59f5a7c7d8 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/element.py +++ b/src/ifcopenshell-python/ifcopenshell/util/element.py @@ -808,7 +808,7 @@ def copy(ifc_file, element): return new -def copy_deep(ifc_file, element, exclude=None, exclude_callback=None): +def copy_deep(ifc_file, element, exclude=None, exclude_callback=None, copied_entities=None): """ Recursively copy an element and all of its directly related subelements. @@ -825,10 +825,22 @@ def copy_deep(ifc_file, element, exclude=None, exclude_callback=None): :param exclude_callback: A callback to determine whether or not to exclude an entity or not. Returns True to exclude and False to exclude. :type exclude_callback: function,optional + :param copied_entities: A dictionary of IDs as keys and entities as values + to reuse when coming across the same entity twice. This can typically + be left as None. + :type copied_entities: dict[int:ifcopenshell.entity_instance.entity_instance] :return: The newly copied element :rtype: ifcopenshell.entity_instance.entity_instance """ + if copied_entities is None: + copied_entities = {} + else: + copied_entity = copied_entities.get(element.id(), None) + if copied_entity: + return copied_entity new = ifc_file.create_entity(element.is_a()) + if element.id(): + copied_entities[element.id()] = new for i, attribute in enumerate(element): if attribute is None: continue @@ -838,7 +850,7 @@ def copy_deep(ifc_file, element, exclude=None, exclude_callback=None): elif exclude_callback and exclude_callback(attribute): pass else: - attribute = copy_deep(ifc_file, attribute, exclude=exclude) + attribute = copy_deep(ifc_file, attribute, exclude=exclude, copied_entities=copied_entities) elif isinstance(attribute, tuple) and attribute and isinstance(attribute[0], ifcopenshell.entity_instance): if exclude and any([attribute[0].is_a(e) for e in exclude]): pass @@ -847,7 +859,13 @@ def copy_deep(ifc_file, element, exclude=None, exclude_callback=None): else: attribute = list(attribute) for j, item in enumerate(attribute): - attribute[j] = copy_deep(ifc_file, item, exclude=exclude, exclude_callback=exclude_callback) + attribute[j] = copy_deep( + ifc_file, + item, + exclude=exclude, + exclude_callback=exclude_callback, + copied_entities=copied_entities, + ) if new.attribute_name(i) == "GlobalId": new[i] = ifcopenshell.guid.new() else: diff --git a/src/ifcopenshell-python/test/util/test_element.py b/src/ifcopenshell-python/test/util/test_element.py index 9d5a1f1589..798c06349f 100644 --- a/src/ifcopenshell-python/test/util/test_element.py +++ b/src/ifcopenshell-python/test/util/test_element.py @@ -707,3 +707,19 @@ class TestCopyDeepIFC4(test.bootstrap.IFC4): rel.RelatedObjects = [element] rel2 = subject.copy_deep(self.file, rel, exclude_callback=lambda x: x.is_a("IfcWall")) assert rel.RelatedObjects == rel2.RelatedObjects + + def test_copying_and_reusing_element_references(self): + points = self.file.createIfcCartesianPointList2D() + subelement1 = self.file.createIfcIndexedPolyCurve(points) + subelement2 = self.file.createIfcIndexedPolyCurve(points) + element = self.file.createIfcGeometricCurveSet([subelement1, subelement2]) + element2 = subject.copy_deep(self.file, element) + assert element2.Elements[0].Points.id() == element2.Elements[1].Points.id() + + def test_copying_primitive_entities(self): + element = self.file.createIfcIndexedPolyCurve( + Segments=(self.file.createIfcLineIndex((1, 2)), self.file.createIfcLineIndex((3, 4))) + ) + element2 = subject.copy_deep(self.file, element) + assert element2.Segments[0][0] == (1, 2) + assert element2.Segments[1][0] == (3, 4) From 00b18f67cf97d2ea3f03c1e826933020f20177c5 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Sun, 19 Mar 2023 12:46:15 +0100 Subject: [PATCH 02/12] #2685 indeterminate upper bound formatting --- src/ifcopenshell-python/ifcopenshell/validate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ifcopenshell-python/ifcopenshell/validate.py b/src/ifcopenshell-python/ifcopenshell/validate.py index 275459420a..73e5252e2f 100644 --- a/src/ifcopenshell-python/ifcopenshell/validate.py +++ b/src/ifcopenshell-python/ifcopenshell/validate.py @@ -125,7 +125,7 @@ def assert_valid_inverse(attr, val, schema): aggr = attr.type_of_aggregation_string().upper() if aggr: - aggr_str = f'{aggr} [{b1}:{b2}] OF ' + aggr_str = f'{aggr} [{b1}:{'?' if b2 == -1 else b2}] OF ' else: aggr_str = '' From 5fcfbac4a30068657b3b8a1a6c84f9e40dc0d399 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Sun, 19 Mar 2023 13:24:27 +0100 Subject: [PATCH 03/12] Update validate.py --- src/ifcopenshell-python/ifcopenshell/validate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ifcopenshell-python/ifcopenshell/validate.py b/src/ifcopenshell-python/ifcopenshell/validate.py index 73e5252e2f..0343c2e9d1 100644 --- a/src/ifcopenshell-python/ifcopenshell/validate.py +++ b/src/ifcopenshell-python/ifcopenshell/validate.py @@ -125,7 +125,7 @@ def assert_valid_inverse(attr, val, schema): aggr = attr.type_of_aggregation_string().upper() if aggr: - aggr_str = f'{aggr} [{b1}:{'?' if b2 == -1 else b2}] OF ' + aggr_str = f'{aggr} [{b1}:{"?" if b2 == -1 else b2}] OF ' else: aggr_str = '' From ff806dc6e4f102ca53fbf981f3a5be3fd37fd649 Mon Sep 17 00:00:00 2001 From: Sigma Dimensions <79010126+myoualid@users.noreply.github.com> Date: Sun, 19 Mar 2023 13:30:35 +0000 Subject: [PATCH 04/12] improve covering qto calculation --- .../pset/calc_quantity_function_mapper.py | 6 +-- .../bim/module/pset/qto_calculator.py | 43 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/pset/calc_quantity_function_mapper.py b/src/blenderbim/blenderbim/bim/module/pset/calc_quantity_function_mapper.py index 145e4f89f9..d366033073 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/calc_quantity_function_mapper.py +++ b/src/blenderbim/blenderbim/bim/module/pset/calc_quantity_function_mapper.py @@ -133,9 +133,9 @@ mapper = { 'NetWeight' : None, }, 'Qto_CoveringBaseQuantities' : { - 'Width' : "get_height", - 'GrossArea' : "get_gross_footprint_area", - 'NetArea' : "get_net_footprint_area", + 'Width' : "get_covering_width", + 'GrossArea' : "get_covering_gross_area", + 'NetArea' : "get_covering_net_area", }, 'Qto_PipeSegmentBaseQuantities' : { 'Length' : "get_length", diff --git a/src/blenderbim/blenderbim/bim/module/pset/qto_calculator.py b/src/blenderbim/blenderbim/bim/module/pset/qto_calculator.py index 59daa75c66..a64cc934c6 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/qto_calculator.py +++ b/src/blenderbim/blenderbim/bim/module/pset/qto_calculator.py @@ -136,6 +136,49 @@ class QtoCalculator: OBB_gross_footprint_area = self.get_gross_footprint_area(OBB_obj) return OBB_gross_footprint_area + def get_parametric_axis(self, obj): + relating_type = ifcopenshell.util.element.get_type(tool.Ifc.get_entity(obj)) + if relating_type: + parametric = ifcopenshell.util.element.get_psets(relating_type).get("EPset_Parametric") + if parametric: + layer_set_direction = None + layer_set_direction = parametric.get("LayerSetDirection", layer_set_direction) + if layer_set_direction == "AXIS2": + return "AXIS2" + elif layer_set_direction == "AXIS3": + return "AXIS3" + else: + return None + return None + + def get_covering_gross_area(self, obj): + get_parametric_axis = self.get_parametric_axis(obj) + if not get_parametric_axis: + return self.get_gross_footprint_area(obj) + elif get_parametric_axis == "AXIS2": + return self.get_gross_surface_area(obj) + elif get_parametric_axis == "AXIS3": + return self.get_gross_footprint_area(obj) + + def get_covering_net_area(self, obj): + get_parametric_axis = self.get_parametric_axis(obj) + if not get_parametric_axis: + return self.get_net_footprint_area(obj) + elif get_parametric_axis == "AXIS2": + return self.get_net_surface_area(obj) + elif get_parametric_axis == "AXIS3": + return self.get_net_footprint_area(obj) + return self.get_net_footprint_area(obj) + + def get_covering_width(self, obj): + get_parametric_axis = self.get_parametric_axis(obj) + if not get_parametric_axis: + return self.get_net_footprint_area(obj) + elif get_parametric_axis == "AXIS2": + return self.get_width(obj) + elif get_parametric_axis == "AXIS3": + return self.get_height(obj) + def get_width(self, o): """_summary_: Returns the width of the object bounding box From 0e03a01f61a7be62906cc2791be6d75d339256b2 Mon Sep 17 00:00:00 2001 From: Sigma Dimensions <79010126+myoualid@users.noreply.github.com> Date: Sun, 19 Mar 2023 14:11:32 +0000 Subject: [PATCH 05/12] fixing previous commit #ff806dc --- .../blenderbim/bim/module/pset/qto_calculator.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/pset/qto_calculator.py b/src/blenderbim/blenderbim/bim/module/pset/qto_calculator.py index a64cc934c6..9c566095de 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/qto_calculator.py +++ b/src/blenderbim/blenderbim/bim/module/pset/qto_calculator.py @@ -156,7 +156,7 @@ class QtoCalculator: if not get_parametric_axis: return self.get_gross_footprint_area(obj) elif get_parametric_axis == "AXIS2": - return self.get_gross_surface_area(obj) + return self.get_gross_side_area(obj) elif get_parametric_axis == "AXIS3": return self.get_gross_footprint_area(obj) @@ -165,15 +165,14 @@ class QtoCalculator: if not get_parametric_axis: return self.get_net_footprint_area(obj) elif get_parametric_axis == "AXIS2": - return self.get_net_surface_area(obj) + return self.get_net_side_area(obj) elif get_parametric_axis == "AXIS3": return self.get_net_footprint_area(obj) - return self.get_net_footprint_area(obj) def get_covering_width(self, obj): get_parametric_axis = self.get_parametric_axis(obj) if not get_parametric_axis: - return self.get_net_footprint_area(obj) + return self.get_height(obj) elif get_parametric_axis == "AXIS2": return self.get_width(obj) elif get_parametric_axis == "AXIS3": From 05bdc962a3a825a20f5b1ae923ea1b93a3dd669d Mon Sep 17 00:00:00 2001 From: Massimo Fabbro Date: Sun, 19 Mar 2023 17:00:06 +0100 Subject: [PATCH 06/12] Now it's possible to see the selected object related cost items and related quantities in qto n-panel --- .../blenderbim/bim/module/qto/ui.py | 35 +++++++++++-- src/blenderbim/blenderbim/core/tool.py | 3 +- src/blenderbim/blenderbim/tool/qto.py | 51 +++++++++++++++++++ src/blenderbim/test/tool/test_qto.py | 16 ++++++ 4 files changed, 101 insertions(+), 4 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/qto/ui.py b/src/blenderbim/blenderbim/bim/module/qto/ui.py index 6386859d88..43e5e0b584 100644 --- a/src/blenderbim/blenderbim/bim/module/qto/ui.py +++ b/src/blenderbim/blenderbim/bim/module/qto/ui.py @@ -16,10 +16,11 @@ # You should have received a copy of the GNU General Public License # along with BlenderBIM Add-on. If not, see . -from bpy.types import Panel +import bpy +from blenderbim.bim.module.qto.data import QtoData -class BIM_PT_qto_utilities(Panel): +class BIM_PT_qto_utilities(bpy.types.Panel): bl_idname = "BIM_PT_qto_utilities" bl_label = "Quantity Take-off" bl_options = {"DEFAULT_CLOSED"} @@ -28,6 +29,9 @@ class BIM_PT_qto_utilities(Panel): bl_category = "BlenderBIM" def draw(self, context): + if not QtoData.is_loaded: + QtoData.load() + layout = self.layout props = context.scene.BIMQtoProperties @@ -51,9 +55,34 @@ class BIM_PT_qto_utilities(Panel): row.prop(props, "qto_name", text="") row.prop(props, "prop_name", text="") row.operator("bim.quantify_objects", icon="COPYDOWN", text="") - + row = layout.row(align=True) row.operator("bim.assign_objects_base_qto") row = layout.row(align=True) row.operator("bim.calculate_all_quantities", icon="MOD_EDGESPLIT") + + if context.selected_objects: + row = layout.row(align=True) + row.label(text=f"Relating Cost Item:") + + if QtoData.data['has_cost_item']: + for relating_cost_item in QtoData.data['relating_cost_items']: + row.label(text=f"\n") + row = layout.row(align=True) + row.label(text=f"Cost item name:") + row.label(text=f"{relating_cost_item['cost_item_name']}") + row = layout.row(align=True) + row.label(text=f"Quantity name:") + row.label(text=f"{relating_cost_item['quantity_name']}") + row = layout.row(align=True) + row.label(text=f"Quantity value:") + row.label(text=f"{relating_cost_item['quantity_value']}") + row = layout.row(align=True) + row.label(text=f"Quantity type:") + row.label(text=f"{relating_cost_item['quantity_type']}") + row = layout.row(align=True) + else: + row = layout.row(align=True) + row.label(text = f"No cost item related") + diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 39d3b5e3b5..e4b4444f58 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -518,6 +518,7 @@ class Qto: def add_product_base_qto(cls, product): pass def get_new_calculated_quantity(cls, qto_name, quantity_name, object): pass def get_new_guessed_quantity(cls, object, qto_name, quantity_name, ): pass + def get_related_cost_item_quantities(cls, product): pass @interface @@ -625,7 +626,7 @@ class Sequence: def get_recurrence_pattern_attributes(cls, recurrence_pattern): pass def get_recurrence_pattern_times(cls): pass def get_rel_sequence_attributes(cls): pass - + def get_selected_resource(cls): pass def get_start_date(cls): pass def get_task_attribute_value(cls, attribute_name): pass diff --git a/src/blenderbim/blenderbim/tool/qto.py b/src/blenderbim/blenderbim/tool/qto.py index 290354d5ae..2dbf11e285 100644 --- a/src/blenderbim/blenderbim/tool/qto.py +++ b/src/blenderbim/blenderbim/tool/qto.py @@ -127,3 +127,54 @@ class Qto(blenderbim.core.tool.Qto): ): continue return rel.RelatingPropertyDefinition + + @classmethod + def get_related_cost_item_quantities(cls, product): + """_summary_: Returns the related cost item and related quantities of the product + + :param ifc-instance product: ifc instance + :type product: ifcopenshell.entity_instance.entity_instance + + :return list of dictionaries in the form [ + { + "cost_item_id" : XX, + "cost_item_name" : XX, + "quantity_id" : XX, + "quantity_name" : XX, + "quantity_value" : XX, + "quantity_type" : XX + }] + :rtype list + + Example: + + .. code::Python + import blenderbim.tool as tool + + relating_cost_items = tool.Qto.relating_cost_items(my_beautiful_wall) + for relating_cost_item in relating_cost_items: + print(f"RELATING COST ITEM NAME: {relating_cost_item["cost_item_name"]}") + print(f"RELATING COST QUANTITY NAME: {relating_cost_item["quantity_name"]}") + ... + """ + quantities = cls.get_base_qto(product).Quantities + model = tool.Ifc.get() + cost_items = model.by_type("IfcCostItem") + result = [] + + for cost_item in cost_items: + cost_item_quantities = cost_item.CostQuantities if cost_item.CostQuantities is not None else [] + for cost_item_quantity in cost_item_quantities: + for quantity in quantities: + if quantity == cost_item_quantity: + result.append( + { + "cost_item_id" : cost_item.id(), + "cost_item_name" : cost_item.Name, + "quantity_id" : quantity.id(), + "quantity_name" : quantity.Name, + "quantity_value" : quantity[3], + "quantity_type" : quantity.is_a(), + } + ) + return result diff --git a/src/blenderbim/test/tool/test_qto.py b/src/blenderbim/test/tool/test_qto.py index 382c02a2c9..e5fe515d3e 100644 --- a/src/blenderbim/test/tool/test_qto.py +++ b/src/blenderbim/test/tool/test_qto.py @@ -142,3 +142,19 @@ class TestGetBaseQto(test.bim.bootstrap.NewFile): product = tool.Ifc.get_entity(wall_obj) assert not subject.get_base_qto(product) == True +class TestGetRelatedCostItemQuantities(test.bim.bootstrap.NewFile): + def test_run(self): + ifc = ifcopenshell.file() + tool.Ifc.set(ifc) + wall = ifc.createIfcWall() + product = tool.Ifc.get_entity(wall) + schedule = ifcopenshell.api.run("cost.add_cost_schedule", ifc) + item = ifcopenshell.api.run("cost.add_cost_item", ifc, cost_schedule=schedule) + ifcopenshell.api.run("cost.edit_cost_item", ifc, cost_item=item, attributes={"Name": "Foo"}) + qto = ifcopenshell.api.run("pset.add_qto", ifc, product=wall, name="Qto_WallBaseQuantities") + ifcopenshell.api.run("pset.edit_qto", ifc, qto=qto, properties={"NetVolume": 42.0}) + ifcopenshell.api.run("cost.assign_cost_item_quantity", ifc, cost_item=item, products=[wall], prop_name="NetVolume") + assert subject.get_related_cost_item_quantities(wall)[0]['cost_item_name'] == "Foo" + assert subject.get_related_cost_item_quantities(wall)[0]['quantity_name'] == "NetVolume" + assert subject.get_related_cost_item_quantities(wall)[0]['quantity_value'] == 42 + assert subject.get_related_cost_item_quantities(wall)[0]['quantity_type'] == "IfcQuantityVolume" From d911d8579dba9a5890a8d68a0b4a675c7e8d7ca5 Mon Sep 17 00:00:00 2001 From: Massimo Fabbro Date: Sun, 19 Mar 2023 17:06:00 +0100 Subject: [PATCH 07/12] Add qto data file --- .../blenderbim/bim/module/qto/data.py | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/blenderbim/blenderbim/bim/module/qto/data.py diff --git a/src/blenderbim/blenderbim/bim/module/qto/data.py b/src/blenderbim/blenderbim/bim/module/qto/data.py new file mode 100644 index 0000000000..7d5fcc6a66 --- /dev/null +++ b/src/blenderbim/blenderbim/bim/module/qto/data.py @@ -0,0 +1,75 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2021 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import bpy +import blenderbim.tool as tool + +def refresh(): + QtoData.is_loaded = False + +class QtoData: + data = {} + is_loaded = False + + @classmethod + def load(cls): + cls.data = { + "has_cost_item" : cls.has_cost_item(), + "relating_cost_items" : cls.relating_cost_items(), + } + + cls.is_loaded = True + + @classmethod + def has_cost_item(cls): + return False if not cls.relating_cost_items() else True + + @classmethod + def relating_cost_items(cls): + obj = bpy.context.active_object + if not obj: + return + element = tool.Ifc.get_entity(obj) + if not element: + return [] + + results = [] + relating_cost_items = tool.Qto.get_related_cost_item_quantities(element) + for relating_cost_item in relating_cost_items: + results.append( + { + 'cost_item_id' : relating_cost_item['cost_item_id'], + 'cost_item_name' : relating_cost_item['cost_item_name'], + 'quantity_id' : relating_cost_item['quantity_id'], + 'quantity_name' : relating_cost_item['quantity_name'], + 'quantity_value' : relating_cost_item['quantity_value'], + 'quantity_type' : relating_cost_item['quantity_type'], + } + ) + + return results + + + + + + + + + + From 33e6a0fdaef20e8ec56362192c32b2559c0f8fd5 Mon Sep 17 00:00:00 2001 From: Andres Date: Mon, 13 Mar 2023 01:54:31 +0100 Subject: [PATCH 08/12] Update logger to match Sverchok latest --- src/ifcsverchok/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ifcsverchok/__init__.py b/src/ifcsverchok/__init__.py index 2d0a4bd15c..26f26f036d 100644 --- a/src/ifcsverchok/__init__.py +++ b/src/ifcsverchok/__init__.py @@ -29,7 +29,8 @@ bl_info = { } import importlib -from sverchok.utils.logging import info, debug +import logging +logger = logging.getLogger('sverchok') from sverchok.ui.nodeview_space_menu import add_node_menu From d41a277b71da12cb4f72e857445e52a9dbcfa597 Mon Sep 17 00:00:00 2001 From: Andres Date: Mon, 13 Mar 2023 01:55:51 +0100 Subject: [PATCH 09/12] Fix runtime error when unregistering add-on --- src/ifcsverchok/__init__.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ifcsverchok/__init__.py b/src/ifcsverchok/__init__.py index 26f26f036d..48e34ba987 100644 --- a/src/ifcsverchok/__init__.py +++ b/src/ifcsverchok/__init__.py @@ -285,6 +285,12 @@ def register(): def unregister(): global imported_modules for module in reversed(imported_modules): - module.unregister() + try: + module.unregister() + except: + logger.error(f"Unable to unregister module: {module}") for cls in reversed(CLASSES): - bpy.utils.unregister_class(cls) + try: + bpy.utils.unregister_class(cls) + except: + logger.error(f"Unable to unregister class: {cls}") \ No newline at end of file From b20b99669d26f63e6b27a96a8e88c063a7b4d14b Mon Sep 17 00:00:00 2001 From: Andres Date: Mon, 13 Mar 2023 01:57:34 +0100 Subject: [PATCH 10/12] Chore: add newline at end of file --- src/ifcsverchok/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ifcsverchok/__init__.py b/src/ifcsverchok/__init__.py index 48e34ba987..e2346f23b6 100644 --- a/src/ifcsverchok/__init__.py +++ b/src/ifcsverchok/__init__.py @@ -293,4 +293,4 @@ def unregister(): try: bpy.utils.unregister_class(cls) except: - logger.error(f"Unable to unregister class: {cls}") \ No newline at end of file + logger.error(f"Unable to unregister class: {cls}") From cb0e8b6bf2a66cbccf36b887fe7252a452a16c8d Mon Sep 17 00:00:00 2001 From: Andres Date: Tue, 14 Mar 2023 01:54:25 +0100 Subject: [PATCH 11/12] Add own sublogger for IfcSverchok --- src/ifcsverchok/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ifcsverchok/__init__.py b/src/ifcsverchok/__init__.py index e2346f23b6..119235ffca 100644 --- a/src/ifcsverchok/__init__.py +++ b/src/ifcsverchok/__init__.py @@ -30,7 +30,7 @@ bl_info = { import importlib import logging -logger = logging.getLogger('sverchok') +logger = logging.getLogger('sverchok.ifc') from sverchok.ui.nodeview_space_menu import add_node_menu From d68356c3a77588829c8cabd234df196ebe81b2ac Mon Sep 17 00:00:00 2001 From: Andres Date: Thu, 16 Mar 2023 04:16:08 +0100 Subject: [PATCH 12/12] Rename class causing unregistering error --- src/ifcsverchok/__init__.py | 11 ++--------- src/ifcsverchok/nodes/ifc/api.py | 4 +++- src/ifcsverchok/nodes/ifc/api_WIP.py | 4 ++-- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/ifcsverchok/__init__.py b/src/ifcsverchok/__init__.py index 119235ffca..4936c7fb91 100644 --- a/src/ifcsverchok/__init__.py +++ b/src/ifcsverchok/__init__.py @@ -33,7 +33,6 @@ import logging logger = logging.getLogger('sverchok.ifc') from sverchok.ui.nodeview_space_menu import add_node_menu - def nodes_index(): return [ ( @@ -285,12 +284,6 @@ def register(): def unregister(): global imported_modules for module in reversed(imported_modules): - try: - module.unregister() - except: - logger.error(f"Unable to unregister module: {module}") + module.unregister() for cls in reversed(CLASSES): - try: - bpy.utils.unregister_class(cls) - except: - logger.error(f"Unable to unregister class: {cls}") + bpy.utils.unregister_class(cls) diff --git a/src/ifcsverchok/nodes/ifc/api.py b/src/ifcsverchok/nodes/ifc/api.py index 2c61a46c2e..cf9784c31b 100644 --- a/src/ifcsverchok/nodes/ifc/api.py +++ b/src/ifcsverchok/nodes/ifc/api.py @@ -23,6 +23,8 @@ import ifcsverchok.helper from bpy.props import StringProperty, EnumProperty from sverchok.node_tree import SverchCustomTreeNode from sverchok.data_structure import updateNode +import logging +logger = logging.getLogger('sverchok.ifc') def update_usecase(self, context): @@ -98,8 +100,8 @@ class SvIfcApi(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCor def register(): - bpy.utils.register_class(SvIfcTooltip) bpy.utils.register_class(SvIfcApi) + bpy.utils.register_class(SvIfcTooltip) def unregister(): diff --git a/src/ifcsverchok/nodes/ifc/api_WIP.py b/src/ifcsverchok/nodes/ifc/api_WIP.py index 3c4d7122af..a1f3d7f061 100644 --- a/src/ifcsverchok/nodes/ifc/api_WIP.py +++ b/src/ifcsverchok/nodes/ifc/api_WIP.py @@ -26,8 +26,8 @@ from sverchok.data_structure import updateNode import importlib -class SvIfcTooltip(bpy.types.Operator): - bl_idname = "node.sv_ifc_tooltip" +class SvIfcTooltipWIP(bpy.types.Operator): + bl_idname = "node.sv_ifc_tooltipWIP" bl_label = "IFC Info" tooltip: bpy.props.StringProperty()