mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
bim.save_uv_to_style - support saving uv to objects without a style
There was a problem with assigning uv workflow if object wasn't originally from IFC - saving uv requires object to have IfcSurfaceStyle but assigning IfcSurfaceStyle would reload representation discarding UV. So, the current workflow for saving non-ifc objects uv to ifc: 1) Assign class to ifc object 2) Create IfcSurfaceStyle with a texture (currently also requires a rendering style) 3) Use "Save UV To Style" Example - https://imgur.com/a/GZqo38M
This commit is contained in:
@@ -882,7 +882,11 @@ class AddSurfaceTexture(bpy.types.Operator):
|
||||
class SaveUVToStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.save_uv_to_style"
|
||||
bl_label = "Save UV To Style"
|
||||
bl_description = "Save active object UV to it's IfcSurfaceStyle's IfcSurfaceTexture"
|
||||
bl_description = (
|
||||
"Save active object UV to the IfcSurfaceStyle's IfcSurfaceTexture.\n\n"
|
||||
"If object already has IfcSurfaceStyleWithTextures, then it will be used.\n"
|
||||
"Otherwise operator will use currently selected surface style (style will be autoassigned)"
|
||||
)
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
@@ -890,9 +894,6 @@ class SaveUVToStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
if not (obj := context.active_object) or not tool.Ifc.get_entity(obj):
|
||||
cls.poll_message_set("No IFC object selected")
|
||||
return False
|
||||
if not obj.active_material or not tool.Ifc.get_entity(obj.active_material):
|
||||
cls.poll_message_set("Object has no IFC style.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def _execute(self, context):
|
||||
@@ -903,12 +904,25 @@ class SaveUVToStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
# We need IFC material with a texture style since in IFC
|
||||
# UV indexing (IfcTextureCoordinate) requires some IfcSurfaceTexture.
|
||||
material, style = None, None
|
||||
style_is_assigned = False
|
||||
material = obj.active_material
|
||||
assert material
|
||||
if material:
|
||||
style = tool.Ifc.get_entity(material)
|
||||
|
||||
# find active style item
|
||||
style = tool.Ifc.get_entity(material)
|
||||
assert style
|
||||
if style:
|
||||
style_is_assigned = True
|
||||
else:
|
||||
style_item = tool.Style.get_active_style_in_ui()
|
||||
if not style_item:
|
||||
self.report({"ERROR"}, "Object has no style and no style is selected.")
|
||||
return {"CANCELLED"}
|
||||
style = ifc_file.by_id(style_item.ifc_definition_id)
|
||||
|
||||
texture_style = tool.Style.get_texture_style(style)
|
||||
if not texture_style:
|
||||
self.report({"ERROR"}, "IfcSurfaceStyle has no texture style.")
|
||||
return {"CANCELLED"}
|
||||
|
||||
def get_active_representation_items() -> list[ifcopenshell.entity_instance]:
|
||||
representation = tool.Geometry.get_active_representation(obj)
|
||||
@@ -923,7 +937,7 @@ class SaveUVToStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
all_styled_items = set(tool.Style.get_styled_items(style))
|
||||
active_representation_items = set(get_active_representation_items())
|
||||
|
||||
if not active_representation_items.issubset(all_styled_items):
|
||||
if style_is_assigned and not active_representation_items.issubset(all_styled_items):
|
||||
self.report(
|
||||
{"ERROR"},
|
||||
"Not all items of the current representation are styled by the active style, not yet supported",
|
||||
@@ -943,11 +957,6 @@ class SaveUVToStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
self.report({"ERROR"}, "Only 1 faceset item is supported.")
|
||||
return {"CANCELLED"}
|
||||
|
||||
texture_style = tool.Style.get_texture_style(material)
|
||||
if not texture_style:
|
||||
self.report({"ERROR"}, "No texture style found, not yet supported.")
|
||||
return {"CANCELLED"}
|
||||
|
||||
mesh = obj.data
|
||||
assert isinstance(mesh, bpy.types.Mesh)
|
||||
uv_layer = mesh.uv_layers.active
|
||||
@@ -1016,6 +1025,10 @@ class SaveUVToStyle(bpy.types.Operator, tool.Ifc.Operator):
|
||||
uv_verts_list.TexCoordsList = uv_verts
|
||||
texture_coord.TexCoords = uv_verts_list
|
||||
|
||||
if not style_is_assigned:
|
||||
with context.temp_override(selected_objects=[obj]):
|
||||
bpy.ops.bim.assign_style_to_selected(style_id=style.id())
|
||||
|
||||
self.report({"INFO"}, f"UV saved to the style '{style.Name}'.")
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -103,6 +103,13 @@ class Style(bonsai.core.tool.Style):
|
||||
props = bpy.context.scene.BIMStylesProperties
|
||||
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
|
||||
if len(props.styles) > props.active_style_index >= 0:
|
||||
return props.styles[props.active_style_index]
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_active_style_type(cls) -> str:
|
||||
return bpy.context.scene.BIMStylesProperties.style_type
|
||||
@@ -432,22 +439,30 @@ class Style(bonsai.core.tool.Style):
|
||||
return attributes
|
||||
|
||||
@classmethod
|
||||
def get_surface_rendering_style(cls, obj: bpy.types.Material) -> Union[ifcopenshell.entity_instance, None]:
|
||||
style_elements = cls.get_style_elements(obj)
|
||||
def get_surface_rendering_style(
|
||||
cls, blender_material_or_style: Union[bpy.types.Material, ifcopenshell.entity_instance]
|
||||
) -> Union[ifcopenshell.entity_instance, None]:
|
||||
style_elements = cls.get_style_elements(blender_material_or_style)
|
||||
return style_elements.get("IfcSurfaceStyleRendering", None)
|
||||
|
||||
@classmethod
|
||||
def get_texture_style(cls, obj: bpy.types.Material) -> Union[ifcopenshell.entity_instance, None]:
|
||||
style_elements = cls.get_style_elements(obj)
|
||||
def get_texture_style(
|
||||
cls, blender_material_or_style: Union[bpy.types.Material, ifcopenshell.entity_instance]
|
||||
) -> Union[ifcopenshell.entity_instance, None]:
|
||||
style_elements = cls.get_style_elements(blender_material_or_style)
|
||||
return style_elements.get("IfcSurfaceStyleWithTextures", None)
|
||||
|
||||
@classmethod
|
||||
def get_external_style(cls, obj: bpy.types.Material) -> Union[ifcopenshell.entity_instance, None]:
|
||||
style_elements = cls.get_style_elements(obj)
|
||||
def get_external_style(
|
||||
cls, blender_material_or_style: Union[bpy.types.Material, ifcopenshell.entity_instance]
|
||||
) -> Union[ifcopenshell.entity_instance, None]:
|
||||
style_elements = cls.get_style_elements(blender_material_or_style)
|
||||
return style_elements.get("IfcExternallyDefinedSurfaceStyle", None)
|
||||
|
||||
@classmethod
|
||||
def get_surface_shading_attributes(cls, obj: bpy.types.Material) -> dict[str, Any]:
|
||||
def get_surface_shading_attributes(
|
||||
cls, blender_material_or_style: Union[bpy.types.Material, ifcopenshell.entity_instance]
|
||||
) -> dict[str, Any]:
|
||||
data = {
|
||||
"SurfaceColour": {
|
||||
"Name": None,
|
||||
|
||||
Reference in New Issue
Block a user