mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 06:58:56 +00:00
Merge remote-tracking branch 'upstream/v0.7.0' into pset_custom_units_test
This commit is contained in:
@@ -133,9 +133,9 @@ mapper = {
|
|||||||
'NetWeight' : None,
|
'NetWeight' : None,
|
||||||
},
|
},
|
||||||
'Qto_CoveringBaseQuantities' : {
|
'Qto_CoveringBaseQuantities' : {
|
||||||
'Width' : "get_height",
|
'Width' : "get_covering_width",
|
||||||
'GrossArea' : "get_gross_footprint_area",
|
'GrossArea' : "get_covering_gross_area",
|
||||||
'NetArea' : "get_net_footprint_area",
|
'NetArea' : "get_covering_net_area",
|
||||||
},
|
},
|
||||||
'Qto_PipeSegmentBaseQuantities' : {
|
'Qto_PipeSegmentBaseQuantities' : {
|
||||||
'Length' : "get_length",
|
'Length' : "get_length",
|
||||||
|
|||||||
@@ -136,6 +136,48 @@ class QtoCalculator:
|
|||||||
OBB_gross_footprint_area = self.get_gross_footprint_area(OBB_obj)
|
OBB_gross_footprint_area = self.get_gross_footprint_area(OBB_obj)
|
||||||
return OBB_gross_footprint_area
|
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_side_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_side_area(obj)
|
||||||
|
elif get_parametric_axis == "AXIS3":
|
||||||
|
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_height(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):
|
def get_width(self, o):
|
||||||
"""_summary_: Returns the width of the object bounding box
|
"""_summary_: Returns the width of the object bounding box
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||||
|
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||||
|
#
|
||||||
|
# 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -16,10 +16,11 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
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_idname = "BIM_PT_qto_utilities"
|
||||||
bl_label = "Quantity Take-off"
|
bl_label = "Quantity Take-off"
|
||||||
bl_options = {"DEFAULT_CLOSED"}
|
bl_options = {"DEFAULT_CLOSED"}
|
||||||
@@ -28,6 +29,9 @@ class BIM_PT_qto_utilities(Panel):
|
|||||||
bl_category = "BlenderBIM"
|
bl_category = "BlenderBIM"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
|
if not QtoData.is_loaded:
|
||||||
|
QtoData.load()
|
||||||
|
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
props = context.scene.BIMQtoProperties
|
props = context.scene.BIMQtoProperties
|
||||||
|
|
||||||
@@ -51,9 +55,34 @@ class BIM_PT_qto_utilities(Panel):
|
|||||||
row.prop(props, "qto_name", text="")
|
row.prop(props, "qto_name", text="")
|
||||||
row.prop(props, "prop_name", text="")
|
row.prop(props, "prop_name", text="")
|
||||||
row.operator("bim.quantify_objects", icon="COPYDOWN", text="")
|
row.operator("bim.quantify_objects", icon="COPYDOWN", text="")
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.operator("bim.assign_objects_base_qto")
|
row.operator("bim.assign_objects_base_qto")
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.operator("bim.calculate_all_quantities", icon="MOD_EDGESPLIT")
|
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")
|
||||||
|
|
||||||
|
|||||||
@@ -518,6 +518,7 @@ class Qto:
|
|||||||
def add_product_base_qto(cls, product): pass
|
def add_product_base_qto(cls, product): pass
|
||||||
def get_new_calculated_quantity(cls, qto_name, quantity_name, object): 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_new_guessed_quantity(cls, object, qto_name, quantity_name, ): pass
|
||||||
|
def get_related_cost_item_quantities(cls, product): pass
|
||||||
|
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
@@ -625,7 +626,7 @@ class Sequence:
|
|||||||
def get_recurrence_pattern_attributes(cls, recurrence_pattern): pass
|
def get_recurrence_pattern_attributes(cls, recurrence_pattern): pass
|
||||||
def get_recurrence_pattern_times(cls): pass
|
def get_recurrence_pattern_times(cls): pass
|
||||||
def get_rel_sequence_attributes(cls): pass
|
def get_rel_sequence_attributes(cls): pass
|
||||||
|
|
||||||
def get_selected_resource(cls): pass
|
def get_selected_resource(cls): pass
|
||||||
def get_start_date(cls): pass
|
def get_start_date(cls): pass
|
||||||
def get_task_attribute_value(cls, attribute_name): pass
|
def get_task_attribute_value(cls, attribute_name): pass
|
||||||
|
|||||||
@@ -127,3 +127,54 @@ class Qto(blenderbim.core.tool.Qto):
|
|||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
return rel.RelatingPropertyDefinition
|
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
|
||||||
|
|||||||
@@ -142,3 +142,19 @@ class TestGetBaseQto(test.bim.bootstrap.NewFile):
|
|||||||
product = tool.Ifc.get_entity(wall_obj)
|
product = tool.Ifc.get_entity(wall_obj)
|
||||||
assert not subject.get_base_qto(product) == True
|
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"
|
||||||
|
|||||||
@@ -808,7 +808,7 @@ def copy(ifc_file, element):
|
|||||||
return new
|
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.
|
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
|
:param exclude_callback: A callback to determine whether or not to exclude
|
||||||
an entity or not. Returns True to exclude and False to exclude.
|
an entity or not. Returns True to exclude and False to exclude.
|
||||||
:type exclude_callback: function,optional
|
: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
|
:return: The newly copied element
|
||||||
:rtype: ifcopenshell.entity_instance.entity_instance
|
: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())
|
new = ifc_file.create_entity(element.is_a())
|
||||||
|
if element.id():
|
||||||
|
copied_entities[element.id()] = new
|
||||||
for i, attribute in enumerate(element):
|
for i, attribute in enumerate(element):
|
||||||
if attribute is None:
|
if attribute is None:
|
||||||
continue
|
continue
|
||||||
@@ -838,7 +850,7 @@ def copy_deep(ifc_file, element, exclude=None, exclude_callback=None):
|
|||||||
elif exclude_callback and exclude_callback(attribute):
|
elif exclude_callback and exclude_callback(attribute):
|
||||||
pass
|
pass
|
||||||
else:
|
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):
|
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]):
|
if exclude and any([attribute[0].is_a(e) for e in exclude]):
|
||||||
pass
|
pass
|
||||||
@@ -847,7 +859,13 @@ def copy_deep(ifc_file, element, exclude=None, exclude_callback=None):
|
|||||||
else:
|
else:
|
||||||
attribute = list(attribute)
|
attribute = list(attribute)
|
||||||
for j, item in enumerate(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":
|
if new.attribute_name(i) == "GlobalId":
|
||||||
new[i] = ifcopenshell.guid.new()
|
new[i] = ifcopenshell.guid.new()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ def assert_valid_inverse(attr, val, schema):
|
|||||||
aggr = attr.type_of_aggregation_string().upper()
|
aggr = attr.type_of_aggregation_string().upper()
|
||||||
|
|
||||||
if aggr:
|
if aggr:
|
||||||
aggr_str = f'{aggr} [{b1}:{b2}] OF '
|
aggr_str = f'{aggr} [{b1}:{"?" if b2 == -1 else b2}] OF '
|
||||||
else:
|
else:
|
||||||
aggr_str = ''
|
aggr_str = ''
|
||||||
|
|
||||||
|
|||||||
@@ -707,3 +707,19 @@ class TestCopyDeepIFC4(test.bootstrap.IFC4):
|
|||||||
rel.RelatedObjects = [element]
|
rel.RelatedObjects = [element]
|
||||||
rel2 = subject.copy_deep(self.file, rel, exclude_callback=lambda x: x.is_a("IfcWall"))
|
rel2 = subject.copy_deep(self.file, rel, exclude_callback=lambda x: x.is_a("IfcWall"))
|
||||||
assert rel.RelatedObjects == rel2.RelatedObjects
|
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)
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ bl_info = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
from sverchok.utils.logging import info, debug
|
import logging
|
||||||
|
logger = logging.getLogger('sverchok.ifc')
|
||||||
from sverchok.ui.nodeview_space_menu import add_node_menu
|
from sverchok.ui.nodeview_space_menu import add_node_menu
|
||||||
|
|
||||||
|
|
||||||
def nodes_index():
|
def nodes_index():
|
||||||
return [
|
return [
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import ifcsverchok.helper
|
|||||||
from bpy.props import StringProperty, EnumProperty
|
from bpy.props import StringProperty, EnumProperty
|
||||||
from sverchok.node_tree import SverchCustomTreeNode
|
from sverchok.node_tree import SverchCustomTreeNode
|
||||||
from sverchok.data_structure import updateNode
|
from sverchok.data_structure import updateNode
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger('sverchok.ifc')
|
||||||
|
|
||||||
|
|
||||||
def update_usecase(self, context):
|
def update_usecase(self, context):
|
||||||
@@ -98,8 +100,8 @@ class SvIfcApi(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCor
|
|||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
bpy.utils.register_class(SvIfcTooltip)
|
|
||||||
bpy.utils.register_class(SvIfcApi)
|
bpy.utils.register_class(SvIfcApi)
|
||||||
|
bpy.utils.register_class(SvIfcTooltip)
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ from sverchok.data_structure import updateNode
|
|||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
|
|
||||||
class SvIfcTooltip(bpy.types.Operator):
|
class SvIfcTooltipWIP(bpy.types.Operator):
|
||||||
bl_idname = "node.sv_ifc_tooltip"
|
bl_idname = "node.sv_ifc_tooltipWIP"
|
||||||
bl_label = "IFC Info"
|
bl_label = "IFC Info"
|
||||||
tooltip: bpy.props.StringProperty()
|
tooltip: bpy.props.StringProperty()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user