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:
shading = area.spaces.active.shading.type
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():
@@ -311,7 +311,9 @@ class CadHotkey(bpy.types.Operator):
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
row = layout.row(align=True)
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:
return
scene = context.scene
if object_type == "PROFILE":
props = tool.Profile.get_profile_props()
if props.is_editing:
bpy.ops.bim.load_profiles()
elif object_type == "STYLE":
if scene.BIMStylesProperties.is_editing:
props = tool.Style.get_style_props()
if props.is_editing:
bpy.ops.bim.load_styles()
elif object_type == "MATERIAL":
props = tool.Material.get_material_props()
@@ -754,13 +754,13 @@ class MergeIdenticalObjects(bpy.types.Operator, tool.Ifc.Operator):
if merged == 0:
return
scene = context.scene
if object_type == "PROFILE":
props = tool.Profile.get_profile_props()
if props.is_editing:
bpy.ops.bim.load_profiles()
elif object_type == "STYLE":
if scene.BIMStylesProperties.is_editing:
props = tool.Style.get_style_props()
if props.is_editing:
bpy.ops.bim.load_styles()
elif object_type == "MATERIAL":
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)
attributes = bonsai.bim.helper.export_attributes(props.material_set_attributes)
ifcopenshell.api.run(
"material.edit_assigned_material",
ifcopenshell.api.material.edit_assigned_material(
self.file,
**{"element": material_set, "attributes": attributes},
element=material_set,
attributes=attributes,
)
if 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)
if material_set_usage.is_a("IfcMaterialLayerSetUsage"):
ifcopenshell.api.run(
"material.edit_layer_usage",
ifcopenshell.api.material.edit_layer_usage(
self.file,
**{"usage": material_set_usage, "attributes": attributes},
usage=material_set_usage,
attributes=attributes,
)
slab.DumbSlabPlaner().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"):
if attributes.get("CardinalPoint", None):
attributes["CardinalPoint"] = int(attributes["CardinalPoint"])
ifcopenshell.api.run(
"material.edit_profile_usage",
ifcopenshell.api.material.edit_profile_usage(
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)
+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.door import update_door_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]]:
@@ -607,7 +607,7 @@ class BIMWindowProperties(PropertyGroup):
framing_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 = {
"window_type": self.window_type,
"overall_height": self.overall_height,
@@ -617,7 +617,9 @@ class BIMWindowProperties(PropertyGroup):
return kwargs
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:
window_type = self.window_type
kwargs = {
@@ -660,7 +662,7 @@ class BIMWindowProperties(PropertyGroup):
return 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 = {
"frame_depth": self.frame_depth,
"frame_thickness": self.frame_thickness,
@@ -669,7 +671,7 @@ class BIMWindowProperties(PropertyGroup):
return 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)
for prop_name in kwargs:
setattr(self, prop_name, kwargs[prop_name])
@@ -28,6 +28,7 @@ import bonsai.core.root
import bonsai.core.geometry
from ifcopenshell.api.geometry.add_window_representation import DEFAULT_PANEL_SCHEMAS
import ifcopenshell.api
import ifcopenshell.api.material
import ifcopenshell.util.element
import ifcopenshell.util.representation
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 typing import Union, TYPE_CHECKING, Literal, get_args
if TYPE_CHECKING:
from bonsai.bim.module.project.prop import Link
class NewProject(bpy.types.Operator):
bl_idname = "bim.new_project"
@@ -1484,7 +1487,7 @@ class ToggleLinkVisibility(bpy.types.Operator):
self.toggle_visibility(link)
return {"FINISHED"}
def toggle_wireframe(self, link):
def toggle_wireframe(self, link: "Link") -> None:
for collection in self.get_linked_collections():
objs = filter(lambda obj: "IfcOpeningElement" not in obj.name, collection.all_objects)
for i, obj in enumerate(objs):
@@ -1496,7 +1499,7 @@ class ToggleLinkVisibility(bpy.types.Operator):
obj.display_type = display_type
link.is_wireframe = display_type == "WIRE"
def toggle_visibility(self, link):
def toggle_visibility(self, link: "Link") -> None:
linked_collections = self.get_linked_collections()
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
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"}
updated_materials = set()
@@ -258,8 +259,9 @@ class SetAssetMaterialToExternalStyle(bpy.types.Operator):
# the temp override to copy material node tree `right now`
name = context.asset.name
filepath = context.asset.full_library_path
props = tool.Style.get_style_props()
bpy.app.timers.register(
lambda: self.execute_delayed(name, filepath, context.scene.BIMStylesProperties),
lambda: self.execute_delayed(name, filepath, props),
first_interval=0.001,
)
return {"FINISHED"}
@@ -388,7 +390,8 @@ class BrowseExternalStyle(bpy.types.Operator):
bpy.data.materials.remove(db["data_block"])
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["Identification"].string_value = f"{self.data_block_type}/{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.")
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":
location = props.external_style_attributes["Location"].string_value
identification = props.external_style_attributes["Identification"].string_value
@@ -509,7 +512,8 @@ class LoadStyles(bpy.types.Operator):
style_type: bpy.props.StringProperty()
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)
bonsai.bim.handler.refresh_ui_data()
return {"FINISHED"}
@@ -561,7 +565,8 @@ class ChooseTextureMapPath(bpy.types.Operator):
return {"CANCELLED"}
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
return {"FINISHED"}
@@ -577,7 +582,7 @@ class RemoveTextureMap(bpy.types.Operator):
self.report({"ERROR"}, "Provide a texture map index")
return {"CANCELLED"}
props = context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
props.textures.remove(self.texture_map_index)
# just to trigger shader graph update
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")
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()
style = ifc_file.by_id(self.style)
tool.Style.duplicate_style(style)
@@ -636,7 +642,7 @@ class AddPresentationStyle(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
if props.style_type == "IfcSurfaceStyle":
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="")
def execute(self, context):
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
style = tool.Ifc.get().by_id(self.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]
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)
style_elements = tool.Style.get_style_elements(self.style)
@@ -950,13 +956,14 @@ class AddSurfaceTexture(bpy.types.Operator):
@classmethod
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")
return False
return True
def execute(self, context):
props = context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
props.textures.add()
return {"FINISHED"}
@@ -1183,7 +1190,7 @@ class SelectStyleInStylesUI(bpy.types.Operator):
style_id: bpy.props.IntProperty()
def execute(self, context):
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
ifc_file = tool.Ifc.get()
style = ifc_file.by_id(self.style_id)
core.load_styles(tool.Style, style.is_a())
@@ -1204,7 +1211,7 @@ class RemoveSurfaceStyle(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context):
ifc_file = tool.Ifc.get()
props = context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
style = ifc_file.by_id(props.is_editing_style)
surface_style = tool.Style.get_style_elements(style)[props.is_editing_class]
ifcopenshell.api.style.remove_surface_style(ifc_file, surface_style)
+60 -16
View File
@@ -33,7 +33,7 @@ from bpy.props import (
)
import gettext
from typing import Literal, Union
from typing import Literal, Union, TYPE_CHECKING, get_args
_ = gettext.gettext
@@ -154,6 +154,17 @@ class ColourRgb(PropertyGroup):
return "color_value"
SurfaceStyleClass = Literal[
"IfcSurfaceStyleShading",
"IfcSurfaceStyleRendering",
"IfcSurfaceStyleWithTextures",
"IfcSurfaceStyleLighting",
"IfcSurfaceStyleRefraction",
"IfcExternallyDefinedSurfaceStyle",
]
ColourClass = Literal["IfcColourRgb", "IfcNormalisedRatioMeasure"]
class BIMStylesProperties(PropertyGroup):
is_adding: BoolProperty(name="Is Adding", description="Is adding new 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_name: StringProperty(name="Style Name")
surface_style_class: EnumProperty(
items=[
(x, x, "")
for x in (
"IfcSurfaceStyleShading",
"IfcSurfaceStyleRendering",
"IfcSurfaceStyleWithTextures",
"IfcSurfaceStyleLighting",
"IfcSurfaceStyleRefraction",
"IfcExternallyDefinedSurfaceStyle",
)
],
items=[(x, x, "") for x in get_args(SurfaceStyleClass)],
name="Surface Style Class",
default="IfcSurfaceStyleShading",
)
@@ -200,7 +201,7 @@ class BIMStylesProperties(PropertyGroup):
# TODO: do something on null?
is_diffuse_colour_null: BoolProperty(name="Is Null")
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",
update=update_shader_graph,
)
@@ -212,7 +213,7 @@ class BIMStylesProperties(PropertyGroup):
)
is_specular_colour_null: BoolProperty(name="Is Null")
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",
update=update_shader_graph,
default="IfcNormalisedRatioMeasure",
@@ -269,11 +270,49 @@ class BIMStylesProperties(PropertyGroup):
active_style_type: EnumProperty(
name="Active Style Type",
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",
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:
blender_material = self.id_data
@@ -290,8 +329,13 @@ class BIMStyleProperties(PropertyGroup):
active_style_type: EnumProperty(
name="Active 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",
update=update_shading_style,
)
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:
StylesData.load()
self.props = context.scene.BIMStylesProperties
self.props = tool.Style.get_style_props()
if not self.props.is_editing:
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):
if item:
row = layout.row(align=True)
props = context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
if item.ifc_definition_id == props.is_editing_style:
row.label(text="", icon="GREASEPENCIL")
row.prop(item, "name", text="", emboss=False)
@@ -330,6 +330,6 @@ def draw_asset_browser_context_menu_append(self, context):
asset = context.asset
if not asset or not asset.id_type == "MATERIAL":
return
if not context.scene.BIMStylesProperties.is_editing:
if not tool.Style.get_style_props().is_editing:
return
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.opening import FilledOpeningGenerator
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")
V_ = tool.Blender.V_
@@ -108,7 +108,7 @@ class Model(bonsai.core.tool.Model):
return value * cls.unit_scale
@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())
for prop_name in data:
if prop_name in non_si_props:
@@ -121,7 +121,7 @@ class Model(bonsai.core.tool.Model):
return data
@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())
for prop_name in data:
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
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy
import numpy as np
import ifcopenshell
import ifcopenshell.api.style
import ifcopenshell.util.element
import ifcopenshell.util.representation
import bonsai.core.style
@@ -26,7 +28,10 @@ import bonsai.core.tool
import bonsai.tool as tool
import bonsai.bim.helper
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
TEXTURE_MAPS_BY_METHODS = {
@@ -44,10 +49,18 @@ STYLE_PROPS_MAP = {
"specular_colour": "SpecularColour",
}
STYLE_TYPES = Literal["Shading", "External"]
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
def can_support_rendering_style(cls, obj: bpy.types.Material) -> bool:
return obj.use_nodes and hasattr(obj.node_tree, "nodes")
@@ -58,19 +71,19 @@ class Style(bonsai.core.tool.Style):
@classmethod
def enable_adding_presentation_style(cls) -> None:
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
props.is_adding = True
props.update_graph = False
@classmethod
def disable_adding_presentation_style(cls) -> None:
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
props.is_adding = False
props.update_graph = True
@classmethod
def disable_editing(cls) -> None:
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
props.is_editing_style = 0
props.is_editing_class = ""
props.attributes.clear()
@@ -81,7 +94,7 @@ class Style(bonsai.core.tool.Style):
@classmethod
def disable_editing_styles(cls) -> None:
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
props.is_editing = False
props.styles.clear()
@@ -100,27 +113,29 @@ class Style(bonsai.core.tool.Style):
@classmethod
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_class = "IfcSurfaceStyle"
@classmethod
def enable_editing_styles(cls) -> None:
bpy.context.scene.BIMStylesProperties.is_editing = True
props = cls.get_style_props()
props.is_editing = True
@classmethod
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)
@classmethod
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
@classmethod
def get_active_style_type(cls) -> str:
return bpy.context.scene.BIMStylesProperties.style_type
props = cls.get_style_props()
return props.style_type
@classmethod
def get_context(cls) -> Union[ifcopenshell.entity_instance, None]:
@@ -136,7 +151,7 @@ class Style(bonsai.core.tool.Style):
@classmethod
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)
obj = tool.Ifc.get_object(style)
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`
to be compatible with `Loader.create_surface_style_rendering`"""
surface_style_data = dict()
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
available_props = props.bl_rna.properties.keys()
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]]:
"""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`"""
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_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,
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)
# make sure won't be updating while we changing it
prev_update_graph_value = props.update_graph
@@ -503,7 +518,7 @@ class Style(bonsai.core.tool.Style):
@classmethod
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":
return props.external_style_attributes
elif style_type == "IfcSurfaceStyleRefraction":
@@ -514,7 +529,7 @@ class Style(bonsai.core.tool.Style):
@classmethod
def import_presentation_styles(cls, style_type: str) -> None:
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()
styles = sorted(tool.Ifc.get().by_type(style_type), key=lambda x: x.Name or "Unnamed")
for style in styles:
@@ -537,7 +552,8 @@ class Style(bonsai.core.tool.Style):
@classmethod
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()
bonsai.bim.helper.import_attributes2(style, attributes)
@@ -548,11 +564,13 @@ class Style(bonsai.core.tool.Style):
@classmethod
def is_editing_styles(cls) -> bool:
return bpy.context.scene.BIMStylesProperties.is_editing
props = cls.get_style_props()
return props.is_editing
@classmethod
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
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
@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":
try:
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")
bpy.ops.bim.load_styles(style_type="IfcSurfaceStyle")
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()
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)
blue_material = ifcopenshell.api.material.add_material(ifc_file, "Blue Material")
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()
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)
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()
if and_elements:
+20 -16
View File
@@ -47,7 +47,7 @@ class TestCanSupportRenderingStyle(NewFile):
class TestDisableEditing(NewFile):
def test_run(self):
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
props.is_editing_style = 1
subject.disable_editing()
assert props.is_editing_style == 0
@@ -55,14 +55,15 @@ class TestDisableEditing(NewFile):
class TestDisableEditingStyles(NewFile):
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()
assert bpy.context.scene.BIMStylesProperties.is_editing is False
assert props.is_editing is False
class TestEnableEditing(NewFile):
def test_run(self):
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
style = ifcopenshell.file().create_entity("IfcSurfaceStyle")
subject.enable_editing(style)
assert props.is_editing_style is style.id()
@@ -70,9 +71,10 @@ class TestEnableEditing(NewFile):
class TestEnableEditingStyles(NewFile):
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()
assert bpy.context.scene.BIMStylesProperties.is_editing is True
assert props.is_editing is True
class TestExportSurfaceAttributes(NewFile):
@@ -85,9 +87,10 @@ class TestGetActiveStyleType(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
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"
bpy.context.scene.BIMStylesProperties.style_type = "IfcCurveStyle"
props.style_type = "IfcCurveStyle"
assert subject.get_active_style_type() == "IfcCurveStyle"
@@ -378,7 +381,7 @@ class TestGetUVMaps(NewFile):
class TestImportSurfaceAttributes(NewFile):
def test_run(self):
tool.Ifc.set(ifc := ifcopenshell.file())
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
style = ifc.create_entity("IfcSurfaceStyle", "Name", "BOTH")
subject.import_surface_attributes(style)
assert props.attributes.get("Name").string_value == "Name"
@@ -387,7 +390,7 @@ class TestImportSurfaceAttributes(NewFile):
def test_importing_surface_attributes_twice(self):
tool.Ifc.set(ifc := ifcopenshell.file())
style = ifc.create_entity("IfcSurfaceStyle", "Name", "BOTH")
props = bpy.context.scene.BIMStylesProperties
props = tool.Style.get_style_props()
subject.import_surface_attributes(style)
assert len(props.attributes) == 2
assert props.attributes.get("Name").string_value == "Name"
@@ -404,7 +407,7 @@ class TestImportPresentationStyles(NewFile):
tool.Ifc.set(ifc)
style = ifc.createIfcCurveStyle(Name="Name")
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].name == "Name"
assert props.styles[0].total_elements == 0
@@ -414,7 +417,7 @@ class TestImportPresentationStyles(NewFile):
tool.Ifc.set(ifc)
style = ifc.createIfcFillAreaStyle(Name="Name")
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].name == "Name"
assert props.styles[0].total_elements == 0
@@ -424,7 +427,7 @@ class TestImportPresentationStyles(NewFile):
tool.Ifc.set(ifc)
style = ifc.createIfcSurfaceStyle(Name="Name")
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].name == "Name"
assert props.styles[0].total_elements == 0
@@ -434,7 +437,7 @@ class TestImportPresentationStyles(NewFile):
tool.Ifc.set(ifc)
style = ifc.createIfcTextStyle(Name="Name")
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].name == "Name"
assert props.styles[0].total_elements == 0
@@ -442,9 +445,10 @@ class TestImportPresentationStyles(NewFile):
class TestIsEditingStyles(NewFile):
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
bpy.context.scene.BIMStylesProperties.is_editing = True
props.is_editing = True
assert subject.is_editing_styles() is True