This commit is contained in:
Andrej730
2025-02-28 11:08:42 +05:00
parent 9187f2d2b5
commit 277aaca6c5
15 changed files with 184 additions and 102 deletions
+1 -1
View File
@@ -289,7 +289,7 @@ def get_user(ifc: ifcopenshell.file) -> Union[ifcopenshell.entity_instance, None
def viewport_shading_changed_callback(area: bpy.types.Area) -> None: def viewport_shading_changed_callback(area: bpy.types.Area) -> None:
shading = area.spaces.active.shading.type shading = area.spaces.active.shading.type
if shading == "RENDERED": if shading == "RENDERED":
bpy.context.scene.BIMStylesProperties.active_style_type = "External" tool.Style.get_style_props().active_style_type = "Internal"
def subscribe_to_viewport_shading_changes(): def subscribe_to_viewport_shading_changes():
@@ -311,7 +311,9 @@ class CadHotkey(bpy.types.Operator):
bpy.ops.bim.reset_vertex() bpy.ops.bim.reset_vertex()
def add_header_apply_button(layout, text, apply_operator, cancel_operator, ui_context=""): def add_header_apply_button(
layout: bpy.types.UILayout, text: str, apply_operator: str, cancel_operator: str, ui_context: str = ""
) -> None:
custom_icon = custom_icon_previews.get(text.upper().replace(" ", "_"), custom_icon_previews["IFC"]).icon_id custom_icon = custom_icon_previews.get(text.upper().replace(" ", "_"), custom_icon_previews["IFC"]).icon_id
row = layout.row(align=True) row = layout.row(align=True)
row.label(text=f"{text} Mode", icon_value=custom_icon) row.label(text=f"{text} Mode", icon_value=custom_icon)
@@ -704,13 +704,13 @@ class PurgeUnusedObjects(bpy.types.Operator, tool.Ifc.Operator):
if purged == 0: if purged == 0:
return return
scene = context.scene
if object_type == "PROFILE": if object_type == "PROFILE":
props = tool.Profile.get_profile_props() props = tool.Profile.get_profile_props()
if props.is_editing: if props.is_editing:
bpy.ops.bim.load_profiles() bpy.ops.bim.load_profiles()
elif object_type == "STYLE": elif object_type == "STYLE":
if scene.BIMStylesProperties.is_editing: props = tool.Style.get_style_props()
if props.is_editing:
bpy.ops.bim.load_styles() bpy.ops.bim.load_styles()
elif object_type == "MATERIAL": elif object_type == "MATERIAL":
props = tool.Material.get_material_props() props = tool.Material.get_material_props()
@@ -754,13 +754,13 @@ class MergeIdenticalObjects(bpy.types.Operator, tool.Ifc.Operator):
if merged == 0: if merged == 0:
return return
scene = context.scene
if object_type == "PROFILE": if object_type == "PROFILE":
props = tool.Profile.get_profile_props() props = tool.Profile.get_profile_props()
if props.is_editing: if props.is_editing:
bpy.ops.bim.load_profiles() bpy.ops.bim.load_profiles()
elif object_type == "STYLE": elif object_type == "STYLE":
if scene.BIMStylesProperties.is_editing: props = tool.Style.get_style_props()
if props.is_editing:
bpy.ops.bim.load_styles() bpy.ops.bim.load_styles()
elif object_type == "MATERIAL": elif object_type == "MATERIAL":
props = tool.Material.get_material_props() props = tool.Material.get_material_props()
@@ -576,30 +576,30 @@ class EditAssignedMaterial(bpy.types.Operator, tool.Ifc.Operator):
material_set = self.file.by_id(self.material_set) material_set = self.file.by_id(self.material_set)
attributes = bonsai.bim.helper.export_attributes(props.material_set_attributes) attributes = bonsai.bim.helper.export_attributes(props.material_set_attributes)
ifcopenshell.api.run( ifcopenshell.api.material.edit_assigned_material(
"material.edit_assigned_material",
self.file, self.file,
**{"element": material_set, "attributes": attributes}, element=material_set,
attributes=attributes,
) )
if self.material_set_usage: if self.material_set_usage:
material_set_usage = self.file.by_id(self.material_set_usage) material_set_usage = self.file.by_id(self.material_set_usage)
attributes = bonsai.bim.helper.export_attributes(props.material_set_usage_attributes) attributes = bonsai.bim.helper.export_attributes(props.material_set_usage_attributes)
if material_set_usage.is_a("IfcMaterialLayerSetUsage"): if material_set_usage.is_a("IfcMaterialLayerSetUsage"):
ifcopenshell.api.run( ifcopenshell.api.material.edit_layer_usage(
"material.edit_layer_usage",
self.file, self.file,
**{"usage": material_set_usage, "attributes": attributes}, usage=material_set_usage,
attributes=attributes,
) )
slab.DumbSlabPlaner().regenerate_from_layer_set(material_set_usage.ForLayerSet) slab.DumbSlabPlaner().regenerate_from_layer_set(material_set_usage.ForLayerSet)
wall.DumbWallPlaner().regenerate_from_layer_set(material_set_usage.ForLayerSet) wall.DumbWallPlaner().regenerate_from_layer_set(material_set_usage.ForLayerSet)
elif material_set_usage.is_a("IfcMaterialProfileSetUsage"): elif material_set_usage.is_a("IfcMaterialProfileSetUsage"):
if attributes.get("CardinalPoint", None): if attributes.get("CardinalPoint", None):
attributes["CardinalPoint"] = int(attributes["CardinalPoint"]) attributes["CardinalPoint"] = int(attributes["CardinalPoint"])
ifcopenshell.api.run( ifcopenshell.api.material.edit_profile_usage(
"material.edit_profile_usage",
self.file, self.file,
**{"usage": material_set_usage, "attributes": attributes}, usage=material_set_usage,
attributes=attributes,
) )
bpy.ops.bim.disable_editing_assigned_material(obj=active_obj.name) bpy.ops.bim.disable_editing_assigned_material(obj=active_obj.name)
+7 -5
View File
@@ -28,7 +28,7 @@ from math import pi, radians
from bonsai.bim.module.model.decorator import WallAxisDecorator, SlabDirectionDecorator from bonsai.bim.module.model.decorator import WallAxisDecorator, SlabDirectionDecorator
from bonsai.bim.module.model.door import update_door_modifier_bmesh from bonsai.bim.module.model.door import update_door_modifier_bmesh
from bonsai.bim.module.model.window import update_window_modifier_bmesh from bonsai.bim.module.model.window import update_window_modifier_bmesh
from typing import TYPE_CHECKING, Literal, get_args, Union, get_args from typing import TYPE_CHECKING, Literal, get_args, Union, get_args, Any, Optional
def get_ifc_class(self: "BIMModelProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]: def get_ifc_class(self: "BIMModelProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]:
@@ -607,7 +607,7 @@ class BIMWindowProperties(PropertyGroup):
framing_material: str framing_material: str
glazing_material: str glazing_material: str
def get_general_kwargs(self, convert_to_project_units=False): def get_general_kwargs(self, convert_to_project_units: bool = False) -> dict[str, Any]:
kwargs = { kwargs = {
"window_type": self.window_type, "window_type": self.window_type,
"overall_height": self.overall_height, "overall_height": self.overall_height,
@@ -617,7 +617,9 @@ class BIMWindowProperties(PropertyGroup):
return kwargs return kwargs
return tool.Model.convert_data_to_project_units(kwargs, ["window_type"]) return tool.Model.convert_data_to_project_units(kwargs, ["window_type"])
def get_lining_kwargs(self, window_type=None, convert_to_project_units=False): def get_lining_kwargs(
self, window_type: Optional[WindowType] = None, convert_to_project_units: bool = False
) -> dict[str, Any]:
if not window_type: if not window_type:
window_type = self.window_type window_type = self.window_type
kwargs = { kwargs = {
@@ -660,7 +662,7 @@ class BIMWindowProperties(PropertyGroup):
return kwargs return kwargs
return tool.Model.convert_data_to_project_units(kwargs) return tool.Model.convert_data_to_project_units(kwargs)
def get_panel_kwargs(self, convert_to_project_units=False): def get_panel_kwargs(self, convert_to_project_units: bool = False) -> dict[str, Any]:
kwargs = { kwargs = {
"frame_depth": self.frame_depth, "frame_depth": self.frame_depth,
"frame_thickness": self.frame_thickness, "frame_thickness": self.frame_thickness,
@@ -669,7 +671,7 @@ class BIMWindowProperties(PropertyGroup):
return kwargs return kwargs
return tool.Model.convert_data_to_project_units(kwargs) return tool.Model.convert_data_to_project_units(kwargs)
def set_props_kwargs_from_ifc_data(self, kwargs): def set_props_kwargs_from_ifc_data(self, kwargs: dict[str, Any]):
kwargs = tool.Model.convert_data_to_si_units(kwargs, self.non_si_units_props) kwargs = tool.Model.convert_data_to_si_units(kwargs, self.non_si_units_props)
for prop_name in kwargs: for prop_name in kwargs:
setattr(self, prop_name, kwargs[prop_name]) setattr(self, prop_name, kwargs[prop_name])
@@ -28,6 +28,7 @@ import bonsai.core.root
import bonsai.core.geometry import bonsai.core.geometry
from ifcopenshell.api.geometry.add_window_representation import DEFAULT_PANEL_SCHEMAS from ifcopenshell.api.geometry.add_window_representation import DEFAULT_PANEL_SCHEMAS
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.material
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.representation import ifcopenshell.util.representation
import ifcopenshell.util.shape_builder import ifcopenshell.util.shape_builder
@@ -65,6 +65,9 @@ from bonsai.bim.module.model.decorator import PolylineDecorator
from bonsai.bim.module.model.polyline import PolylineOperator from bonsai.bim.module.model.polyline import PolylineOperator
from typing import Union, TYPE_CHECKING, Literal, get_args from typing import Union, TYPE_CHECKING, Literal, get_args
if TYPE_CHECKING:
from bonsai.bim.module.project.prop import Link
class NewProject(bpy.types.Operator): class NewProject(bpy.types.Operator):
bl_idname = "bim.new_project" bl_idname = "bim.new_project"
@@ -1484,7 +1487,7 @@ class ToggleLinkVisibility(bpy.types.Operator):
self.toggle_visibility(link) self.toggle_visibility(link)
return {"FINISHED"} return {"FINISHED"}
def toggle_wireframe(self, link): def toggle_wireframe(self, link: "Link") -> None:
for collection in self.get_linked_collections(): for collection in self.get_linked_collections():
objs = filter(lambda obj: "IfcOpeningElement" not in obj.name, collection.all_objects) objs = filter(lambda obj: "IfcOpeningElement" not in obj.name, collection.all_objects)
for i, obj in enumerate(objs): for i, obj in enumerate(objs):
@@ -1496,7 +1499,7 @@ class ToggleLinkVisibility(bpy.types.Operator):
obj.display_type = display_type obj.display_type = display_type
link.is_wireframe = display_type == "WIRE" link.is_wireframe = display_type == "WIRE"
def toggle_visibility(self, link): def toggle_visibility(self, link: "Link") -> None:
linked_collections = self.get_linked_collections() linked_collections = self.get_linked_collections()
link.is_hidden = (is_hidden := not link.is_hidden) link.is_hidden = (is_hidden := not link.is_hidden)
+22 -15
View File
@@ -224,7 +224,8 @@ class UpdateCurrentStyle(bpy.types.Operator):
current_style_type = material.BIMStyleProperties.active_style_type current_style_type = material.BIMStyleProperties.active_style_type
if self.update_all: if self.update_all:
context.scene.BIMStylesProperties.active_style_type = current_style_type sprops = tool.Style.get_style_props()
sprops.active_style_type = current_style_type
return {"FINISHED"} return {"FINISHED"}
updated_materials = set() updated_materials = set()
@@ -258,8 +259,9 @@ class SetAssetMaterialToExternalStyle(bpy.types.Operator):
# the temp override to copy material node tree `right now` # the temp override to copy material node tree `right now`
name = context.asset.name name = context.asset.name
filepath = context.asset.full_library_path filepath = context.asset.full_library_path
props = tool.Style.get_style_props()
bpy.app.timers.register( bpy.app.timers.register(
lambda: self.execute_delayed(name, filepath, context.scene.BIMStylesProperties), lambda: self.execute_delayed(name, filepath, props),
first_interval=0.001, first_interval=0.001,
) )
return {"FINISHED"} return {"FINISHED"}
@@ -388,7 +390,8 @@ class BrowseExternalStyle(bpy.types.Operator):
bpy.data.materials.remove(db["data_block"]) bpy.data.materials.remove(db["data_block"])
filepath = tool.Ifc.get_uri(self.filepath, use_relative_path=self.use_relative_path) filepath = tool.Ifc.get_uri(self.filepath, use_relative_path=self.use_relative_path)
attributes = context.scene.BIMStylesProperties.external_style_attributes props = tool.Style.get_style_props()
attributes = props.external_style_attributes
attributes["Location"].string_value = filepath attributes["Location"].string_value = filepath
attributes["Identification"].string_value = f"{self.data_block_type}/{self.data_block}" attributes["Identification"].string_value = f"{self.data_block_type}/{self.data_block}"
attributes["Name"].string_value = self.data_block attributes["Name"].string_value = self.data_block
@@ -416,7 +419,7 @@ class ActivateExternalStyle(bpy.types.Operator):
self.report({"INFO"}, "Material '{self.material_name}' is not an IFC style.") self.report({"INFO"}, "Material '{self.material_name}' is not an IFC style.")
return {"CANCELLED"} return {"CANCELLED"}
props = context.scene.BIMStylesProperties props = tool.Style.get_style_props()
if props.is_editing_style == style.id() and props.is_editing_class == "IfcExternallyDefinedSurfaceStyle": if props.is_editing_style == style.id() and props.is_editing_class == "IfcExternallyDefinedSurfaceStyle":
location = props.external_style_attributes["Location"].string_value location = props.external_style_attributes["Location"].string_value
identification = props.external_style_attributes["Identification"].string_value identification = props.external_style_attributes["Identification"].string_value
@@ -509,7 +512,8 @@ class LoadStyles(bpy.types.Operator):
style_type: bpy.props.StringProperty() style_type: bpy.props.StringProperty()
def execute(self, context): def execute(self, context):
style_type = self.style_type if self.style_type else context.scene.BIMStylesProperties.style_type props = tool.Style.get_style_props()
style_type = self.style_type if self.style_type else props.style_type
core.load_styles(tool.Style, style_type=style_type) core.load_styles(tool.Style, style_type=style_type)
bonsai.bim.handler.refresh_ui_data() bonsai.bim.handler.refresh_ui_data()
return {"FINISHED"} return {"FINISHED"}
@@ -561,7 +565,8 @@ class ChooseTextureMapPath(bpy.types.Operator):
return {"CANCELLED"} return {"CANCELLED"}
filepath = tool.Ifc.get_uri(self.filepath, use_relative_path=self.use_relative_path) filepath = tool.Ifc.get_uri(self.filepath, use_relative_path=self.use_relative_path)
texture = context.scene.BIMStylesProperties.textures[self.texture_map_index] props = tool.Style.get_style_props()
texture = props.textures[self.texture_map_index]
texture.path = filepath texture.path = filepath
return {"FINISHED"} return {"FINISHED"}
@@ -577,7 +582,7 @@ class RemoveTextureMap(bpy.types.Operator):
self.report({"ERROR"}, "Provide a texture map index") self.report({"ERROR"}, "Provide a texture map index")
return {"CANCELLED"} return {"CANCELLED"}
props = context.scene.BIMStylesProperties props = tool.Style.get_style_props()
props.textures.remove(self.texture_map_index) props.textures.remove(self.texture_map_index)
# just to trigger shader graph update # just to trigger shader graph update
props.surface_colour = props.surface_colour props.surface_colour = props.surface_colour
@@ -612,7 +617,8 @@ class DuplicateStyle(bpy.types.Operator, tool.Ifc.Operator):
style: bpy.props.IntProperty(name="Style ID") style: bpy.props.IntProperty(name="Style ID")
def _execute(self, context): def _execute(self, context):
style_type = context.scene.BIMStylesProperties.style_type props = tool.Style.get_style_props()
style_type = props.style_type
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
style = ifc_file.by_id(self.style) style = ifc_file.by_id(self.style)
tool.Style.duplicate_style(style) tool.Style.duplicate_style(style)
@@ -636,7 +642,7 @@ class AddPresentationStyle(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def _execute(self, context): def _execute(self, context):
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
if props.style_type == "IfcSurfaceStyle": if props.style_type == "IfcSurfaceStyle":
style = ifcopenshell.api.run("style.add_style", tool.Ifc.get(), name=props.style_name) style = ifcopenshell.api.run("style.add_style", tool.Ifc.get(), name=props.style_name)
@@ -692,7 +698,7 @@ class EnableEditingSurfaceStyle(bpy.types.Operator):
ifc_class: bpy.props.StringProperty(default="") ifc_class: bpy.props.StringProperty(default="")
def execute(self, context): def execute(self, context):
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
style = tool.Ifc.get().by_id(self.style) style = tool.Ifc.get().by_id(self.style)
style_elements = tool.Style.get_style_elements(style) style_elements = tool.Style.get_style_elements(style)
@@ -753,7 +759,7 @@ class EditSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
surface_style: Union[ifcopenshell.entity_instance, None] surface_style: Union[ifcopenshell.entity_instance, None]
def _execute(self, context): def _execute(self, context):
self.props = bpy.context.scene.BIMStylesProperties self.props = tool.Style.get_style_props()
self.style = tool.Ifc.get().by_id(self.props.is_editing_style) self.style = tool.Ifc.get().by_id(self.props.is_editing_style)
style_elements = tool.Style.get_style_elements(self.style) style_elements = tool.Style.get_style_elements(self.style)
@@ -950,13 +956,14 @@ class AddSurfaceTexture(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
if len(context.scene.BIMStylesProperties.textures) >= 8: props = tool.Style.get_style_props()
if len(props.textures) >= 8:
cls.poll_message_set("Only 8 texture maps available") cls.poll_message_set("Only 8 texture maps available")
return False return False
return True return True
def execute(self, context): def execute(self, context):
props = context.scene.BIMStylesProperties props = tool.Style.get_style_props()
props.textures.add() props.textures.add()
return {"FINISHED"} return {"FINISHED"}
@@ -1183,7 +1190,7 @@ class SelectStyleInStylesUI(bpy.types.Operator):
style_id: bpy.props.IntProperty() style_id: bpy.props.IntProperty()
def execute(self, context): def execute(self, context):
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
style = ifc_file.by_id(self.style_id) style = ifc_file.by_id(self.style_id)
core.load_styles(tool.Style, style.is_a()) core.load_styles(tool.Style, style.is_a())
@@ -1204,7 +1211,7 @@ class RemoveSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context): def _execute(self, context):
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
props = context.scene.BIMStylesProperties props = tool.Style.get_style_props()
style = ifc_file.by_id(props.is_editing_style) style = ifc_file.by_id(props.is_editing_style)
surface_style = tool.Style.get_style_elements(style)[props.is_editing_class] surface_style = tool.Style.get_style_elements(style)[props.is_editing_class]
ifcopenshell.api.style.remove_surface_style(ifc_file, surface_style) ifcopenshell.api.style.remove_surface_style(ifc_file, surface_style)
+60 -16
View File
@@ -33,7 +33,7 @@ from bpy.props import (
) )
import gettext import gettext
from typing import Literal, Union from typing import Literal, Union, TYPE_CHECKING, get_args
_ = gettext.gettext _ = gettext.gettext
@@ -154,6 +154,17 @@ class ColourRgb(PropertyGroup):
return "color_value" return "color_value"
SurfaceStyleClass = Literal[
"IfcSurfaceStyleShading",
"IfcSurfaceStyleRendering",
"IfcSurfaceStyleWithTextures",
"IfcSurfaceStyleLighting",
"IfcSurfaceStyleRefraction",
"IfcExternallyDefinedSurfaceStyle",
]
ColourClass = Literal["IfcColourRgb", "IfcNormalisedRatioMeasure"]
class BIMStylesProperties(PropertyGroup): class BIMStylesProperties(PropertyGroup):
is_adding: BoolProperty(name="Is Adding", description="Is adding new IfcPresentationStyle") is_adding: BoolProperty(name="Is Adding", description="Is adding new IfcPresentationStyle")
is_editing: BoolProperty(name="Is Editing", description="Is editing IfcPresentationStyle") is_editing: BoolProperty(name="Is Editing", description="Is editing IfcPresentationStyle")
@@ -170,17 +181,7 @@ class BIMStylesProperties(PropertyGroup):
style_type: EnumProperty(items=get_style_types, default=2, name="Style Type") style_type: EnumProperty(items=get_style_types, default=2, name="Style Type")
style_name: StringProperty(name="Style Name") style_name: StringProperty(name="Style Name")
surface_style_class: EnumProperty( surface_style_class: EnumProperty(
items=[ items=[(x, x, "") for x in get_args(SurfaceStyleClass)],
(x, x, "")
for x in (
"IfcSurfaceStyleShading",
"IfcSurfaceStyleRendering",
"IfcSurfaceStyleWithTextures",
"IfcSurfaceStyleLighting",
"IfcSurfaceStyleRefraction",
"IfcExternallyDefinedSurfaceStyle",
)
],
name="Surface Style Class", name="Surface Style Class",
default="IfcSurfaceStyleShading", default="IfcSurfaceStyleShading",
) )
@@ -200,7 +201,7 @@ class BIMStylesProperties(PropertyGroup):
# TODO: do something on null? # TODO: do something on null?
is_diffuse_colour_null: BoolProperty(name="Is Null") is_diffuse_colour_null: BoolProperty(name="Is Null")
diffuse_colour_class: EnumProperty( diffuse_colour_class: EnumProperty(
items=[(x, x, "") for x in ("IfcColourRgb", "IfcNormalisedRatioMeasure")], items=[(x, x, "") for x in get_args(ColourClass)],
name="Diffuse Colour Class", name="Diffuse Colour Class",
update=update_shader_graph, update=update_shader_graph,
) )
@@ -212,7 +213,7 @@ class BIMStylesProperties(PropertyGroup):
) )
is_specular_colour_null: BoolProperty(name="Is Null") is_specular_colour_null: BoolProperty(name="Is Null")
specular_colour_class: EnumProperty( specular_colour_class: EnumProperty(
items=[(x, x, "") for x in ("IfcColourRgb", "IfcNormalisedRatioMeasure")], items=[(x, x, "") for x in get_args(ColourClass)],
name="Specular Colour Class", name="Specular Colour Class",
update=update_shader_graph, update=update_shader_graph,
default="IfcNormalisedRatioMeasure", default="IfcNormalisedRatioMeasure",
@@ -269,11 +270,49 @@ class BIMStylesProperties(PropertyGroup):
active_style_type: EnumProperty( active_style_type: EnumProperty(
name="Active Style Type", name="Active Style Type",
description="Update current blender material to match style type for all objects in the scene", description="Update current blender material to match style type for all objects in the scene",
items=STYLE_TYPES, items=[(i, i, "") for i in get_args(tool.Style.StyleType)],
default="Shading", default="Shading",
update=update_shading_styles, update=update_shading_styles,
) )
if TYPE_CHECKING:
is_adding: bool
is_editing: bool
is_editing_style: int
is_editing_class: str
is_editing_existing_style: bool
attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
external_style_attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
refraction_style_attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
lighting_style_colours: bpy.types.bpy_prop_collection_idprop[ColourRgb]
style_type: str
style_name: str
surface_style_class: SurfaceStyleClass
update_graph: bool
# Shading props.
surface_colour: tuple[float, float, float]
transparency: float
is_diffuse_colour_null: bool
diffuse_colour_class: ColourClass
diffuse_colour: tuple[float, float, float]
diffuse_colour_ratio: float
is_specular_colour_null: bool
specular_colour_class: ColourClass
specular_colour: tuple[float, float, float]
specular_colour_ratio: float
is_specular_highlight_null: bool
specular_highlight: float
reflectance_method: str
# Texture props.
textures: bpy.types.bpy_prop_collection_idprop[Texture]
uv_mode: Literal["UV", "Generated", "Camera"]
styles: bpy.types.bpy_prop_collection_idprop[Style]
active_style_index: int
active_style_type: tool.Style.StyleType
def update_shading_style(self: "BIMStyleProperties", context: bpy.types.Context) -> None: def update_shading_style(self: "BIMStyleProperties", context: bpy.types.Context) -> None:
blender_material = self.id_data blender_material = self.id_data
@@ -290,8 +329,13 @@ class BIMStyleProperties(PropertyGroup):
active_style_type: EnumProperty( active_style_type: EnumProperty(
name="Active Style Type", name="Active Style Type",
description="Update current blender material to match style type", description="Update current blender material to match style type",
items=STYLE_TYPES, items=[(i, i, "") for i in get_args(tool.Style.StyleType)],
default="Shading", default="Shading",
update=update_shading_style, update=update_shading_style,
) )
is_renaming: BoolProperty(description="Used to prevent triggering handler callback.", default=False) is_renaming: BoolProperty(description="Used to prevent triggering handler callback.", default=False)
if TYPE_CHECKING:
ifc_definition_id: int
active_style_type: tool.Style.StyleType
is_renaming: bool
+3 -3
View File
@@ -40,7 +40,7 @@ class BIM_PT_styles(Panel):
if not StylesData.is_loaded: if not StylesData.is_loaded:
StylesData.load() StylesData.load()
self.props = context.scene.BIMStylesProperties self.props = tool.Style.get_style_props()
if not self.props.is_editing: if not self.props.is_editing:
row = self.layout.row(align=True) row = self.layout.row(align=True)
@@ -258,7 +258,7 @@ class BIM_UL_styles(UIList):
def draw_item(self, context, layout: bpy.types.UILayout, data, item, icon, active_data, active_property): def draw_item(self, context, layout: bpy.types.UILayout, data, item, icon, active_data, active_property):
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
props = context.scene.BIMStylesProperties props = tool.Style.get_style_props()
if item.ifc_definition_id == props.is_editing_style: if item.ifc_definition_id == props.is_editing_style:
row.label(text="", icon="GREASEPENCIL") row.label(text="", icon="GREASEPENCIL")
row.prop(item, "name", text="", emboss=False) row.prop(item, "name", text="", emboss=False)
@@ -330,6 +330,6 @@ def draw_asset_browser_context_menu_append(self, context):
asset = context.asset asset = context.asset
if not asset or not asset.id_type == "MATERIAL": if not asset or not asset.id_type == "MATERIAL":
return return
if not context.scene.BIMStylesProperties.is_editing: if not tool.Style.get_style_props().is_editing:
return return
self.layout.operator("bim.set_asset_material_to_external_style") self.layout.operator("bim.set_asset_material_to_external_style")
+3 -3
View File
@@ -49,7 +49,7 @@ from bonsai.bim.module.geometry.helper import Helper
from bonsai.bim.module.model.data import AuthoringData, RailingData, RoofData, WindowData, DoorData from bonsai.bim.module.model.data import AuthoringData, RailingData, RoofData, WindowData, DoorData
from bonsai.bim.module.model.opening import FilledOpeningGenerator from bonsai.bim.module.model.opening import FilledOpeningGenerator
from ifcopenshell.util.shape_builder import ShapeBuilder from ifcopenshell.util.shape_builder import ShapeBuilder
from typing import Optional, Union, TypeVar, Any, Iterable, Literal, TYPE_CHECKING from typing import Optional, Union, TypeVar, Any, Iterable, Literal, TYPE_CHECKING, Sequence
T = TypeVar("T") T = TypeVar("T")
V_ = tool.Blender.V_ V_ = tool.Blender.V_
@@ -108,7 +108,7 @@ class Model(bonsai.core.tool.Model):
return value * cls.unit_scale return value * cls.unit_scale
@classmethod @classmethod
def convert_data_to_project_units(cls, data: dict[str, Any], non_si_props: list[str] = []) -> dict[str, Any]: def convert_data_to_project_units(cls, data: dict[str, Any], non_si_props: Sequence[str] = ()) -> dict[str, Any]:
si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
for prop_name in data: for prop_name in data:
if prop_name in non_si_props: if prop_name in non_si_props:
@@ -121,7 +121,7 @@ class Model(bonsai.core.tool.Model):
return data return data
@classmethod @classmethod
def convert_data_to_si_units(cls, data: dict[str, Any], non_si_props: list[str] = []) -> dict[str, Any]: def convert_data_to_si_units(cls, data: dict[str, Any], non_si_props: Sequence[str] = ()) -> dict[str, Any]:
si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
for prop_name in data: for prop_name in data:
if prop_name in non_si_props: if prop_name in non_si_props:
+40 -22
View File
@@ -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 Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy import bpy
import numpy as np import numpy as np
import ifcopenshell import ifcopenshell
import ifcopenshell.api.style
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.representation import ifcopenshell.util.representation
import bonsai.core.style import bonsai.core.style
@@ -26,7 +28,10 @@ import bonsai.core.tool
import bonsai.tool as tool import bonsai.tool as tool
import bonsai.bim.helper import bonsai.bim.helper
from mathutils import Color from mathutils import Color
from typing import Union, Any, Optional, Literal from typing import Union, Any, Optional, Literal, TYPE_CHECKING
if TYPE_CHECKING:
from bonsai.bim.module.style.prop import BIMStylesProperties, BIMStyleProperties
# fmt: off # fmt: off
TEXTURE_MAPS_BY_METHODS = { TEXTURE_MAPS_BY_METHODS = {
@@ -44,10 +49,18 @@ STYLE_PROPS_MAP = {
"specular_colour": "SpecularColour", "specular_colour": "SpecularColour",
} }
STYLE_TYPES = Literal["Shading", "External"]
class Style(bonsai.core.tool.Style): class Style(bonsai.core.tool.Style):
StyleType = Literal["Shading", "External"]
@classmethod
def get_style_props(cls) -> BIMStylesProperties:
return bpy.context.scene.BIMStylesProperties
@classmethod
def get_material_style_props(cls, material: bpy.types.Material) -> BIMStyleProperties:
return material.BIMStyleProperties
@classmethod @classmethod
def can_support_rendering_style(cls, obj: bpy.types.Material) -> bool: def can_support_rendering_style(cls, obj: bpy.types.Material) -> bool:
return obj.use_nodes and hasattr(obj.node_tree, "nodes") return obj.use_nodes and hasattr(obj.node_tree, "nodes")
@@ -58,19 +71,19 @@ class Style(bonsai.core.tool.Style):
@classmethod @classmethod
def enable_adding_presentation_style(cls) -> None: def enable_adding_presentation_style(cls) -> None:
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
props.is_adding = True props.is_adding = True
props.update_graph = False props.update_graph = False
@classmethod @classmethod
def disable_adding_presentation_style(cls) -> None: def disable_adding_presentation_style(cls) -> None:
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
props.is_adding = False props.is_adding = False
props.update_graph = True props.update_graph = True
@classmethod @classmethod
def disable_editing(cls) -> None: def disable_editing(cls) -> None:
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
props.is_editing_style = 0 props.is_editing_style = 0
props.is_editing_class = "" props.is_editing_class = ""
props.attributes.clear() props.attributes.clear()
@@ -81,7 +94,7 @@ class Style(bonsai.core.tool.Style):
@classmethod @classmethod
def disable_editing_styles(cls) -> None: def disable_editing_styles(cls) -> None:
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
props.is_editing = False props.is_editing = False
props.styles.clear() props.styles.clear()
@@ -100,27 +113,29 @@ class Style(bonsai.core.tool.Style):
@classmethod @classmethod
def enable_editing(cls, style: ifcopenshell.entity_instance) -> None: def enable_editing(cls, style: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
props.is_editing_style = style.id() props.is_editing_style = style.id()
props.is_editing_class = "IfcSurfaceStyle" props.is_editing_class = "IfcSurfaceStyle"
@classmethod @classmethod
def enable_editing_styles(cls) -> None: def enable_editing_styles(cls) -> None:
bpy.context.scene.BIMStylesProperties.is_editing = True props = cls.get_style_props()
props.is_editing = True
@classmethod @classmethod
def export_surface_attributes(cls) -> dict[str, Any]: def export_surface_attributes(cls) -> dict[str, Any]:
props = bpy.context.scene.BIMStylesProperties props = cls.get_style_props()
return bonsai.bim.helper.export_attributes(props.attributes) return bonsai.bim.helper.export_attributes(props.attributes)
@classmethod @classmethod
def get_active_style_in_ui(cls) -> Union[bpy.types.PropertyGroup, None]: def get_active_style_in_ui(cls) -> Union[bpy.types.PropertyGroup, None]:
props = bpy.context.scene.BIMStylesProperties props = cls.get_style_props()
return props.active_style return props.active_style
@classmethod @classmethod
def get_active_style_type(cls) -> str: def get_active_style_type(cls) -> str:
return bpy.context.scene.BIMStylesProperties.style_type props = cls.get_style_props()
return props.style_type
@classmethod @classmethod
def get_context(cls) -> Union[ifcopenshell.entity_instance, None]: def get_context(cls) -> Union[ifcopenshell.entity_instance, None]:
@@ -136,7 +151,7 @@ class Style(bonsai.core.tool.Style):
@classmethod @classmethod
def get_currently_edited_material(cls) -> bpy.types.Material: def get_currently_edited_material(cls) -> bpy.types.Material:
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
style = tool.Ifc.get().by_id(props.is_editing_style) style = tool.Ifc.get().by_id(props.is_editing_style)
obj = tool.Ifc.get_object(style) obj = tool.Ifc.get_object(style)
assert isinstance(obj, bpy.types.Material) assert isinstance(obj, bpy.types.Material)
@@ -162,7 +177,7 @@ class Style(bonsai.core.tool.Style):
"""returns style data from blender props in similar way to `Loader.surface_style_to_dict` """returns style data from blender props in similar way to `Loader.surface_style_to_dict`
to be compatible with `Loader.create_surface_style_rendering`""" to be compatible with `Loader.create_surface_style_rendering`"""
surface_style_data = dict() surface_style_data = dict()
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
available_props = props.bl_rna.properties.keys() available_props = props.bl_rna.properties.keys()
for prop_blender, prop_ifc in STYLE_PROPS_MAP.items(): for prop_blender, prop_ifc in STYLE_PROPS_MAP.items():
@@ -189,7 +204,7 @@ class Style(bonsai.core.tool.Style):
def get_texture_style_data_from_props(cls) -> list[dict[str, Any]]: def get_texture_style_data_from_props(cls) -> list[dict[str, Any]]:
"""returns style data from blender props in similar way to `Loader.surface_texture_to_dict` """returns style data from blender props in similar way to `Loader.surface_texture_to_dict`
to be compatible with `Loader.create_surface_style_with_textures`""" to be compatible with `Loader.create_surface_style_with_textures`"""
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
textures = [] textures = []
for texture in props.textures: for texture in props.textures:
@@ -210,7 +225,7 @@ class Style(bonsai.core.tool.Style):
"""set blender style props based on currently edited IfcSurfaceStyle, """set blender style props based on currently edited IfcSurfaceStyle,
reset unrelated props to default values""" reset unrelated props to default values"""
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
style = tool.Ifc.get().by_id(props.is_editing_style) style = tool.Ifc.get().by_id(props.is_editing_style)
# make sure won't be updating while we changing it # make sure won't be updating while we changing it
prev_update_graph_value = props.update_graph prev_update_graph_value = props.update_graph
@@ -503,7 +518,7 @@ class Style(bonsai.core.tool.Style):
@classmethod @classmethod
def get_style_ui_props_attributes(cls, style_type: str) -> Union[bpy.types.PropertyGroup, None]: def get_style_ui_props_attributes(cls, style_type: str) -> Union[bpy.types.PropertyGroup, None]:
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
if style_type == "IfcExternallyDefinedSurfaceStyle": if style_type == "IfcExternallyDefinedSurfaceStyle":
return props.external_style_attributes return props.external_style_attributes
elif style_type == "IfcSurfaceStyleRefraction": elif style_type == "IfcSurfaceStyleRefraction":
@@ -514,7 +529,7 @@ class Style(bonsai.core.tool.Style):
@classmethod @classmethod
def import_presentation_styles(cls, style_type: str) -> None: def import_presentation_styles(cls, style_type: str) -> None:
color_to_tuple = lambda x: (x.Red, x.Green, x.Blue) color_to_tuple = lambda x: (x.Red, x.Green, x.Blue)
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
props.styles.clear() props.styles.clear()
styles = sorted(tool.Ifc.get().by_type(style_type), key=lambda x: x.Name or "Unnamed") styles = sorted(tool.Ifc.get().by_type(style_type), key=lambda x: x.Name or "Unnamed")
for style in styles: for style in styles:
@@ -537,7 +552,8 @@ class Style(bonsai.core.tool.Style):
@classmethod @classmethod
def import_surface_attributes(cls, style: ifcopenshell.entity_instance) -> None: def import_surface_attributes(cls, style: ifcopenshell.entity_instance) -> None:
attributes = bpy.context.scene.BIMStylesProperties.attributes props = cls.get_style_props()
attributes = props.attributes
attributes.clear() attributes.clear()
bonsai.bim.helper.import_attributes2(style, attributes) bonsai.bim.helper.import_attributes2(style, attributes)
@@ -548,11 +564,13 @@ class Style(bonsai.core.tool.Style):
@classmethod @classmethod
def is_editing_styles(cls) -> bool: def is_editing_styles(cls) -> bool:
return bpy.context.scene.BIMStylesProperties.is_editing props = cls.get_style_props()
return props.is_editing
@classmethod @classmethod
def is_editing_style(cls) -> bool: def is_editing_style(cls) -> bool:
return bpy.context.scene.BIMStylesProperties.is_editing_style props = cls.get_style_props()
return bool(props.is_editing_style)
@classmethod @classmethod
def select_elements(cls, elements: list[ifcopenshell.entity_instance]) -> None: def select_elements(cls, elements: list[ifcopenshell.entity_instance]) -> None:
@@ -617,7 +635,7 @@ class Style(bonsai.core.tool.Style):
blender_material.BIMStyleProperties.active_style_type = blender_material.BIMStyleProperties.active_style_type blender_material.BIMStyleProperties.active_style_type = blender_material.BIMStyleProperties.active_style_type
@classmethod @classmethod
def switch_shading(cls, blender_material: bpy.types.Material, style_type: STYLE_TYPES) -> None: def switch_shading(cls, blender_material: bpy.types.Material, style_type: StyleType) -> None:
if style_type == "External": if style_type == "External":
try: try:
bpy.ops.bim.activate_external_style(material_name=blender_material.name) bpy.ops.bim.activate_external_style(material_name=blender_material.name)
+4 -3
View File
@@ -484,20 +484,21 @@ class TestApplyIfcMaterialChanges(NewFile):
red_material = ifcopenshell.api.material.add_material(ifc_file, "Red Material") red_material = ifcopenshell.api.material.add_material(ifc_file, "Red Material")
bpy.ops.bim.load_styles(style_type="IfcSurfaceStyle") bpy.ops.bim.load_styles(style_type="IfcSurfaceStyle")
bpy.ops.bim.enable_adding_presentation_style() bpy.ops.bim.enable_adding_presentation_style()
bpy.data.scenes["Scene"].BIMStylesProperties.style_name = "Red" sprops = tool.Style.get_style_props()
sprops.style_name = "Red"
bpy.ops.bim.add_presentation_style() bpy.ops.bim.add_presentation_style()
red_style = next((i for i in ifc_file.by_type("IfcSurfaceStyle") if i.Name == "Red")) red_style = next((i for i in ifc_file.by_type("IfcSurfaceStyle") if i.Name == "Red"))
ifcopenshell.api.style.assign_material_style(ifc_file, red_material, red_style, context) ifcopenshell.api.style.assign_material_style(ifc_file, red_material, red_style, context)
blue_material = ifcopenshell.api.material.add_material(ifc_file, "Blue Material") blue_material = ifcopenshell.api.material.add_material(ifc_file, "Blue Material")
bpy.ops.bim.enable_adding_presentation_style() bpy.ops.bim.enable_adding_presentation_style()
bpy.data.scenes["Scene"].BIMStylesProperties.style_name = "Blue" sprops.style_name = "Blue"
bpy.ops.bim.add_presentation_style() bpy.ops.bim.add_presentation_style()
blue_style = next((i for i in ifc_file.by_type("IfcSurfaceStyle") if i.Name == "Blue")) blue_style = next((i for i in ifc_file.by_type("IfcSurfaceStyle") if i.Name == "Blue"))
ifcopenshell.api.style.assign_material_style(ifc_file, blue_material, blue_style, context) ifcopenshell.api.style.assign_material_style(ifc_file, blue_material, blue_style, context)
bpy.ops.bim.enable_adding_presentation_style() bpy.ops.bim.enable_adding_presentation_style()
bpy.data.scenes["Scene"].BIMStylesProperties.style_name = "Green" sprops.style_name = "Green"
bpy.ops.bim.add_presentation_style() bpy.ops.bim.add_presentation_style()
if and_elements: if and_elements:
+20 -16
View File
@@ -47,7 +47,7 @@ class TestCanSupportRenderingStyle(NewFile):
class TestDisableEditing(NewFile): class TestDisableEditing(NewFile):
def test_run(self): def test_run(self):
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
props.is_editing_style = 1 props.is_editing_style = 1
subject.disable_editing() subject.disable_editing()
assert props.is_editing_style == 0 assert props.is_editing_style == 0
@@ -55,14 +55,15 @@ class TestDisableEditing(NewFile):
class TestDisableEditingStyles(NewFile): class TestDisableEditingStyles(NewFile):
def test_run(self): def test_run(self):
bpy.context.scene.BIMStylesProperties.is_editing = True props = tool.Style.get_style_props()
props.is_editing = True
subject.disable_editing_styles() subject.disable_editing_styles()
assert bpy.context.scene.BIMStylesProperties.is_editing is False assert props.is_editing is False
class TestEnableEditing(NewFile): class TestEnableEditing(NewFile):
def test_run(self): def test_run(self):
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
style = ifcopenshell.file().create_entity("IfcSurfaceStyle") style = ifcopenshell.file().create_entity("IfcSurfaceStyle")
subject.enable_editing(style) subject.enable_editing(style)
assert props.is_editing_style is style.id() assert props.is_editing_style is style.id()
@@ -70,9 +71,10 @@ class TestEnableEditing(NewFile):
class TestEnableEditingStyles(NewFile): class TestEnableEditingStyles(NewFile):
def test_run(self): def test_run(self):
bpy.context.scene.BIMStylesProperties.is_editing = False props = props = tool.Style.get_style_props()
props.is_editing = False
subject.enable_editing_styles() subject.enable_editing_styles()
assert bpy.context.scene.BIMStylesProperties.is_editing is True assert props.is_editing is True
class TestExportSurfaceAttributes(NewFile): class TestExportSurfaceAttributes(NewFile):
@@ -85,9 +87,10 @@ class TestGetActiveStyleType(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
bpy.context.scene.BIMStylesProperties.style_type = "IfcSurfaceStyle" props = tool.Style.get_style_props()
props.style_type = "IfcSurfaceStyle"
assert subject.get_active_style_type() == "IfcSurfaceStyle" assert subject.get_active_style_type() == "IfcSurfaceStyle"
bpy.context.scene.BIMStylesProperties.style_type = "IfcCurveStyle" props.style_type = "IfcCurveStyle"
assert subject.get_active_style_type() == "IfcCurveStyle" assert subject.get_active_style_type() == "IfcCurveStyle"
@@ -378,7 +381,7 @@ class TestGetUVMaps(NewFile):
class TestImportSurfaceAttributes(NewFile): class TestImportSurfaceAttributes(NewFile):
def test_run(self): def test_run(self):
tool.Ifc.set(ifc := ifcopenshell.file()) tool.Ifc.set(ifc := ifcopenshell.file())
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
style = ifc.create_entity("IfcSurfaceStyle", "Name", "BOTH") style = ifc.create_entity("IfcSurfaceStyle", "Name", "BOTH")
subject.import_surface_attributes(style) subject.import_surface_attributes(style)
assert props.attributes.get("Name").string_value == "Name" assert props.attributes.get("Name").string_value == "Name"
@@ -387,7 +390,7 @@ class TestImportSurfaceAttributes(NewFile):
def test_importing_surface_attributes_twice(self): def test_importing_surface_attributes_twice(self):
tool.Ifc.set(ifc := ifcopenshell.file()) tool.Ifc.set(ifc := ifcopenshell.file())
style = ifc.create_entity("IfcSurfaceStyle", "Name", "BOTH") style = ifc.create_entity("IfcSurfaceStyle", "Name", "BOTH")
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
subject.import_surface_attributes(style) subject.import_surface_attributes(style)
assert len(props.attributes) == 2 assert len(props.attributes) == 2
assert props.attributes.get("Name").string_value == "Name" assert props.attributes.get("Name").string_value == "Name"
@@ -404,7 +407,7 @@ class TestImportPresentationStyles(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
style = ifc.createIfcCurveStyle(Name="Name") style = ifc.createIfcCurveStyle(Name="Name")
subject.import_presentation_styles("IfcCurveStyle") subject.import_presentation_styles("IfcCurveStyle")
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
assert props.styles[0].ifc_definition_id == style.id() assert props.styles[0].ifc_definition_id == style.id()
assert props.styles[0].name == "Name" assert props.styles[0].name == "Name"
assert props.styles[0].total_elements == 0 assert props.styles[0].total_elements == 0
@@ -414,7 +417,7 @@ class TestImportPresentationStyles(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
style = ifc.createIfcFillAreaStyle(Name="Name") style = ifc.createIfcFillAreaStyle(Name="Name")
subject.import_presentation_styles("IfcFillAreaStyle") subject.import_presentation_styles("IfcFillAreaStyle")
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
assert props.styles[0].ifc_definition_id == style.id() assert props.styles[0].ifc_definition_id == style.id()
assert props.styles[0].name == "Name" assert props.styles[0].name == "Name"
assert props.styles[0].total_elements == 0 assert props.styles[0].total_elements == 0
@@ -424,7 +427,7 @@ class TestImportPresentationStyles(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
style = ifc.createIfcSurfaceStyle(Name="Name") style = ifc.createIfcSurfaceStyle(Name="Name")
subject.import_presentation_styles("IfcSurfaceStyle") subject.import_presentation_styles("IfcSurfaceStyle")
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
assert props.styles[0].ifc_definition_id == style.id() assert props.styles[0].ifc_definition_id == style.id()
assert props.styles[0].name == "Name" assert props.styles[0].name == "Name"
assert props.styles[0].total_elements == 0 assert props.styles[0].total_elements == 0
@@ -434,7 +437,7 @@ class TestImportPresentationStyles(NewFile):
tool.Ifc.set(ifc) tool.Ifc.set(ifc)
style = ifc.createIfcTextStyle(Name="Name") style = ifc.createIfcTextStyle(Name="Name")
subject.import_presentation_styles("IfcTextStyle") subject.import_presentation_styles("IfcTextStyle")
props = bpy.context.scene.BIMStylesProperties props = tool.Style.get_style_props()
assert props.styles[0].ifc_definition_id == style.id() assert props.styles[0].ifc_definition_id == style.id()
assert props.styles[0].name == "Name" assert props.styles[0].name == "Name"
assert props.styles[0].total_elements == 0 assert props.styles[0].total_elements == 0
@@ -442,9 +445,10 @@ class TestImportPresentationStyles(NewFile):
class TestIsEditingStyles(NewFile): class TestIsEditingStyles(NewFile):
def test_run(self): def test_run(self):
bpy.context.scene.BIMStylesProperties.is_editing = False props = tool.Style.get_style_props()
props.is_editing = False
assert subject.is_editing_styles() is False assert subject.is_editing_styles() is False
bpy.context.scene.BIMStylesProperties.is_editing = True props.is_editing = True
assert subject.is_editing_styles() is True assert subject.is_editing_styles() is True
+2 -2
View File
@@ -133,7 +133,7 @@ def write(output: Union[ifcopenshell.file, str], filepath: str) -> None:
def extract_docs( def extract_docs(
submodule_name: str, cls_name: str, method_name: str = "__init__", boilerplate_args: Optional[Iterable[str]] = None submodule_name: str, cls_name: str, method_name: str = "__init__", boilerplate_args: Optional[Sequence[str]] = None
) -> Union["PatcherDoc", None]: ) -> Union["PatcherDoc", None]:
"""Extract class docstrings and method arguments """Extract class docstrings and method arguments
@@ -173,7 +173,7 @@ class InputDoc(TypedDict):
filter_glob: NotRequired[str] filter_glob: NotRequired[str]
def _extract_docs(cls: type, method_name: str, boilerplate_args: Union[Iterable[str], None]) -> PatcherDoc: def _extract_docs(cls: type, method_name: str, boilerplate_args: Union[Sequence[str], None]) -> PatcherDoc:
inputs: dict[str, InputDoc] = {} inputs: dict[str, InputDoc] = {}
method = getattr(cls, method_name) method = getattr(cls, method_name)
if boilerplate_args is None: if boilerplate_args is None: