From 1357b83d992f6b25ad960a78a48a5bbf1965e9c0 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Fri, 30 Jun 2023 14:42:43 +0500 Subject: [PATCH] Added support for OCCLUSION textures for 3aff29dec --- .../blenderbim/bim/module/style/prop.py | 8 ++++ .../blenderbim/bim/module/style/ui.py | 17 ++++---- src/blenderbim/blenderbim/tool/loader.py | 40 ++++++++++++++++--- src/blenderbim/blenderbim/tool/style.py | 5 ++- .../api/style/add_surface_textures.py | 8 +++- 5 files changed, 59 insertions(+), 19 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/style/prop.py b/src/blenderbim/blenderbim/bim/module/style/prop.py index f2faba9dc2..111b36a5fd 100644 --- a/src/blenderbim/blenderbim/bim/module/style/prop.py +++ b/src/blenderbim/blenderbim/bim/module/style/prop.py @@ -215,3 +215,11 @@ class BIMStyleProperties(PropertyGroup): subtype="FILE_PATH", update=update_shader_graph, ) + occlusion_path: bpy.props.StringProperty( + name="Occlusion", + description="Note that occlusion isn't actually used in Blender shader, we're just storing the data", + maxlen=1024, + default="", + subtype="FILE_PATH", + update=update_shader_graph, + ) diff --git a/src/blenderbim/blenderbim/bim/module/style/ui.py b/src/blenderbim/blenderbim/bim/module/style/ui.py index 54a0837921..8d362bbb09 100644 --- a/src/blenderbim/blenderbim/bim/module/style/ui.py +++ b/src/blenderbim/blenderbim/bim/module/style/ui.py @@ -21,6 +21,7 @@ from bpy.types import Panel, UIList from blenderbim.bim.ifc import IfcStore from blenderbim.bim.module.style.data import StylesData, StyleAttributesData from bl_ui.properties_material import MaterialButtonsPanel +from blenderbim.tool.style import TEXTURE_MAPS_BY_METHODS, STYLE_TEXTURE_PROPS_MAP class BIM_PT_styles(Panel): @@ -266,19 +267,15 @@ class BIM_PT_STYLE_GRAPH(Panel): ): layout.prop(props, "roughness") - layout.label(text="Texture Maps:") - def add_texture_path(path_name): row = layout.row(align=True) row.prop(props, path_name) op = row.operator("bim.clear_texture_map_path", text="", icon="X") op.texture_map_prop = path_name - if props.reflectance_method == "PHYSICAL": - add_texture_path("diffuse_path") - add_texture_path("emissive_path") - add_texture_path("normal_path") - add_texture_path("metallic_roughness_path") - - if props.reflectance_method == "FLAT": - add_texture_path("emissive_path") + texture_maps = TEXTURE_MAPS_BY_METHODS.get(props.reflectance_method, []) + if not texture_maps: + return + layout.label(text="Texture Maps:") + for texture_type in texture_maps: + add_texture_path(STYLE_TEXTURE_PROPS_MAP[texture_type]) diff --git a/src/blenderbim/blenderbim/tool/loader.py b/src/blenderbim/blenderbim/tool/loader.py index c5a810574b..0020cf39f8 100644 --- a/src/blenderbim/blenderbim/tool/loader.py +++ b/src/blenderbim/blenderbim/tool/loader.py @@ -91,19 +91,25 @@ class Loader(blenderbim.core.tool.Loader): if surface_style.get("DiffuseColour", None) and surface_style["DiffuseColour"].is_a("IfcColourRgb"): surface_style["DiffuseColour"] = ("IfcColourRgb", color_to_tuple(surface_style["DiffuseColour"])) - elif surface_style.get("DiffuseColour", None) and surface_style["DiffuseColour"].is_a("IfcNormalisedRatioMeasure"): + elif surface_style.get("DiffuseColour", None) and surface_style["DiffuseColour"].is_a( + "IfcNormalisedRatioMeasure" + ): diffuse_color_value = surface_style["DiffuseColour"].wrappedValue diffuse_color = [v * diffuse_color_value for v in surface_style["SurfaceColor"][:3]] + [1] surface_style["DiffuseColour"] = ("IfcNormalisedRatioMeasure", diffuse_color) else: surface_style["DiffuseColour"] = None - if surface_style.get("SpecularColour", None) and surface_style["SpecularColour"].is_a("IfcNormalisedRatioMeasure"): + if surface_style.get("SpecularColour", None) and surface_style["SpecularColour"].is_a( + "IfcNormalisedRatioMeasure" + ): surface_style["SpecularColour"] = surface_style["SpecularColour"].wrappedValue else: surface_style["SpecularColour"] = None - if surface_style.get("SpecularHighlight", None) and surface_style["SpecularHighlight"].is_a("IfcSpecularRoughness"): + if surface_style.get("SpecularHighlight", None) and surface_style["SpecularHighlight"].is_a( + "IfcSpecularRoughness" + ): surface_style["SpecularHighlight"] = surface_style["SpecularHighlight"].wrappedValue else: surface_style["SpecularHighlight"] = None @@ -246,9 +252,30 @@ class Loader(blenderbim.core.tool.Loader): blender_material.node_tree.links.new(node.outputs[0], separate.inputs[0]) elif mode == "OCCLUSION": - # TODO work out how to implement glTF settings here - # https://docs.blender.org/manual/en/dev/addons/import_export/scene_gltf2.html - pass + + def get_gltf_occlusion_output(): + gltf_node_group_name = "glTF Material Output" + if node_group := bpy.data.node_groups.get(gltf_node_group_name, None): + return node_group + + gltf_node_group = bpy.data.node_groups.new(gltf_node_group_name, "ShaderNodeTree") + gltf_node_group.inputs.new("NodeSocketFloat", "Occlusion") + gltf_node_group.nodes.new("NodeGroupOutput") + gltf_node_group_input = gltf_node_group.nodes.new("NodeGroupInput") + gltf_node_group_input.location = Vector((-200, 0)) + return gltf_node_group + + gltf_output_node_group = get_gltf_occlusion_output() + group = blender_material.node_tree.nodes.new(type="ShaderNodeGroup") + group.node_tree = gltf_output_node_group + group.location = bsdf.location + Vector((800, 0)) + + node = blender_material.node_tree.nodes.new(type="ShaderNodeTexImage") + node.location = group.location - Vector((300, 0)) + image = bpy.data.images.load(image_url) + image.colorspace_settings.name = "Non-Color" + node.image = image + blender_material.node_tree.links.new(node.outputs[0], group.inputs["Occlusion"]) elif mode == "DIFFUSE": node = blender_material.node_tree.nodes.new(type="ShaderNodeTexImage") @@ -273,6 +300,7 @@ class Loader(blenderbim.core.tool.Loader): image = bpy.data.images.load(image_url) # TODO: orphaned textures after shader recreated? node.image = image + blender_material.node_tree.links.new(node.outputs[0], bsdf.inputs[2]) # TODO: add support for texture data not ifc elements diff --git a/src/blenderbim/blenderbim/tool/style.py b/src/blenderbim/blenderbim/tool/style.py index 33e4174148..980269b729 100644 --- a/src/blenderbim/blenderbim/tool/style.py +++ b/src/blenderbim/blenderbim/tool/style.py @@ -26,7 +26,7 @@ import os.path # fmt: off TEXTURE_MAPS_BY_METHODS = { - "PHYSICAL": ("NORMAL", "EMISSIVE", "METALLICROUGHNESS", "DIFFUSE"), + "PHYSICAL": ("NORMAL", "EMISSIVE", "METALLICROUGHNESS", "DIFFUSE", "OCCLUSION"), "FLAT": ("EMISSIVE",) } # fmt: on @@ -45,6 +45,7 @@ STYLE_TEXTURE_PROPS_MAP = { "NORMAL": "normal_path", "METALLICROUGHNESS": "metallic_roughness_path", "DIFFUSE": "diffuse_path", + "OCCLUSION": "occlusion_path", } @@ -371,7 +372,7 @@ class Style(blenderbim.core.tool.Style): def get_texture_style(cls, obj): style_elements = cls.get_style_elements(obj) return style_elements.get("IfcSurfaceStyleWithTextures", None) - + @classmethod def get_external_style(cls, obj): style_elements = cls.get_style_elements(obj) diff --git a/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py b/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py index 21a45fa29f..3218b9e54b 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py +++ b/src/ifcopenshell-python/ifcopenshell/api/style/add_surface_textures.py @@ -108,7 +108,13 @@ class Usecase: def detect_occlusion_map(self): for node in self.settings["material"].node_tree.nodes: - if node.type != "GROUP" or node.name != "glTF Settings" or not node.inputs or not node.inputs[0].links: + if ( + node.type != "GROUP" + or not node.node_tree + or node.node_tree.name != "glTF Material Output" + or not node.inputs + or not node.inputs[0].links + ): continue from_node = node.inputs[0].links[0].from_node if from_node.type == "SEPRGB":