mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 13:46:54 +00:00
typing
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user