Run black

This commit is contained in:
Dion Moult
2022-08-01 19:45:36 +10:00
parent d2083b9a3d
commit ffe9ac6614
18 changed files with 116 additions and 97 deletions
@@ -882,7 +882,7 @@ class ActivateBcfViewpoint(bpy.types.Operator):
# Operators with context overrides are used because they are
# significantly faster than looping through all objects
exception_global_ids = [v.ifc_guid for v in viewpoint.components.visibility.exceptions]
exception_global_ids = {v.ifc_guid for v in viewpoint.components.visibility.exceptions}
if viewpoint.components.visibility.default_visibility:
old = context.area.type
@@ -39,7 +39,7 @@ class LoadGroups(bpy.types.Operator):
self.ifc = IfcStore.get_file()
if not self.is_refresh:
context.scene.ExpandedGroups.json_string = "{}"
for ifc_definition_id, group in Data.groups.items():
if not group["HasAssignments"]:
new = self.props.groups.add()
@@ -48,17 +48,19 @@ class LoadGroups(bpy.types.Operator):
new.selection_query = group["Description"].split("*selector*")[1] if group["Description"] else ""
new.has_children = True if len(group["IsGroupedBy"]) != 0 else False
new.tree_depth = 0
if self.is_refresh:
self.recursively_load_sub_groups(ifc_definition_id, new)
self.props.is_editing = True
bpy.ops.bim.disable_editing_group()
Data.load(IfcStore.get_file())
return {"FINISHED"}
def recursively_load_sub_groups(self, ifc_definition_id, parent):
sub_groups = ([k for k,v in Data.products.items() if self.ifc.by_id(k).is_a("IfcGroup") and ifc_definition_id in v])
sub_groups = [
k for k, v in Data.products.items() if self.ifc.by_id(k).is_a("IfcGroup") and ifc_definition_id in v
]
if str(ifc_definition_id) not in self.expanded_groups or sub_groups == []:
return
else:
@@ -67,7 +69,11 @@ class LoadGroups(bpy.types.Operator):
new = self.props.groups.add()
new.ifc_definition_id = group
new.name = Data.groups[group]["Name"]
new.selection_query = Data.groups[group]["Description"].split("*selector*")[1] if Data.groups[group]["Description"] else ""
new.selection_query = (
Data.groups[group]["Description"].split("*selector*")[1]
if Data.groups[group]["Description"]
else ""
)
new.has_children = True if len(Data.groups[group]["IsGroupedBy"]) != 0 else False
new.tree_depth = parent.tree_depth + 1
self.recursively_load_sub_groups(new.ifc_definition_id, new)
@@ -115,11 +121,11 @@ class AddGroup(bpy.types.Operator):
def _execute(self, context):
result = ifcopenshell.api.run("group.add_group", IfcStore.get_file())
Data.load(IfcStore.get_file())
bpy.ops.bim.load_groups(is_refresh=True)
bpy.ops.bim.enable_editing_group(group=result.id())
return {"FINISHED"}
class AddGroupToGroup(bpy.types.Operator):
bl_idname = "bim.add_group_to_group"
@@ -134,12 +140,7 @@ class AddGroupToGroup(bpy.types.Operator):
self.file = IfcStore.get_file()
result = ifcopenshell.api.run("group.add_group", self.file)
ifcopenshell.api.run(
"group.assign_group",
IfcStore.get_file(),
**{
"product": [result],
"group" : self.file.by_id(self.group)
}
"group.assign_group", IfcStore.get_file(), **{"product": [result], "group": self.file.by_id(self.group)}
)
Data.load(IfcStore.get_file())
bpy.ops.bim.load_groups(is_refresh=True)
@@ -163,10 +164,10 @@ class EditGroup(bpy.types.Operator):
attributes[attribute.name] = None
else:
attributes[attribute.name] = attribute.string_value
if self.copy_from_selector:
attributes["Description"] = context.scene.IFCSelector.selection_query
self.file = IfcStore.get_file()
ifcopenshell.api.run(
"group.edit_group", self.file, **{"group": self.file.by_id(props.active_group_id), "attributes": attributes}
@@ -301,6 +302,7 @@ class SelectGroupProducts(bpy.types.Operator):
obj.select_set(True)
return {"FINISHED"}
class UpdateGroup(bpy.types.Operator):
bl_idname = "bim.update_group"
bl_label = "Update Group"
@@ -37,6 +37,7 @@ from bpy.props import (
class ExpandedGroups(StrProperty):
json_string: StringProperty(name="JSON String", default="{}")
class Group(PropertyGroup):
name: StringProperty(name="Name")
ifc_definition_id: IntProperty(name="IFC Definition ID")
@@ -44,7 +45,8 @@ class Group(PropertyGroup):
is_expanded: BoolProperty(name="Is Expanded", default=False)
has_children: BoolProperty(name="Has Children")
tree_depth: IntProperty(name="Tree Depth")
class BIMGroupProperties(PropertyGroup):
group_attributes: CollectionProperty(name="Group Attributes", type=Attribute)
is_editing: BoolProperty(name="Is Editing", default=False)
@@ -52,4 +54,3 @@ class BIMGroupProperties(PropertyGroup):
groups: CollectionProperty(name="Groups", type=Group)
active_group_index: IntProperty(name="Active Group Index")
active_group_id: IntProperty(name="Active Group Id")
@@ -122,10 +122,8 @@ class BIM_UL_groups(UIList):
row.label(text="", icon="BLANK1")
if item.has_children:
op = row.operator(
"bim.toggle_group",
icon="TRIA_DOWN" if item.is_expanded else "TRIA_RIGHT",
text="",
emboss=False)
"bim.toggle_group", icon="TRIA_DOWN" if item.is_expanded else "TRIA_RIGHT", text="", emboss=False
)
op.ifc_definition_id = item.ifc_definition_id
op.index = index
op.option = "Collapse" if item.is_expanded else "Expand"
@@ -173,10 +171,8 @@ class BIM_UL_object_groups(UIList):
row.label(text="", icon="BLANK1")
if item.has_children:
op = row.operator(
"bim.toggle_group",
icon="TRIA_DOWN" if item.is_expanded else "TRIA_RIGHT",
text="",
emboss=False)
"bim.toggle_group", icon="TRIA_DOWN" if item.is_expanded else "TRIA_RIGHT", text="", emboss=False
)
op.ifc_definition_id = item.ifc_definition_id
op.index = index
op.option = "Collapse" if item.is_expanded else "Expand"
@@ -91,9 +91,7 @@ class AuthoringData:
@classmethod
def relating_types(cls, ifc_class=None):
return [
(str(e.id()), e.Name, e.Description or "") for e in cls.constr_class_entities(ifc_class=ifc_class)
]
return [(str(e.id()), e.Name, e.Description or "") for e in cls.constr_class_entities(ifc_class=ifc_class)]
@classmethod
def relating_types_browser(cls):
@@ -116,8 +114,10 @@ class AuthoringData:
for constr_class_entity in constr_class_occurrences:
### handle asset regeneration when library entity is updated ¿?
if (ifc_class not in preview_constr_types
or str(constr_class_entity.id()) not in preview_constr_types[ifc_class]):
if (
ifc_class not in preview_constr_types
or str(constr_class_entity.id()) not in preview_constr_types[ifc_class]
):
obj = tool.Ifc.get_object(constr_class_entity)
cls.assetize_object(obj, ifc_class, constr_class_entity)
relating_type_info = cls.relating_type_info(ifc_class)
@@ -127,10 +127,10 @@ class AuthoringData:
def assetize_object(cls, obj, ifc_class, ifc_class_entity, from_selection=False):
relating_type_id = ifc_class_entity.id()
to_be_deleted = False
if obj.type == 'EMPTY':
if obj.type == "EMPTY":
kwargs = {}
if not from_selection:
kwargs.update({'ifc_class': ifc_class, 'relating_type_id': relating_type_id})
kwargs.update({"ifc_class": ifc_class, "relating_type_id": relating_type_id})
new_obj = cls.new_relating_type(**kwargs)
if new_obj is not None:
to_be_deleted = True
@@ -165,6 +165,7 @@ class DumbProfileGenerator:
try:
obj.select_set(True)
except RuntimeError:
def msg(self, context):
txt = "The created object could not be assigned to a collection. "
txt += "Has any IfcSpatialElement been deleted?"
@@ -43,9 +43,10 @@ def update_icon_id(self, context):
ifc_class_browser = self.ifc_class_browser
relating_type_id_browser = self.relating_type_id_browser
relating_type_browser = AuthoringData.relating_type_name_by_id(ifc_class_browser, relating_type_id_browser)
if ((ifc_class_browser not in AuthoringData.data["preview_constr_types"]
or relating_type_id_browser not in AuthoringData.data["preview_constr_types"][ifc_class_browser])
and relating_type_browser is not None):
if (
ifc_class_browser not in AuthoringData.data["preview_constr_types"]
or relating_type_id_browser not in AuthoringData.data["preview_constr_types"][ifc_class_browser]
) and relating_type_browser is not None:
if not AuthoringData.assetize_relating_type_from_selection():
return
self.icon_id = AuthoringData.data["preview_constr_types"][ifc_class_browser][relating_type_id_browser]["icon_id"]
@@ -85,7 +86,9 @@ def update_relating_type_by_name(self, context):
def update_relating_type_browser_by_name(self, context):
AuthoringData.load_relating_types_browser()
relating_type_id_browser = AuthoringData.relating_type_id_by_name(self.ifc_class_browser, self.relating_type_browser)
relating_type_id_browser = AuthoringData.relating_type_id_by_name(
self.ifc_class_browser, self.relating_type_browser
)
if relating_type_id_browser is not None:
self.relating_type_id_browser = relating_type_id_browser
@@ -119,10 +122,7 @@ class BIMModelProperties(PropertyGroup):
name="Occurrence Name Style",
)
occurrence_name_function: bpy.props.StringProperty(name="Occurrence Name Function")
getter_enum = {
"ifc_class_browser": get_ifc_class,
"relating_type_browser": get_relating_type_browser
}
getter_enum = {"ifc_class_browser": get_ifc_class, "relating_type_browser": get_relating_type_browser}
def get_relating_type_info(self, context):
@@ -131,9 +131,5 @@ def get_relating_type_info(self, context):
class ConstrTypeInfo(PropertyGroup):
name: bpy.props.StringProperty(name="Construction class")
relating_type: bpy.props.EnumProperty(
name="Construction type", items=get_relating_type_info
)
relating_type: bpy.props.EnumProperty(name="Construction type", items=get_relating_type_info)
fully_loaded: bpy.props.BoolProperty(default=False)
@@ -309,6 +309,7 @@ class DumbSlabGenerator:
try:
obj.select_set(True)
except RuntimeError:
def msg(self, context):
txt = "The created object could not be assigned to a collection. "
txt += "Has any IfcSpatialElement been deleted?"
@@ -820,6 +820,7 @@ class DumbWallGenerator:
try:
obj.select_set(True)
except RuntimeError:
def msg(self, context):
txt = "The created object could not be assigned to a collection. "
txt += "Has any IfcSpatialElement been deleted?"
@@ -93,6 +93,7 @@ def get_ifc_classes_suggestions():
IfcClassData.load()
return IfcClassData.data["ifc_classes_suggestions"]
def get_contexts(self, context):
if not IfcClassData.is_loaded:
IfcClassData.load()
@@ -465,6 +465,7 @@ class ActivateIfcBuildingStoreyFilter(Operator):
row.operator("bim.toggle_filter_selection", text="Select All").action = "SELECT"
row.operator("bim.toggle_filter_selection", text="Deselect All").action = "DESELECT"
class UnhideAllElements(Operator):
"""Filter model elements based on selection"""
@@ -481,6 +482,7 @@ class UnhideAllElements(Operator):
class FilterModelElements(Operator):
"""Filter model elements based on selection"""
bl_idname = "bim.filter_model_elements"
bl_label = "Filter Model Elements"
option: StringProperty("select|isolate|hide")
@@ -563,6 +565,7 @@ class FilterModelElements(Operator):
class IfcSelector(Operator):
"""Select elements in model with IFC Selector"""
bl_idname = "bim.ifc_selector"
bl_label = "Select elements with IFC Selector"
@@ -578,6 +581,7 @@ class IfcSelector(Operator):
def draw(self, context):
from . import ui
ui.IfcSelectorUI.draw(context, self.layout)
@@ -603,6 +607,7 @@ class SaveSelectorQuery(Operator):
class OpenQueryLibrary(Operator):
"""Open Query Library"""
bl_idname = "bim.open_query_library"
bl_label = "Open Query Library"
@@ -633,53 +638,54 @@ class LoadQuery(Operator):
bl_idname = "bim.load_query"
bl_label = "Load Query"
index: IntProperty()
def invoke(self, context, event):
close_operator_panel(event)
return self.execute(context)
def execute(self, context):
ifc_selector = context.scene.IfcSelectorProperties
ifc_selector.selector_query_syntax = ifc_selector.query_library[self.index].query
return {"FINISHED"}
class AddToIfcGroup(Operator):
bl_idname = "bim.add_to_ifc_group"
bl_label = "Add to IFC Group"
group_name: StringProperty(name="Group Name")
def invoke(self, context, event):
bpy.ops.bim.load_groups()
return context.window_manager.invoke_props_dialog(self, width=400)
def draw(self, context):
self.props = context.scene.BIMGroupProperties
row = self.layout.row()
row.operator("bim.add_group")
self.layout.template_list(
"BIM_UL_groups",
"",
self.props,
"groups",
self.props,
"active_group_index",
)
"BIM_UL_groups",
"",
self.props,
"groups",
self.props,
"active_group_index",
)
if self.props.active_group_id:
for attribute in self.props.group_attributes:
if attribute.name in ["Name", "Description"]:
row = self.layout.row(align=True)
row.prop(attribute, "string_value", text=attribute.name)
def execute(self, context):
active_group_index = self.props.active_group_index
ifc_definition_id = self.props.groups[active_group_index].ifc_definition_id
bpy.ops.bim.enable_editing_group(group=ifc_definition_id)
bpy.ops.bim.enable_editing_group(group=ifc_definition_id)
selector_query_syntax = context.scene.IfcSelectorProperties.selector_query_syntax
for attribute in self.props.group_attributes:
if attribute.name == "Description":
if "*selector*" not in attribute.string_value:
@@ -688,7 +694,7 @@ class AddToIfcGroup(Operator):
new_description = attribute.string_value.split("*selector*")
new_description[1] = selector_query_syntax
attribute.string_value = "*selector*".join(new_description)
bpy.ops.bim.edit_group()
bpy.ops.bim.disable_group_editing_ui()
return {"FINISHED"}
@@ -175,6 +175,7 @@ class SearchCollection(PropertyGroup):
global_id: StringProperty()
query: StringProperty()
class IfcSelector:
and_or: EnumProperty(
items=[(i, i, i) for i in ["and", "or"]],
@@ -231,9 +232,9 @@ class SearchQueryGroup(PropertyGroup, IfcSelector):
class IfcSelectorProperties(PropertyGroup, IfcSelector):
groups: CollectionProperty(type=SearchQueryGroup)
selector_query_syntax: StringProperty()
query_library: CollectionProperty(type=SearchCollection)
active_query: StringProperty()
active_query: StringProperty()
manual_override: BoolProperty(default=False, description="Toggle to allow manual typing of query-syntax")
@@ -1850,7 +1850,6 @@ class VisualiseWorkScheduleDateRange(bpy.types.Operator):
self.total_frames = self.calculate_total_frames(context)
self.preprocess_tasks()
for obj in bpy.data.objects:
if not obj.BIMObjectProperties.ifc_definition_id:
continue
@@ -1862,7 +1861,6 @@ class VisualiseWorkScheduleDateRange(bpy.types.Operator):
self.animate_output(obj, product_frame)
self.add_text_animation_handler()
area = next(area for area in context.screen.areas if area.type == "VIEW_3D")
area.spaces[0].shading.color_type = "OBJECT"
context.scene.frame_start = self.start_frame
@@ -49,8 +49,8 @@ class BIM_PT_work_plans(Panel):
row = self.layout.row()
row.label(
text="{} Work Plans Found".format(SequenceData.number_of_work_plans_loaded),
icon="TEXT",
text="{} Work Plans Found".format(SequenceData.number_of_work_plans_loaded),
icon="TEXT",
)
row.operator("bim.add_work_plan", icon="ADD")
@@ -662,7 +662,9 @@ class AddStructuralLoadGroup(bpy.types.Operator):
def _execute(self, context):
self.file = IfcStore.get_file()
load_group = ifcopenshell.api.run("structural.add_structural_load_group", self.file)
ifcopenshell.api.run("group.assign_group", self.file, product=[load_group], group=self.file.by_id(self.load_case))
ifcopenshell.api.run(
"group.assign_group", self.file, product=[load_group], group=self.file.by_id(self.load_case)
)
Data.load(IfcStore.get_file())
return {"FINISHED"}
+9 -4
View File
@@ -1,6 +1,6 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>, 2022 Yassine Oualid <yassine@sigmadimensions.com>
#
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
@@ -21,24 +21,29 @@ def add_work_plan(ifc, sequence):
ifc.run("sequence.add_work_plan")
sequence.load_work_plans()
def remove_work_plan(ifc, sequence, work_plan=None):
ifc.run("sequence.remove_work_plan",**{"work_plan": ifc.get().by_id(work_plan)})
ifc.run("sequence.remove_work_plan", **{"work_plan": ifc.get().by_id(work_plan)})
sequence.load_work_plans()
def load_work_plan_attributes(sequence, work_plan=None):
data = sequence.get_ifc_work_plan_attributes(work_plan)
sequence.load_work_plan_attributes(data)
def enable_editing_work_plan(sequence, work_plan=None):
load_work_plan_attributes(sequence, work_plan)
sequence.enable_editing_work_plan(work_plan)
def disable_editing_work_plan(sequence):
sequence.disable_editing_work_plan()
def edit_work_plan(ifc, sequence):
work_plan = sequence.get_current_ifc_work_plan()
attributes = sequence.get_work_plan_attributes()
ifc.run("sequence.edit_work_plan",**{"work_plan": work_plan, "attributes": attributes})
ifc.run("sequence.edit_work_plan", **{"work_plan": work_plan, "attributes": attributes})
sequence.disable_editing_work_plan()
sequence.load_work_plans()
sequence.load_work_plans()
+10 -4
View File
@@ -80,19 +80,25 @@ class Sequence(blenderbim.core.tool.Sequence):
def load_work_plan_attributes(cls, data):
props = bpy.context.scene.BIMWorkPlanProperties
props.work_plan_attributes.clear()
blenderbim.bim.helper.import_attributes("IfcWorkPlan", props.work_plan_attributes, data, tool.Sequence.import_attributes)
blenderbim.bim.helper.import_attributes(
"IfcWorkPlan", props.work_plan_attributes, data, tool.Sequence.import_attributes
)
@classmethod
def import_attributes(name, prop, data):
if name in ["CreationDate", "StartTime", "FinishTime"]:
prop.string_value = "" if prop.is_null else data[name].isoformat()
return True
@classmethod
def get_work_plan_attributes(cls):
props = bpy.context.scene.BIMWorkPlanProperties
attributes = blenderbim.bim.helper.export_attributes(props.work_plan_attributes, tool.Sequence.export_attributes)
attributes = blenderbim.bim.helper.export_attributes(
props.work_plan_attributes, tool.Sequence.export_attributes
)
return attributes
@classmethod
def export_attributes(attributes, prop):
if "Date" in prop.name or "Time" in prop.name:
if prop.is_null:
@@ -105,4 +111,4 @@ class Sequence(blenderbim.core.tool.Sequence):
attributes[prop.name] = None
return True
attributes[prop.name] = helper.parse_duration(prop.string_value)
return True
return True
+17 -15
View File
@@ -109,7 +109,6 @@ def i_add_a_new_collection_item(collection):
assert False, "Collection does not exist"
@given(parsers.parse('the material "{name}" colour is set to "{colour}"'))
@when(parsers.parse('the material "{name}" colour is set to "{colour}"'))
def the_material_name_colour_is_set_to_colour(name, colour):
@@ -578,21 +577,21 @@ def the_object_name_has_no_modifiers(name):
@then(parsers.parse('the construction type "{ifc_class}"/"{relating_type}" has a preview'))
def the_construction_type_has_a_preview(ifc_class, relating_type):
if "preview_constr_types" not in AuthoringData.data:
assert False, 'There are no previews loaded'
assert False, "There are no previews loaded"
preview_constr_types = AuthoringData.data["preview_constr_types"]
if ifc_class not in preview_constr_types:
assert False, f'Construction class {ifc_class} has no available previews'
assert False, f"Construction class {ifc_class} has no available previews"
relating_type_id = AuthoringData.relating_type_id_by_name(ifc_class, relating_type)
if relating_type_id is None:
assert False, f'No construction type {ifc_class}/{relating_type} was found'
assert False, f"No construction type {ifc_class}/{relating_type} was found"
if relating_type_id not in preview_constr_types[ifc_class]:
assert False, f'Construction type {ifc_class}/{relating_type} has no available previews'
assert False, f"Construction type {ifc_class}/{relating_type} has no available previews"
preview_data = preview_constr_types[ifc_class][relating_type_id]
if 'icon_id' not in preview_data:
assert False, f'Construction type {ifc_class}/{relating_type} has a preview, but no assigned icon_id'
if "icon_id" not in preview_data:
assert False, f"Construction type {ifc_class}/{relating_type} has a preview, but no assigned icon_id"
icon_id = preview_data["icon_id"]
if not isinstance(icon_id, int):
assert False, f'Construction type {ifc_class}/{relating_type} has an invalid icon_id {icon_id}'
assert False, f"Construction type {ifc_class}/{relating_type} has an invalid icon_id {icon_id}"
# Note: icon_id must be > 0 in UI mode, but asset_generate_preview() doesn't work headlessly -> skipping for now
# if icon_id == 0:
# assert False, f'Construction type {ifc_class}/{relating_type} has the default null value for icon_id'
@@ -608,10 +607,10 @@ def there_is_a_construction_type_preview():
@then(parsers.parse('all construction types for "{ifc_class}" have a preview'))
def all_construction_types_have_a_preview(ifc_class):
if "preview_constr_types" not in AuthoringData.data:
assert False, 'There are no previews loaded'
assert False, "There are no previews loaded"
preview_constr_types = AuthoringData.data["preview_constr_types"]
if ifc_class not in preview_constr_types:
assert False, f'Construction class {ifc_class} has no available previews'
assert False, f"Construction class {ifc_class} has no available previews"
constr_class_occurrences = AuthoringData.constr_class_entities(ifc_class)
for constr_class_entity in constr_class_occurrences:
the_construction_type_has_a_preview(ifc_class, constr_class_entity.Name)
@@ -620,14 +619,14 @@ def all_construction_types_have_a_preview(ifc_class):
@given("I load the demo construction library")
@when("I load the demo construction library")
def i_add_a_construction_library():
lib_path = './blenderbim/bim/data/libraries/IFC4 Demo Library.ifc'
lib_path = "./blenderbim/bim/data/libraries/IFC4 Demo Library.ifc"
bpy.ops.bim.select_library_file(filepath=lib_path, append_all=True)
@given("I display the construction type browser")
@when("I display the construction type browser")
def i_display_the_construction_type_browser():
bpy.ops.bim.display_relating_types('INVOKE_DEFAULT')
bpy.ops.bim.display_relating_types("INVOKE_DEFAULT")
@given("I preview only one asset on the construction type browser")
@@ -663,9 +662,12 @@ def i_add_the_active_construction_type():
@then(parsers.parse("browser construction type is {relating_type_name}"))
def browser_construction_type(relating_type_name):
props = bpy.context.scene.BIMModelProperties
relating_type_browser = AuthoringData.relating_type_name_by_id(props.ifc_class_browser, props.relating_type_id_browser)
assert relating_type_browser == relating_type_name, (f"Construction Type is a {relating_type_browser}, not " +
f"a {relating_type_name}")
relating_type_browser = AuthoringData.relating_type_name_by_id(
props.ifc_class_browser, props.relating_type_id_browser
)
assert relating_type_browser == relating_type_name, (
f"Construction Type is a {relating_type_browser}, not " + f"a {relating_type_name}"
)
@then(parsers.parse("construction type is {relating_type_name}"))