mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 14:07:43 +00:00
Added support for OCCLUSION textures for 3aff29dec
This commit is contained in:
@@ -215,3 +215,11 @@ class BIMStyleProperties(PropertyGroup):
|
|||||||
subtype="FILE_PATH",
|
subtype="FILE_PATH",
|
||||||
update=update_shader_graph,
|
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,
|
||||||
|
)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ from bpy.types import Panel, UIList
|
|||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from blenderbim.bim.module.style.data import StylesData, StyleAttributesData
|
from blenderbim.bim.module.style.data import StylesData, StyleAttributesData
|
||||||
from bl_ui.properties_material import MaterialButtonsPanel
|
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):
|
class BIM_PT_styles(Panel):
|
||||||
@@ -266,19 +267,15 @@ class BIM_PT_STYLE_GRAPH(Panel):
|
|||||||
):
|
):
|
||||||
layout.prop(props, "roughness")
|
layout.prop(props, "roughness")
|
||||||
|
|
||||||
layout.label(text="Texture Maps:")
|
|
||||||
|
|
||||||
def add_texture_path(path_name):
|
def add_texture_path(path_name):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(props, path_name)
|
row.prop(props, path_name)
|
||||||
op = row.operator("bim.clear_texture_map_path", text="", icon="X")
|
op = row.operator("bim.clear_texture_map_path", text="", icon="X")
|
||||||
op.texture_map_prop = path_name
|
op.texture_map_prop = path_name
|
||||||
|
|
||||||
if props.reflectance_method == "PHYSICAL":
|
texture_maps = TEXTURE_MAPS_BY_METHODS.get(props.reflectance_method, [])
|
||||||
add_texture_path("diffuse_path")
|
if not texture_maps:
|
||||||
add_texture_path("emissive_path")
|
return
|
||||||
add_texture_path("normal_path")
|
layout.label(text="Texture Maps:")
|
||||||
add_texture_path("metallic_roughness_path")
|
for texture_type in texture_maps:
|
||||||
|
add_texture_path(STYLE_TEXTURE_PROPS_MAP[texture_type])
|
||||||
if props.reflectance_method == "FLAT":
|
|
||||||
add_texture_path("emissive_path")
|
|
||||||
|
|||||||
@@ -91,19 +91,25 @@ class Loader(blenderbim.core.tool.Loader):
|
|||||||
if surface_style.get("DiffuseColour", None) and surface_style["DiffuseColour"].is_a("IfcColourRgb"):
|
if surface_style.get("DiffuseColour", None) and surface_style["DiffuseColour"].is_a("IfcColourRgb"):
|
||||||
surface_style["DiffuseColour"] = ("IfcColourRgb", color_to_tuple(surface_style["DiffuseColour"]))
|
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_value = surface_style["DiffuseColour"].wrappedValue
|
||||||
diffuse_color = [v * diffuse_color_value for v in surface_style["SurfaceColor"][:3]] + [1]
|
diffuse_color = [v * diffuse_color_value for v in surface_style["SurfaceColor"][:3]] + [1]
|
||||||
surface_style["DiffuseColour"] = ("IfcNormalisedRatioMeasure", diffuse_color)
|
surface_style["DiffuseColour"] = ("IfcNormalisedRatioMeasure", diffuse_color)
|
||||||
else:
|
else:
|
||||||
surface_style["DiffuseColour"] = None
|
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
|
surface_style["SpecularColour"] = surface_style["SpecularColour"].wrappedValue
|
||||||
else:
|
else:
|
||||||
surface_style["SpecularColour"] = None
|
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
|
surface_style["SpecularHighlight"] = surface_style["SpecularHighlight"].wrappedValue
|
||||||
else:
|
else:
|
||||||
surface_style["SpecularHighlight"] = None
|
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])
|
blender_material.node_tree.links.new(node.outputs[0], separate.inputs[0])
|
||||||
|
|
||||||
elif mode == "OCCLUSION":
|
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
|
def get_gltf_occlusion_output():
|
||||||
pass
|
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":
|
elif mode == "DIFFUSE":
|
||||||
node = blender_material.node_tree.nodes.new(type="ShaderNodeTexImage")
|
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)
|
image = bpy.data.images.load(image_url)
|
||||||
# TODO: orphaned textures after shader recreated?
|
# TODO: orphaned textures after shader recreated?
|
||||||
node.image = image
|
node.image = image
|
||||||
|
|
||||||
blender_material.node_tree.links.new(node.outputs[0], bsdf.inputs[2])
|
blender_material.node_tree.links.new(node.outputs[0], bsdf.inputs[2])
|
||||||
|
|
||||||
# TODO: add support for texture data not ifc elements
|
# TODO: add support for texture data not ifc elements
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import os.path
|
|||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
TEXTURE_MAPS_BY_METHODS = {
|
TEXTURE_MAPS_BY_METHODS = {
|
||||||
"PHYSICAL": ("NORMAL", "EMISSIVE", "METALLICROUGHNESS", "DIFFUSE"),
|
"PHYSICAL": ("NORMAL", "EMISSIVE", "METALLICROUGHNESS", "DIFFUSE", "OCCLUSION"),
|
||||||
"FLAT": ("EMISSIVE",)
|
"FLAT": ("EMISSIVE",)
|
||||||
}
|
}
|
||||||
# fmt: on
|
# fmt: on
|
||||||
@@ -45,6 +45,7 @@ STYLE_TEXTURE_PROPS_MAP = {
|
|||||||
"NORMAL": "normal_path",
|
"NORMAL": "normal_path",
|
||||||
"METALLICROUGHNESS": "metallic_roughness_path",
|
"METALLICROUGHNESS": "metallic_roughness_path",
|
||||||
"DIFFUSE": "diffuse_path",
|
"DIFFUSE": "diffuse_path",
|
||||||
|
"OCCLUSION": "occlusion_path",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -371,7 +372,7 @@ class Style(blenderbim.core.tool.Style):
|
|||||||
def get_texture_style(cls, obj):
|
def get_texture_style(cls, obj):
|
||||||
style_elements = cls.get_style_elements(obj)
|
style_elements = cls.get_style_elements(obj)
|
||||||
return style_elements.get("IfcSurfaceStyleWithTextures", None)
|
return style_elements.get("IfcSurfaceStyleWithTextures", None)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_external_style(cls, obj):
|
def get_external_style(cls, obj):
|
||||||
style_elements = cls.get_style_elements(obj)
|
style_elements = cls.get_style_elements(obj)
|
||||||
|
|||||||
@@ -108,7 +108,13 @@ class Usecase:
|
|||||||
|
|
||||||
def detect_occlusion_map(self):
|
def detect_occlusion_map(self):
|
||||||
for node in self.settings["material"].node_tree.nodes:
|
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
|
continue
|
||||||
from_node = node.inputs[0].links[0].from_node
|
from_node = node.inputs[0].links[0].from_node
|
||||||
if from_node.type == "SEPRGB":
|
if from_node.type == "SEPRGB":
|
||||||
|
|||||||
Reference in New Issue
Block a user