Minor fix.

This commit is contained in:
Dion Moult
2021-11-16 17:52:08 +11:00
parent 43869c33f6
commit 2120653104
5 changed files with 68 additions and 30 deletions
@@ -17,6 +17,8 @@
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import bpy
import ifcopenshell.util.type
import ifcopenshell.util.element
import blenderbim.tool as tool
@@ -30,24 +32,55 @@ class TypeData:
@classmethod
def load(cls):
cls.is_loaded = True
cls.data = {
"relating_type_classes": cls.relating_type_classes(),
"relating_types": cls.relating_types(),
"is_product": cls.is_product(),
"total_instances": cls.total_instances(),
"type_name": cls.type_name(),
}
cls.is_loaded = True
@classmethod
def relating_type_classes(cls):
results = []
element = tool.Ifc.get_entity(bpy.context.active_object)
obj = bpy.context.active_object
if not obj:
return
element = tool.Ifc.get_entity(obj)
if not element:
return []
types = ifcopenshell.util.type.get_applicable_types(element.is_a(), schema=tool.Ifc.get_schema())
applicable_types_enum.extend((t, t, "") for t in types)
results.extend((t, t, "") for t in types)
return results
@classmethod
def relating_types(cls):
relating_type_classes = cls.relating_type_classes()
if not relating_type_classes:
return []
results = []
elements = tool.Ifc.get().by_type(bpy.context.active_object.BIMTypeProperties.relating_type_class)
relating_type_class = bpy.context.active_object.BIMTypeProperties.relating_type_class
if not relating_type_class and relating_type_classes:
relating_type_class = relating_type_classes[0][0]
elements = tool.Ifc.get().by_type(relating_type_class)
elements = [(str(e.id()), e.Name, "") for e in elements]
relating_types_enum.extend(sorted(elements, key=lambda s: s[1]))
results.extend(sorted(elements, key=lambda s: s[1]))
return results
@classmethod
def is_product(cls):
element = tool.Ifc.get_entity(bpy.context.active_object)
return element.is_a("IfcProduct")
@classmethod
def total_instances(cls):
element = tool.Ifc.get_entity(bpy.context.active_object)
return str(len(ifcopenshell.util.element.get_types(element)))
@classmethod
def type_name(cls):
element = tool.Ifc.get_entity(bpy.context.active_object)
type = ifcopenshell.util.element.get_type(element)
if type:
return f"{type.is_a()}/{type.Name or 'Unnamed'}"
@@ -46,11 +46,11 @@ def get_relating_type(self, context):
return TypeData.data["relating_types"]
def update_is_editing_type(self, context):
def update_relating_type_class(self, context):
TypeData.is_loaded = False
class BIMTypeProperties(PropertyGroup):
is_editing_type: BoolProperty(name="Is Editing Type", update=update_is_editing_type)
relating_type_class: EnumProperty(items=get_relating_type_class, name="Relating Type Class")
is_editing_type: BoolProperty(name="Is Editing Type")
relating_type_class: EnumProperty(items=get_relating_type_class, name="Relating Type Class", update=update_relating_type_class)
relating_type: EnumProperty(items=get_relating_type, name="Relating Type")
+17 -22
View File
@@ -16,10 +16,11 @@
# 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 blenderbim.tool as tool
import blenderbim.bim.module.type.prop as type_prop
from bpy.types import Panel
from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.type.data import Data
from blenderbim.bim.module.type.data import TypeData
class BIM_PT_type(Panel):
@@ -33,23 +34,20 @@ class BIM_PT_type(Panel):
def poll(cls, context):
if not context.active_object:
return False
props = context.active_object.BIMObjectProperties
if not props.ifc_definition_id:
return False
if not IfcStore.get_element(props.ifc_definition_id):
return False
if props.ifc_definition_id not in Data.products and props.ifc_definition_id not in Data.types:
Data.load(IfcStore.get_file(), props.ifc_definition_id)
if props.ifc_definition_id not in Data.products and props.ifc_definition_id not in Data.types:
return False
if not Data.products.get(props.ifc_definition_id, None) and not Data.types.get(props.ifc_definition_id, None):
element = tool.Ifc.get_entity(context.active_object)
if not element:
return False
if not element.is_a("IfcProduct") and not element.is_a("IfcTypeProduct"):
return True
return True
def draw(self, context):
if not TypeData.is_loaded:
TypeData.load()
oprops = context.active_object.BIMObjectProperties
if oprops.ifc_definition_id in Data.products:
if TypeData.data["is_product"]:
self.draw_product_ui(context)
else:
self.draw_type_ui(context)
@@ -58,7 +56,7 @@ class BIM_PT_type(Panel):
props = context.active_object.BIMTypeProperties
oprops = context.active_object.BIMObjectProperties
row = self.layout.row(align=True)
row.label(text=f"{len(Data.types[oprops.ifc_definition_id])} Typed Objects")
row.label(text=f"{TypeData.data['total_instances']} Typed Objects")
row.operator("bim.select_type_objects", icon="RESTRICT_SELECT_OFF", text="")
def draw_product_ui(self, context):
@@ -69,7 +67,7 @@ class BIM_PT_type(Panel):
row = self.layout.row(align=True)
row.prop(props, "relating_type_class", text="")
if type_prop.get_object_relating_type(None, context):
if type_prop.get_relating_type(None, context):
row.prop(props, "relating_type", text="")
row.operator("bim.assign_type", icon="CHECKMARK", text="")
else:
@@ -77,18 +75,15 @@ class BIM_PT_type(Panel):
row.operator("bim.disable_editing_type", icon="CANCEL", text="")
else:
row = self.layout.row(align=True)
name = "{}/{}".format(
Data.products[oprops.ifc_definition_id]["type"], Data.products[oprops.ifc_definition_id]["Name"]
)
if name == "None/None":
row.label(text="This object has no type")
row.operator("bim.enable_editing_type", icon="GREASEPENCIL", text="")
else:
row.label(text=name)
if TypeData.data["type_name"]:
row.label(text=TypeData.data["type_name"])
row.operator("bim.select_type", icon="TRACKER", text="")
row.operator("bim.select_similar_type", icon="RESTRICT_SELECT_OFF", text="")
row.operator("bim.enable_editing_type", icon="GREASEPENCIL", text="")
row.operator("bim.unassign_type", icon="X", text="")
else:
row.label(text="This object has no type")
row.operator("bim.enable_editing_type", icon="GREASEPENCIL", text="")
def add_object_button(self, context):
@@ -81,6 +81,8 @@ def get_type(element):
def get_types(type):
for rel in getattr(type, "Types", []):
return rel.RelatedObjects
for rel in getattr(type, "ObjectTypeOf", []):
return rel.RelatedObjects
return []
@@ -144,6 +144,14 @@ class TestGetTypes(test.bootstrap.IFC4):
assert subject.get_types(element_type) == (element,)
class TestGetTypesIFC2X3(test.bootstrap.IFC2X3):
def test_getting_the_type_of_a_product(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
ifcopenshell.api.run("type.assign_type", self.file, related_object=element, relating_type=element_type)
assert subject.get_types(element_type) == (element,)
class TestGetMaterial(test.bootstrap.IFC4):
def test_getting_the_material_of_a_product(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")