mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 08:45:22 +00:00
Ifc class suggestion (#2290)
* You can now use suggestions in ifc class enum search popup * Move data to data submodule * Fix error when suggestion mapping contains only one value * Add predefined types to the search popup * Use defaultdict to be able to add suggestions later * Support predefined types and format name to display the ifc class and fix bug where the prop is not defined in the suggestion dictionary * Move data retrieval to data module * Simplify prop search items retrieval * Support prop search for more enums
This commit is contained in:
@@ -69,9 +69,3 @@ class BIMBrickProperties(PropertyGroup):
|
|||||||
libraries: EnumProperty(name="Libraries", items=get_libraries)
|
libraries: EnumProperty(name="Libraries", items=get_libraries)
|
||||||
namespace: EnumProperty(name="Namespace", items=get_namespaces)
|
namespace: EnumProperty(name="Namespace", items=get_namespaces)
|
||||||
brick_equipment_class: EnumProperty(name="Brick Equipment Class", items=get_brick_equipment_classes)
|
brick_equipment_class: EnumProperty(name="Brick Equipment Class", items=get_brick_equipment_classes)
|
||||||
|
|
||||||
getter_enum = {
|
|
||||||
"libraries": get_libraries,
|
|
||||||
"namespace": get_namespaces,
|
|
||||||
"brick_equipment_class": get_brick_equipment_classes,
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ class BIM_PT_context(bpy.types.Panel):
|
|||||||
row.operator("bim.remove_context", icon="X", text="").context = ifc_context["id"]
|
row.operator("bim.remove_context", icon="X", text="").context = ifc_context["id"]
|
||||||
|
|
||||||
row = box.row(align=True)
|
row = box.row(align=True)
|
||||||
row.prop(props, "subcontexts", text="")
|
blenderbim.bim.helper.prop_with_search(row, props, "subcontexts", text="")
|
||||||
row.prop(props, "target_views", text="")
|
blenderbim.bim.helper.prop_with_search(row, props, "target_views", text="")
|
||||||
op = row.operator("bim.add_context", icon="ADD", text="")
|
op = row.operator("bim.add_context", icon="ADD", text="")
|
||||||
op.context_type = ifc_context["context_type"]
|
op.context_type = ifc_context["context_type"]
|
||||||
op.context_identifier = props.subcontexts
|
op.context_identifier = props.subcontexts
|
||||||
|
|||||||
@@ -137,5 +137,3 @@ class BIMObjectMaterialProperties(PropertyGroup):
|
|||||||
parameterized_profile_classes: EnumProperty(
|
parameterized_profile_classes: EnumProperty(
|
||||||
items=getParameterizedProfileClasses, name="Parameterized Profile Classes"
|
items=getParameterizedProfileClasses, name="Parameterized Profile Classes"
|
||||||
)
|
)
|
||||||
|
|
||||||
getter_enum = {"material": get_materials}
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class BIM_PT_materials(Panel):
|
|||||||
row.operator("bim.disable_editing_materials", text="", icon="CANCEL")
|
row.operator("bim.disable_editing_materials", text="", icon="CANCEL")
|
||||||
else:
|
else:
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(self.props, "material_type", text="")
|
prop_with_search(row, self.props, "material_type", text="")
|
||||||
row.operator("bim.load_materials", text="", icon="IMPORT")
|
row.operator("bim.load_materials", text="", icon="IMPORT")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ class BIM_PT_object_material(Panel):
|
|||||||
return self.draw_material_ui()
|
return self.draw_material_ui()
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(self.props, "material_type", text="")
|
prop_with_search(row, self.props, "material_type", text="")
|
||||||
if self.props.material_type == "IfcMaterial" or self.props.material_type == "IfcMaterialList":
|
if self.props.material_type == "IfcMaterial" or self.props.material_type == "IfcMaterialList":
|
||||||
prop_with_search(row, self.props, "material", text="")
|
prop_with_search(row, self.props, "material", text="")
|
||||||
row.operator("bim.assign_material", icon="ADD", text="")
|
row.operator("bim.assign_material", icon="ADD", text="")
|
||||||
|
|||||||
@@ -66,7 +66,3 @@ class BIMPatchProperties(PropertyGroup):
|
|||||||
ifc_patch_output: StringProperty(default="", name="IFC Patch Output IFC")
|
ifc_patch_output: StringProperty(default="", name="IFC Patch Output IFC")
|
||||||
ifc_patch_args: StringProperty(default="", name="Arguments")
|
ifc_patch_args: StringProperty(default="", name="Arguments")
|
||||||
ifc_patch_args_attr: CollectionProperty(type=Attribute, name="Arguments")
|
ifc_patch_args_attr: CollectionProperty(type=Attribute, name="Arguments")
|
||||||
|
|
||||||
getter_enum = {
|
|
||||||
"ifc_patch_recipes": get_ifcpatch_recipes,
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -167,28 +167,3 @@ class BIMProjectProperties(PropertyGroup):
|
|||||||
|
|
||||||
def get_library_element_index(self, lib_element):
|
def get_library_element_index(self, lib_element):
|
||||||
return next((i for i in range(len(self.library_elements)) if self.library_elements[i] == lib_element))
|
return next((i for i in range(len(self.library_elements)) if self.library_elements[i] == lib_element))
|
||||||
|
|
||||||
getter_enum = {
|
|
||||||
"collection_mode": lambda self, context: [
|
|
||||||
("DECOMPOSITION", "Decomposition", "Collections represent aggregates and spatial containers"),
|
|
||||||
("SPATIAL_DECOMPOSITION", "Spatial Decomposition", "Collections represent spatial containers"),
|
|
||||||
("IFC_CLASS", "IFC Class", "Collections represent IFC class"),
|
|
||||||
("NONE", "None", "No collections are created"),
|
|
||||||
],
|
|
||||||
"filter_mode": lambda self, context: [
|
|
||||||
("NONE", "None", "No filtering is performed"),
|
|
||||||
("DECOMPOSITION", "Decomposition", "Filter objects by decomposition"),
|
|
||||||
("IFC_CLASS", "IFC Class", "Filter objects by class"),
|
|
||||||
("IFC_TYPE", "IFC Type", "Filter objects by type"),
|
|
||||||
("WHITELIST", "Whitelist", "Filter objects using a custom whitelist query"),
|
|
||||||
("BLACKLIST", "Blacklist", "Filter objects using a custom blacklist query"),
|
|
||||||
],
|
|
||||||
"merge_mode": lambda self, context: [
|
|
||||||
("NONE", "None", "No objects are merged"),
|
|
||||||
("IFC_CLASS", "IFC Class", "One object per IFC class"),
|
|
||||||
("IFC_TYPE", "IFC Type", "One object per IFC construction type"),
|
|
||||||
("MATERIAL", "Material", "One object per material"),
|
|
||||||
],
|
|
||||||
"export_schema": get_export_schema,
|
|
||||||
"template_file": get_template_file,
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -158,11 +158,6 @@ class PsetProperties(PropertyGroup):
|
|||||||
pset_name: EnumProperty(items=get_pset_names, name="Pset Name")
|
pset_name: EnumProperty(items=get_pset_names, name="Pset Name")
|
||||||
qto_name: EnumProperty(items=get_qto_names, name="Qto Name")
|
qto_name: EnumProperty(items=get_qto_names, name="Qto Name")
|
||||||
|
|
||||||
getter_enum = {
|
|
||||||
"qto_name": get_qto_names,
|
|
||||||
"pset_name": get_pset_names,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class MaterialPsetProperties(PropertyGroup):
|
class MaterialPsetProperties(PropertyGroup):
|
||||||
active_pset_id: IntProperty(name="Active Pset ID")
|
active_pset_id: IntProperty(name="Active Pset ID")
|
||||||
@@ -223,14 +218,6 @@ class AddEditProperties(PropertyGroup):
|
|||||||
)
|
)
|
||||||
enum_values: CollectionProperty(name="Enum Values", type=Attribute)
|
enum_values: CollectionProperty(name="Enum Values", type=Attribute)
|
||||||
|
|
||||||
getter_enum = {
|
|
||||||
"primary_measure_type": get_primary_measure_type,
|
|
||||||
"template_type": lambda self, context: [
|
|
||||||
("IfcPropertySingleValue", "IfcPropertySingleValue", "IfcPropertySingleValue"),
|
|
||||||
("IfcPropertyEnumeratedValue", "IfcPropertyEnumeratedValue", "IfcPropertyEnumeratedValue"),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_value_name(self):
|
def get_value_name(self):
|
||||||
ifc_data_type = IfcStore.get_schema().declaration_by_name(self.primary_measure_type)
|
ifc_data_type = IfcStore.get_schema().declaration_by_name(self.primary_measure_type)
|
||||||
data_type = ifcopenshell.util.attribute.get_primitive_type(ifc_data_type)
|
data_type = ifcopenshell.util.attribute.get_primitive_type(ifc_data_type)
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ class BIM_PT_material_psets(Panel):
|
|||||||
|
|
||||||
props = context.active_object.active_material.PsetProperties
|
props = context.active_object.active_material.PsetProperties
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(props, "pset_name", text="")
|
prop_with_search(row, props, "pset_name", text="")
|
||||||
op = row.operator("bim.add_pset", icon="ADD", text="")
|
op = row.operator("bim.add_pset", icon="ADD", text="")
|
||||||
op.obj = context.active_object.active_material.name
|
op.obj = context.active_object.active_material.name
|
||||||
op.obj_type = "Material"
|
op.obj_type = "Material"
|
||||||
@@ -348,7 +348,7 @@ class BIM_PT_resource_psets(Panel):
|
|||||||
|
|
||||||
props = context.scene.ResourcePsetProperties
|
props = context.scene.ResourcePsetProperties
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(props, "pset_name", text="")
|
prop_with_search(row, props, "pset_name", text="")
|
||||||
op = row.operator("bim.add_pset", icon="ADD", text="")
|
op = row.operator("bim.add_pset", icon="ADD", text="")
|
||||||
op.obj_type = "Resource"
|
op.obj_type = "Resource"
|
||||||
|
|
||||||
@@ -381,7 +381,7 @@ class BIM_PT_profile_psets(Panel):
|
|||||||
|
|
||||||
props = context.scene.ProfilePsetProperties
|
props = context.scene.ProfilePsetProperties
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(props, "pset_name", text="")
|
prop_with_search(row, props, "pset_name", text="")
|
||||||
op = row.operator("bim.add_pset", icon="ADD", text="")
|
op = row.operator("bim.add_pset", icon="ADD", text="")
|
||||||
op.obj_type = "Profile"
|
op.obj_type = "Profile"
|
||||||
|
|
||||||
@@ -410,7 +410,7 @@ class BIM_PT_work_schedule_psets(Panel):
|
|||||||
|
|
||||||
props = context.scene.WorkSchedulePsetProperties
|
props = context.scene.WorkSchedulePsetProperties
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(props, "pset_name", text="")
|
prop_with_search(row, props, "pset_name", text="")
|
||||||
op = row.operator("bim.add_pset", icon="ADD", text="")
|
op = row.operator("bim.add_pset", icon="ADD", text="")
|
||||||
op.obj_type = "WorkSchedule"
|
op.obj_type = "WorkSchedule"
|
||||||
|
|
||||||
@@ -450,7 +450,7 @@ class BIM_PT_rename_parameters(Panel):
|
|||||||
if props:
|
if props:
|
||||||
for index, prop in enumerate(props):
|
for index, prop in enumerate(props):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(prop, "pset_name", text="")
|
prop_with_search(row, prop, "pset_name", text="")
|
||||||
row.prop(prop, "existing_property_name", text="")
|
row.prop(prop, "existing_property_name", text="")
|
||||||
row.prop(prop, "new_property_name", text="")
|
row.prop(prop, "new_property_name", text="")
|
||||||
op = row.operator("bim.remove_property_to_edit", icon="X", text="")
|
op = row.operator("bim.remove_property_to_edit", icon="X", text="")
|
||||||
@@ -485,7 +485,7 @@ class BIM_PT_add_edit_custom_properties(Panel):
|
|||||||
if props:
|
if props:
|
||||||
for index, prop in enumerate(props):
|
for index, prop in enumerate(props):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(prop, "pset_name", text="")
|
prop_with_search(row, prop, "pset_name", text="")
|
||||||
row.prop(prop, "property_name", text="")
|
row.prop(prop, "property_name", text="")
|
||||||
if prop.template_type == "IfcPropertySingleValue":
|
if prop.template_type == "IfcPropertySingleValue":
|
||||||
row.prop(prop, prop.get_value_name(), text="")
|
row.prop(prop, prop.get_value_name(), text="")
|
||||||
@@ -537,7 +537,7 @@ class BIM_PT_delete_psets(Panel):
|
|||||||
if props:
|
if props:
|
||||||
for index, prop in enumerate(props):
|
for index, prop in enumerate(props):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(prop, "pset_name", text="")
|
prop_with_search(row, prop, "pset_name", text="")
|
||||||
op = row.operator("bim.remove_property_to_edit", icon="X", text="")
|
op = row.operator("bim.remove_property_to_edit", icon="X", text="")
|
||||||
op.index = index
|
op.index = index
|
||||||
op.option = "DeletePsets"
|
op.option = "DeletePsets"
|
||||||
|
|||||||
@@ -146,10 +146,6 @@ class PsetTemplate(PropertyGroup):
|
|||||||
template_type: EnumProperty(items=get_template_type, name="Template Type")
|
template_type: EnumProperty(items=get_template_type, name="Template Type")
|
||||||
applicable_entity: StringProperty(name="Applicable Entity")
|
applicable_entity: StringProperty(name="Applicable Entity")
|
||||||
|
|
||||||
getter_enum = {
|
|
||||||
"template_type": get_template_type,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class EnumerationValues(PropertyGroup):
|
class EnumerationValues(PropertyGroup):
|
||||||
string_value: StringProperty(name="Value")
|
string_value: StringProperty(name="Value")
|
||||||
@@ -168,9 +164,6 @@ class PropTemplate(PropertyGroup):
|
|||||||
name="Template Type",
|
name="Template Type",
|
||||||
)
|
)
|
||||||
enum_values: CollectionProperty(type=EnumerationValues)
|
enum_values: CollectionProperty(type=EnumerationValues)
|
||||||
getter_enum = {
|
|
||||||
"primary_measure_type": get_primary_measure_type,
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_value_name(self):
|
def get_value_name(self):
|
||||||
ifc_data_type = IfcStore.get_schema().declaration_by_name(self.primary_measure_type)
|
ifc_data_type = IfcStore.get_schema().declaration_by_name(self.primary_measure_type)
|
||||||
@@ -195,8 +188,3 @@ class BIMPsetTemplateProperties(PropertyGroup):
|
|||||||
active_pset_template: PointerProperty(type=PsetTemplate)
|
active_pset_template: PointerProperty(type=PsetTemplate)
|
||||||
active_prop_template: PointerProperty(type=PropTemplate)
|
active_prop_template: PointerProperty(type=PropTemplate)
|
||||||
new_template_filename: StringProperty("New TemplateFileName")
|
new_template_filename: StringProperty("New TemplateFileName")
|
||||||
|
|
||||||
getter_enum = {
|
|
||||||
"pset_template_files": getPsetTemplateFiles,
|
|
||||||
"pset_templates": getPsetTemplates,
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,9 +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 collections import defaultdict
|
||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
|
||||||
|
|
||||||
def refresh():
|
def refresh():
|
||||||
@@ -35,6 +37,7 @@ class IfcClassData:
|
|||||||
cls.data = {}
|
cls.data = {}
|
||||||
cls.data["ifc_products"] = cls.ifc_products()
|
cls.data["ifc_products"] = cls.ifc_products()
|
||||||
cls.data["ifc_classes"] = cls.ifc_classes()
|
cls.data["ifc_classes"] = cls.ifc_classes()
|
||||||
|
cls.data["ifc_classes_suggestions"] = cls.ifc_classes_suggestions()
|
||||||
cls.data["contexts"] = cls.contexts()
|
cls.data["contexts"] = cls.contexts()
|
||||||
cls.data["has_entity"] = cls.has_entity()
|
cls.data["has_entity"] = cls.has_entity()
|
||||||
cls.data["name"] = cls.name()
|
cls.data["name"] = cls.name()
|
||||||
@@ -74,6 +77,41 @@ class IfcClassData:
|
|||||||
names.extend(("IfcDoorStyle", "IfcWindowStyle"))
|
names.extend(("IfcDoorStyle", "IfcWindowStyle"))
|
||||||
return [(c, c, "") for c in sorted(names)]
|
return [(c, c, "") for c in sorted(names)]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def ifc_classes_suggestions(cls):
|
||||||
|
suggestions = defaultdict(list)
|
||||||
|
suggestions.update(
|
||||||
|
{
|
||||||
|
"IfcWall": ["Glazing", "Glass", "Pane"],
|
||||||
|
"IfcWindow": ["Glazing", "Glass", "Pane"],
|
||||||
|
"IfcPlate": ["Glazing", "Glass", "Pane"],
|
||||||
|
"IfcFurniture": ["Signage"],
|
||||||
|
"IfcSlab": ["Hob"],
|
||||||
|
"IfcCovering": ["Flashing", "Capping"],
|
||||||
|
"IfcCableSegment": ["Lighting Rod"],
|
||||||
|
"IfcSensor": ["Card Reader", "Fob Reader"],
|
||||||
|
"IfcSwitchingDevice": ["Reed Switch", "Electric Isolating Switch"],
|
||||||
|
"IfcActuator": ["Electric Strike"],
|
||||||
|
"IfcAirTerminalBox": ["VAV Box"],
|
||||||
|
"IfcUnitaryEquipment": ["Fan Coil Unit"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
file = IfcStore.get_file()
|
||||||
|
if file:
|
||||||
|
for ifc_class in cls.ifc_classes():
|
||||||
|
ifc_class = ifc_class[0]
|
||||||
|
declaration = IfcStore.get_schema().declaration_by_name(ifc_class)
|
||||||
|
for attribute in declaration.attributes():
|
||||||
|
if attribute.name() == "PredefinedType":
|
||||||
|
for e in attribute.type_of_attribute().declared_type().enumeration_items():
|
||||||
|
if e in (
|
||||||
|
"NOTDEFINED",
|
||||||
|
"USERDEFINED",
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
suggestions[ifc_class].append(e.title())
|
||||||
|
return suggestions
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def contexts(cls):
|
def contexts(cls):
|
||||||
results = []
|
results = []
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ class AssignClass(bpy.types.Operator, Operator):
|
|||||||
ifc_class = self.ifc_class or props.ifc_class
|
ifc_class = self.ifc_class or props.ifc_class
|
||||||
predefined_type = self.userdefined_type if self.predefined_type == "USERDEFINED" else self.predefined_type
|
predefined_type = self.userdefined_type if self.predefined_type == "USERDEFINED" else self.predefined_type
|
||||||
ifc_context = self.context_id
|
ifc_context = self.context_id
|
||||||
if not ifc_context and props.getter_enum["contexts"](props, context):
|
if not ifc_context and props._annotations__["contexts"].keywords.get("items")(props, context):
|
||||||
ifc_context = int(props.contexts or "0") or None
|
ifc_context = int(props.contexts or "0") or None
|
||||||
if ifc_context:
|
if ifc_context:
|
||||||
ifc_context = tool.Ifc.get().by_id(ifc_context)
|
ifc_context = tool.Ifc.get().by_id(ifc_context)
|
||||||
|
|||||||
@@ -88,6 +88,11 @@ def get_ifc_classes(self, context):
|
|||||||
return IfcClassData.data["ifc_classes"]
|
return IfcClassData.data["ifc_classes"]
|
||||||
|
|
||||||
|
|
||||||
|
def get_ifc_classes_suggestions():
|
||||||
|
if not IfcClassData.is_loaded:
|
||||||
|
IfcClassData.load()
|
||||||
|
return IfcClassData.data["ifc_classes_suggestions"]
|
||||||
|
|
||||||
def get_contexts(self, context):
|
def get_contexts(self, context):
|
||||||
if not IfcClassData.is_loaded:
|
if not IfcClassData.is_loaded:
|
||||||
IfcClassData.load()
|
IfcClassData.load()
|
||||||
@@ -101,9 +106,6 @@ class BIMRootProperties(PropertyGroup):
|
|||||||
ifc_predefined_type: EnumProperty(items=getIfcPredefinedTypes, name="Predefined Type", default=None)
|
ifc_predefined_type: EnumProperty(items=getIfcPredefinedTypes, name="Predefined Type", default=None)
|
||||||
ifc_userdefined_type: StringProperty(name="Userdefined Type")
|
ifc_userdefined_type: StringProperty(name="Userdefined Type")
|
||||||
|
|
||||||
getter_enum = {
|
getter_enum_suggestions = {
|
||||||
"contexts": get_contexts,
|
"ifc_class": get_ifc_classes_suggestions,
|
||||||
"ifc_product": get_ifc_products,
|
|
||||||
"ifc_class": get_ifc_classes,
|
|
||||||
"ifc_predefined_type": getIfcPredefinedTypes,
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import bpy
|
|||||||
import blenderbim.bim.helper
|
import blenderbim.bim.helper
|
||||||
from bpy.types import Panel, UIList
|
from bpy.types import Panel, UIList
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from blenderbim.bim.helper import draw_attributes
|
from blenderbim.bim.helper import draw_attributes, prop_with_search
|
||||||
from ifcopenshell.api.structural.data import Data
|
from ifcopenshell.api.structural.data import Data
|
||||||
from blenderbim.bim.module.structural.data import StructuralData
|
from blenderbim.bim.module.structural.data import StructuralData
|
||||||
|
|
||||||
@@ -482,7 +482,7 @@ class BIM_PT_structural_loads(Panel):
|
|||||||
row.operator("bim.disable_structural_load_editing_ui", text="", icon="SCREEN_BACK")
|
row.operator("bim.disable_structural_load_editing_ui", text="", icon="SCREEN_BACK")
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(self.props, "structural_load_types", text="")
|
prop_with_search(row, self.props, "structural_load_types", text="")
|
||||||
row.operator("bim.add_structural_load", text="", icon="ADD").ifc_class = self.props.structural_load_types
|
row.operator("bim.add_structural_load", text="", icon="ADD").ifc_class = self.props.structural_load_types
|
||||||
else:
|
else:
|
||||||
row.operator("bim.load_structural_loads", text="", icon="GREASEPENCIL")
|
row.operator("bim.load_structural_loads", text="", icon="GREASEPENCIL")
|
||||||
@@ -551,7 +551,7 @@ class BIM_PT_boundary_conditions(Panel):
|
|||||||
row.operator("bim.disable_boundary_condition_editing_ui", text="", icon="SCREEN_BACK")
|
row.operator("bim.disable_boundary_condition_editing_ui", text="", icon="SCREEN_BACK")
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(self.props, "boundary_condition_types", text="")
|
prop_with_search(row, self.props, "boundary_condition_types", text="")
|
||||||
row.operator(
|
row.operator(
|
||||||
"bim.add_boundary_condition", text="", icon="ADD"
|
"bim.add_boundary_condition", text="", icon="ADD"
|
||||||
).ifc_class = self.props.boundary_condition_types
|
).ifc_class = self.props.boundary_condition_types
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class BIM_PT_styles(Panel):
|
|||||||
if self.props.is_editing:
|
if self.props.is_editing:
|
||||||
row.operator("bim.disable_editing_styles", text="", icon="CANCEL")
|
row.operator("bim.disable_editing_styles", text="", icon="CANCEL")
|
||||||
else:
|
else:
|
||||||
row.prop(self.props, "style_type", text="")
|
blenderbim.bim.helper.prop_with_search(row, self.props, "style_type", text="")
|
||||||
row.operator("bim.load_styles", text="", icon="IMPORT").style_type = self.props.style_type
|
row.operator("bim.load_styles", text="", icon="IMPORT").style_type = self.props.style_type
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
# 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 blenderbim.bim.helper import prop_with_search
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
from bpy.types import Panel, UIList
|
from bpy.types import Panel, UIList
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
@@ -46,7 +47,7 @@ class BIM_PT_systems(Panel):
|
|||||||
row.operator("bim.disable_system_editing_ui", text="", icon="CANCEL")
|
row.operator("bim.disable_system_editing_ui", text="", icon="CANCEL")
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.prop(self.props, "system_class", text="")
|
prop_with_search(row, self.props, "system_class", text="")
|
||||||
row.operator("bim.add_system", text="", icon="ADD")
|
row.operator("bim.add_system", text="", icon="ADD")
|
||||||
else:
|
else:
|
||||||
row.operator("bim.load_systems", text="", icon="GREASEPENCIL")
|
row.operator("bim.load_systems", text="", icon="GREASEPENCIL")
|
||||||
|
|||||||
@@ -68,9 +68,3 @@ class BIMUnitProperties(PropertyGroup):
|
|||||||
conversion_unit_types: EnumProperty(items=get_conversion_unit_types, name="Conversion Unit Types")
|
conversion_unit_types: EnumProperty(items=get_conversion_unit_types, name="Conversion Unit Types")
|
||||||
named_unit_types: EnumProperty(items=get_named_unit_types, name="Named Unit Types")
|
named_unit_types: EnumProperty(items=get_named_unit_types, name="Named Unit Types")
|
||||||
unit_attributes: CollectionProperty(name="Unit Attributes", type=Attribute)
|
unit_attributes: CollectionProperty(name="Unit Attributes", type=Attribute)
|
||||||
|
|
||||||
getter_enum = {
|
|
||||||
"unit_classes": get_unit_classes,
|
|
||||||
"conversion_unit_types": get_conversion_unit_types,
|
|
||||||
"named_unit_types": get_named_unit_types,
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -527,9 +527,10 @@ class ConfigureVisibility(bpy.types.Operator):
|
|||||||
|
|
||||||
|
|
||||||
def update_enum_property_search_prop(self, context):
|
def update_enum_property_search_prop(self, context):
|
||||||
for i, prop in enumerate(self.collection_name):
|
for i, prop in enumerate(self.collection_names):
|
||||||
if prop.name == self.dummy_name:
|
if prop.name == self.dummy_name:
|
||||||
setattr(context.data, self.prop_name, self.collection_identifier[i].name)
|
setattr(context.data, self.prop_name, self.collection_identifiers[i].name)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
class BIM_OT_enum_property_search(bpy.types.Operator):
|
class BIM_OT_enum_property_search(bpy.types.Operator):
|
||||||
@@ -537,28 +538,55 @@ class BIM_OT_enum_property_search(bpy.types.Operator):
|
|||||||
bl_label = "Search For Property"
|
bl_label = "Search For Property"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
dummy_name: bpy.props.StringProperty(name="Property", update=update_enum_property_search_prop)
|
dummy_name: bpy.props.StringProperty(name="Property", update=update_enum_property_search_prop)
|
||||||
collection_name: bpy.props.CollectionProperty(type=StrProperty)
|
collection_names: bpy.props.CollectionProperty(type=StrProperty)
|
||||||
collection_identifier: bpy.props.CollectionProperty(type=StrProperty)
|
collection_identifiers: bpy.props.CollectionProperty(type=StrProperty)
|
||||||
prop_name: bpy.props.StringProperty()
|
prop_name: bpy.props.StringProperty()
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
|
self.clear_collections()
|
||||||
self.data = context.data
|
self.data = context.data
|
||||||
getter = self.data.getter_enum.get(self.prop_name, None)
|
items = self.data.__annotations__[self.prop_name].keywords.get("items")
|
||||||
if getter is None:
|
if items is None:
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
self.collection_name.clear()
|
if not isinstance(items, list):
|
||||||
self.collection_identifier.clear()
|
items = items(self.data, context)
|
||||||
for item in getter(self.data, context):
|
self.add_items_regular(items)
|
||||||
self.collection_identifier.add().name = item[0]
|
self.add_items_suggestions()
|
||||||
if item[0] == getattr(self.data, self.prop_name):
|
|
||||||
self.dummy_name = item[1] # We found the current enum value
|
|
||||||
self.collection_name.add().name = item[1]
|
|
||||||
return context.window_manager.invoke_props_dialog(self)
|
return context.window_manager.invoke_props_dialog(self)
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
# Mandatory to access context.data in update :
|
# Mandatory to access context.data in update :
|
||||||
self.layout.context_pointer_set(name="data", data=self.data)
|
self.layout.context_pointer_set(name="data", data=self.data)
|
||||||
self.layout.prop_search(self, "dummy_name", self, "collection_name")
|
self.layout.prop_search(self, "dummy_name", self, "collection_names")
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def clear_collections(self):
|
||||||
|
self.collection_names.clear()
|
||||||
|
self.collection_identifiers.clear()
|
||||||
|
|
||||||
|
def add_item(self, identifier: str, name: str):
|
||||||
|
self.collection_identifiers.add().name = identifier
|
||||||
|
self.collection_names.add().name = name
|
||||||
|
|
||||||
|
def add_items_regular(self, items):
|
||||||
|
self.identifiers = []
|
||||||
|
for item in items:
|
||||||
|
self.identifiers.append(item[0])
|
||||||
|
self.add_item(identifier=item[0], name=item[1])
|
||||||
|
if item[0] == getattr(self.data, self.prop_name):
|
||||||
|
self.dummy_name = item[1] # We found the current enum name
|
||||||
|
|
||||||
|
def add_items_suggestions(self):
|
||||||
|
getter_suggestions = getattr(self.data, "getter_enum_suggestions", None)
|
||||||
|
if getter_suggestions is not None:
|
||||||
|
mapping = getter_suggestions.get(self.prop_name)
|
||||||
|
if mapping is None:
|
||||||
|
return
|
||||||
|
for key, values in mapping().items():
|
||||||
|
if key in self.identifiers:
|
||||||
|
if not isinstance(values, (tuple, list)):
|
||||||
|
values = [values]
|
||||||
|
for value in values:
|
||||||
|
self.add_item(identifier=key, name=key + " (" + value + ")")
|
||||||
|
|||||||
@@ -240,10 +240,6 @@ class Attribute(PropertyGroup):
|
|||||||
value = str(value)
|
value = str(value)
|
||||||
setattr(self, self.get_value_name(), value)
|
setattr(self, self.get_value_name(), value)
|
||||||
|
|
||||||
getter_enum = {
|
|
||||||
"enum_value": getAttributeEnumValues,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ModuleVisibility(PropertyGroup):
|
class ModuleVisibility(PropertyGroup):
|
||||||
name: StringProperty(name="Name")
|
name: StringProperty(name="Name")
|
||||||
|
|||||||
Reference in New Issue
Block a user