mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-31 17:06:29 +00:00
Texture support is now compatible with glTF texture maps
This commit is contained in:
@@ -26,6 +26,7 @@ classes = (
|
||||
operator.EditStyle,
|
||||
operator.RemoveStyle,
|
||||
operator.UpdateStyleColours,
|
||||
operator.UpdateStyleTextures,
|
||||
operator.UnlinkStyle,
|
||||
prop.BIMStyleProperties,
|
||||
ui.BIM_PT_style,
|
||||
|
||||
@@ -20,6 +20,7 @@ import bpy
|
||||
import blenderbim.bim.handler
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.core.style as core
|
||||
import ifcopenshell.util.representation
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
|
||||
|
||||
@@ -39,6 +40,21 @@ class UpdateStyleColours(bpy.types.Operator, Operator):
|
||||
core.update_style_colours(tool.Ifc, tool.Style, obj=context.active_object.active_material)
|
||||
|
||||
|
||||
class UpdateStyleTextures(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.update_style_textures"
|
||||
bl_label = "Update Style Textures"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
representation = ifcopenshell.util.representation.get_representation(
|
||||
tool.Ifc.get_entity(context.active_object), "Model", "Body", "MODEL_VIEW"
|
||||
)
|
||||
if representation:
|
||||
core.update_style_textures(
|
||||
tool.Ifc, tool.Style, obj=context.active_object.active_material, representation=representation
|
||||
)
|
||||
|
||||
|
||||
class RemoveStyle(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.remove_style"
|
||||
bl_label = "Remove Style"
|
||||
|
||||
@@ -42,6 +42,7 @@ class BIM_PT_style(Panel):
|
||||
row = self.layout.row(align=True)
|
||||
if props.ifc_style_id:
|
||||
row.operator("bim.update_style_colours", icon="GREASEPENCIL")
|
||||
row.operator("bim.update_style_textures", icon="TEXTURE", text="")
|
||||
row.operator("bim.unlink_style", icon="UNLINKED", text="")
|
||||
row.operator("bim.remove_style", icon="X", text="")
|
||||
else:
|
||||
|
||||
@@ -59,20 +59,25 @@ def update_style_colours(ifc, style, obj=None):
|
||||
else:
|
||||
ifc.run("style.add_surface_style", style=element, ifc_class="IfcSurfaceStyleShading", attributes=attributes)
|
||||
|
||||
|
||||
def update_style_textures(ifc, style, obj=None, representation=None):
|
||||
element = style.get_style(obj)
|
||||
|
||||
uv_maps = style.get_uv_maps(representation)
|
||||
textures = ifc.run("style.add_surface_textures", material=obj, uv_maps=uv_maps)
|
||||
texture_style = style.get_surface_texture_style(obj)
|
||||
if style.can_support_texture_style(obj):
|
||||
textures = ifc.run("style.add_surface_textures", textures=style.get_surface_textures(obj))
|
||||
|
||||
if textures:
|
||||
if texture_style:
|
||||
ifc.run("style.edit_surface_style", style=texture_style, attributes={"Textures": textures})
|
||||
else:
|
||||
ifc.run(
|
||||
"style.add_surface_style",
|
||||
style=element,
|
||||
ifc_class="IfcSurfaceStyleWithTextures",
|
||||
attributes={"Textures": textures},
|
||||
)
|
||||
ifc.run("style.remove_surface_style", style=texture_style)
|
||||
ifc.run(
|
||||
"style.add_surface_style",
|
||||
style=element,
|
||||
ifc_class="IfcSurfaceStyleWithTextures",
|
||||
attributes={"Textures": textures},
|
||||
)
|
||||
elif texture_style:
|
||||
ifc.run("style.remove_style", style=texture_style)
|
||||
ifc.run("style.remove_surface_style", style=texture_style)
|
||||
|
||||
|
||||
def unlink_style(ifc, style, obj=None):
|
||||
|
||||
@@ -396,7 +396,6 @@ class Structural:
|
||||
@interface
|
||||
class Style:
|
||||
def can_support_rendering_style(cls, obj): pass
|
||||
def can_support_texture_style(cls, obj): pass
|
||||
def disable_editing(cls, obj): pass
|
||||
def enable_editing(cls, obj): pass
|
||||
def export_surface_attributes(cls, obj): pass
|
||||
@@ -408,7 +407,7 @@ class Style:
|
||||
def get_surface_shading_attributes(cls, obj): pass
|
||||
def get_surface_shading_style(cls, obj): pass
|
||||
def get_surface_texture_style(cls, obj): pass
|
||||
def get_surface_textures(cls, obj): pass
|
||||
def get_uv_maps(cls, representation): pass
|
||||
def import_surface_attributes(cls, style, obj): pass
|
||||
|
||||
|
||||
|
||||
@@ -300,6 +300,8 @@ class Geometry(blenderbim.core.tool.Geometry):
|
||||
|
||||
@classmethod
|
||||
def should_generate_uvs(cls, obj):
|
||||
if tool.Ifc.get().schema == "IFC2X3":
|
||||
return False
|
||||
for slot in obj.material_slots:
|
||||
if slot.material and slot.material.use_nodes:
|
||||
for node in slot.material.node_tree.nodes:
|
||||
|
||||
@@ -27,41 +27,6 @@ class Style(blenderbim.core.tool.Style):
|
||||
def can_support_rendering_style(cls, obj):
|
||||
return obj.use_nodes and hasattr(obj.node_tree, "nodes")
|
||||
|
||||
@classmethod
|
||||
def can_support_texture_style(cls, obj):
|
||||
if not obj.node_tree:
|
||||
return False
|
||||
|
||||
output = {n.type: n for n in obj.node_tree.nodes}.get("OUTPUT_MATERIAL", None)
|
||||
if not output:
|
||||
return False
|
||||
|
||||
# For now, we assume only a single BSDF is allowed in our node tree.
|
||||
try:
|
||||
bsdf = output.inputs["Surface"].links[0].from_node
|
||||
except:
|
||||
return False
|
||||
|
||||
# For a quick check whether we have a compatible node tree, we check
|
||||
# whether or not we have at least one image texture node that has a
|
||||
# texture assigned and outputs to the bsdf.
|
||||
textures = [n for n in obj.node_tree.nodes if n.type == "TEX_IMAGE" and n.image]
|
||||
|
||||
def does_texture_connect_to(node, target):
|
||||
if node == target:
|
||||
return True
|
||||
try:
|
||||
output = node.outputs[0].links[0].to_node
|
||||
return does_texture_connect_to(output, target)
|
||||
except:
|
||||
return False
|
||||
|
||||
for texture in textures:
|
||||
if does_texture_connect_to(texture, bsdf):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def disable_editing(cls, obj):
|
||||
obj.BIMStyleProperties.is_editing = False
|
||||
@@ -174,7 +139,7 @@ class Style(blenderbim.core.tool.Style):
|
||||
def get_surface_shading_style(cls, obj):
|
||||
if obj.BIMMaterialProperties.ifc_style_id:
|
||||
style = tool.Ifc.get().by_id(obj.BIMMaterialProperties.ifc_style_id)
|
||||
items = [s for s in style.Styles if s.is_a("IfcSurfaceStyleShading")]
|
||||
items = [s for s in style.Styles if s.is_a() == "IfcSurfaceStyleShading"]
|
||||
if items:
|
||||
return items[0]
|
||||
|
||||
@@ -187,47 +152,18 @@ class Style(blenderbim.core.tool.Style):
|
||||
return items[0]
|
||||
|
||||
@classmethod
|
||||
def get_surface_textures(cls, obj):
|
||||
output = {n.type: n for n in obj.node_tree.nodes}.get("OUTPUT_MATERIAL", None)
|
||||
bsdf = output.inputs["Surface"].links[0].from_node
|
||||
node_mappings = {
|
||||
"BSDF_GLOSSY": {
|
||||
"DIFFUSE": "Color",
|
||||
"SHININESS": "Roughness",
|
||||
"NORMAL": "Normal",
|
||||
},
|
||||
"BSDF_DIFFUSE": {
|
||||
"DIFFUSE": "Color",
|
||||
"SHININESS": "Roughness",
|
||||
"NORMAL": "Normal",
|
||||
},
|
||||
"BSDF_GLASS": {
|
||||
"DIFFUSE": "Color",
|
||||
"SHININESS": "Roughness",
|
||||
"NORMAL": "Normal",
|
||||
},
|
||||
"EMISSION": {
|
||||
"DIFFUSE": "Color",
|
||||
},
|
||||
"BSDF_PRINCIPLED": {
|
||||
"DIFFUSE": "Base Color",
|
||||
"SHININESS": "Roughness",
|
||||
"NORMAL": "Normal",
|
||||
"SPECULAR": "Specular",
|
||||
"SELFILLUMINATION": "Emission Strength",
|
||||
"OPACITY": "Alpha",
|
||||
},
|
||||
}
|
||||
def get_uv_maps(cls, representation):
|
||||
items = []
|
||||
for item in representation.Items:
|
||||
if item.is_a("IfcMappedItem"):
|
||||
items.extend(item.MappingSource.MappedRepresentation.Items)
|
||||
items.append(item)
|
||||
|
||||
maps = {}
|
||||
if bsdf.type not in node_mappings:
|
||||
return maps
|
||||
|
||||
for map_type, input_name in node_mappings[bsdf.type].items():
|
||||
if bsdf.inputs[input_name].links:
|
||||
maps[map_type] = bsdf.inputs[input_name].links[0].from_node
|
||||
|
||||
return maps
|
||||
results = []
|
||||
for item in items:
|
||||
for uv_map in item.HasTextures or []:
|
||||
results.append(uv_map)
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def import_surface_attributes(cls, style, obj):
|
||||
|
||||
@@ -32,8 +32,6 @@ class TestAddStyle:
|
||||
"style.add_surface_style", style="style", ifc_class="IfcSurfaceStyleRendering", attributes="attributes"
|
||||
).should_be_called()
|
||||
|
||||
style.can_support_texture_style("obj").should_be_called().will_return(False)
|
||||
|
||||
ifc.get_entity("obj").should_be_called().will_return(None)
|
||||
assert subject.add_style(ifc, style, obj="obj") == "style"
|
||||
|
||||
@@ -48,8 +46,6 @@ class TestAddStyle:
|
||||
"style.add_surface_style", style="style", ifc_class="IfcSurfaceStyleShading", attributes="attributes"
|
||||
).should_be_called()
|
||||
|
||||
style.can_support_texture_style("obj").should_be_called().will_return(False)
|
||||
|
||||
ifc.get_entity("obj").should_be_called().will_return("material")
|
||||
style.get_context("obj").should_be_called().will_return("context")
|
||||
ifc.run("style.assign_material_style", material="material", style="style", context="context").should_be_called()
|
||||
@@ -66,93 +62,88 @@ class TestRemoveStyle:
|
||||
|
||||
class TestUpdateStyleColours:
|
||||
def test_updating_rendering_style_if_available(self, ifc, style):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
style.get_style("obj").should_be_called().will_return("element")
|
||||
style.can_support_rendering_style("obj").should_be_called().will_return(True)
|
||||
style.get_surface_rendering_style("obj").should_be_called().will_return("style")
|
||||
style.get_surface_rendering_attributes("obj").should_be_called().will_return("attributes")
|
||||
ifc.run("style.edit_surface_style", style="style", attributes="attributes").should_be_called()
|
||||
style.get_surface_texture_style("obj").should_be_called().will_return(None)
|
||||
style.can_support_texture_style("obj").should_be_called().will_return(False)
|
||||
subject.update_style_colours(ifc, style, obj="obj")
|
||||
|
||||
def test_adding_a_rendering_style_if_not_available(self, ifc, style):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
style.get_style("obj").should_be_called().will_return("element")
|
||||
style.can_support_rendering_style("obj").should_be_called().will_return(True)
|
||||
style.get_surface_rendering_style("obj").should_be_called().will_return(None)
|
||||
style.get_surface_rendering_attributes("obj").should_be_called().will_return("attributes")
|
||||
ifc.run(
|
||||
"style.add_surface_style", style="element", ifc_class="IfcSurfaceStyleRendering", attributes="attributes"
|
||||
).should_be_called()
|
||||
style.get_surface_texture_style("obj").should_be_called().will_return(None)
|
||||
style.can_support_texture_style("obj").should_be_called().will_return(False)
|
||||
subject.update_style_colours(ifc, style, obj="obj")
|
||||
|
||||
def test_updating_shading_style_as_a_fallback_if_available(self, ifc, style):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
style.get_style("obj").should_be_called().will_return("element")
|
||||
style.can_support_rendering_style("obj").should_be_called().will_return(False)
|
||||
style.get_surface_shading_style("obj").should_be_called().will_return("style")
|
||||
style.get_surface_shading_attributes("obj").should_be_called().will_return("attributes")
|
||||
ifc.run("style.edit_surface_style", style="style", attributes="attributes").should_be_called()
|
||||
style.get_surface_texture_style("obj").should_be_called().will_return(None)
|
||||
style.can_support_texture_style("obj").should_be_called().will_return(False)
|
||||
subject.update_style_colours(ifc, style, obj="obj")
|
||||
|
||||
def test_adding_a_shading_style_as_a_fallback_if_not_available(self, ifc, style):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
style.get_style("obj").should_be_called().will_return("element")
|
||||
style.can_support_rendering_style("obj").should_be_called().will_return(False)
|
||||
style.get_surface_shading_style("obj").should_be_called().will_return(None)
|
||||
style.get_surface_shading_attributes("obj").should_be_called().will_return("attributes")
|
||||
ifc.run(
|
||||
"style.add_surface_style", style="element", ifc_class="IfcSurfaceStyleShading", attributes="attributes"
|
||||
).should_be_called()
|
||||
style.get_surface_texture_style("obj").should_be_called().will_return(None)
|
||||
style.can_support_texture_style("obj").should_be_called().will_return(False)
|
||||
subject.update_style_colours(ifc, style, obj="obj")
|
||||
|
||||
def test_updating_texture_style_if_available(self, ifc, style):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
style.can_support_rendering_style("obj").should_be_called().will_return(False)
|
||||
style.get_surface_shading_style("obj").should_be_called().will_return("style")
|
||||
style.get_surface_shading_attributes("obj").should_be_called().will_return("attributes")
|
||||
ifc.run("style.edit_surface_style", style="style", attributes="attributes").should_be_called()
|
||||
|
||||
class TestUpdateStyleTextures:
|
||||
def test_updating_an_existing_texture_style(self, ifc, style):
|
||||
style.get_style("obj").should_be_called().will_return("element")
|
||||
style.get_uv_maps("representation").should_be_called().will_return("uv_maps")
|
||||
ifc.run("style.add_surface_textures", material="obj", uv_maps="uv_maps").should_be_called().will_return(
|
||||
"textures"
|
||||
)
|
||||
style.get_surface_texture_style("obj").should_be_called().will_return("style")
|
||||
style.can_support_texture_style("obj").should_be_called().will_return(True)
|
||||
style.get_surface_textures("obj").should_be_called().will_return("textures")
|
||||
ifc.run("style.add_surface_textures", textures="textures").should_be_called().will_return("ifc_textures")
|
||||
ifc.run("style.edit_surface_style", style="style", attributes={"Textures": "ifc_textures"}).should_be_called()
|
||||
subject.update_style_colours(ifc, style, obj="obj")
|
||||
|
||||
def test_adding_texture_style_if_not_available(self, ifc, style):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
style.can_support_rendering_style("obj").should_be_called().will_return(False)
|
||||
style.get_surface_shading_style("obj").should_be_called().will_return("style")
|
||||
style.get_surface_shading_attributes("obj").should_be_called().will_return("attributes")
|
||||
ifc.run("style.edit_surface_style", style="style", attributes="attributes").should_be_called()
|
||||
|
||||
style.get_surface_texture_style("obj").should_be_called().will_return(None)
|
||||
style.can_support_texture_style("obj").should_be_called().will_return(True)
|
||||
style.get_surface_textures("obj").should_be_called().will_return("textures")
|
||||
ifc.run("style.add_surface_textures", textures="textures").should_be_called().will_return("ifc_textures")
|
||||
ifc.run("style.remove_surface_style", style="style").should_be_called()
|
||||
ifc.run(
|
||||
"style.add_surface_style",
|
||||
style="element",
|
||||
ifc_class="IfcSurfaceStyleWithTextures",
|
||||
attributes={"Textures": "ifc_textures"},
|
||||
attributes={"Textures": "textures"},
|
||||
).should_be_called()
|
||||
subject.update_style_colours(ifc, style, obj="obj")
|
||||
subject.update_style_textures(ifc, style, obj="obj", representation="representation")
|
||||
|
||||
def test_removing_a_texture_style_if_no_longer_available(self, ifc, style):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
style.can_support_rendering_style("obj").should_be_called().will_return(False)
|
||||
style.get_surface_shading_style("obj").should_be_called().will_return("style")
|
||||
style.get_surface_shading_attributes("obj").should_be_called().will_return("attributes")
|
||||
ifc.run("style.edit_surface_style", style="style", attributes="attributes").should_be_called()
|
||||
def test_adding_a_fresh_texture_style(self, ifc, style):
|
||||
style.get_style("obj").should_be_called().will_return("element")
|
||||
style.get_uv_maps("representation").should_be_called().will_return("uv_maps")
|
||||
ifc.run("style.add_surface_textures", material="obj", uv_maps="uv_maps").should_be_called().will_return(
|
||||
"textures"
|
||||
)
|
||||
style.get_surface_texture_style("obj").should_be_called().will_return(None)
|
||||
ifc.run(
|
||||
"style.add_surface_style",
|
||||
style="element",
|
||||
ifc_class="IfcSurfaceStyleWithTextures",
|
||||
attributes={"Textures": "textures"},
|
||||
).should_be_called()
|
||||
subject.update_style_textures(ifc, style, obj="obj", representation="representation")
|
||||
|
||||
def test_removing_an_texture_if_no_textures_can_be_added(self, ifc, style):
|
||||
style.get_style("obj").should_be_called().will_return("element")
|
||||
style.get_uv_maps("representation").should_be_called().will_return("uv_maps")
|
||||
ifc.run("style.add_surface_textures", material="obj", uv_maps="uv_maps").should_be_called().will_return(None)
|
||||
style.get_surface_texture_style("obj").should_be_called().will_return("style")
|
||||
style.can_support_texture_style("obj").should_be_called().will_return(False)
|
||||
ifc.run("style.remove_style", style="style").should_be_called()
|
||||
subject.update_style_colours(ifc, style, obj="obj")
|
||||
ifc.run("style.remove_surface_style", style="style").should_be_called()
|
||||
subject.update_style_textures(ifc, style, obj="obj", representation="representation")
|
||||
|
||||
def test_doing_nothing_if_no_existing_texture_and_we_cannot_add_a_new_texture(self, ifc, style):
|
||||
style.get_style("obj").should_be_called().will_return("element")
|
||||
style.get_uv_maps("representation").should_be_called().will_return("uv_maps")
|
||||
ifc.run("style.add_surface_textures", material="obj", uv_maps="uv_maps").should_be_called().will_return(None)
|
||||
style.get_surface_texture_style("obj").should_be_called().will_return(None)
|
||||
subject.update_style_textures(ifc, style, obj="obj", representation="representation")
|
||||
|
||||
|
||||
class TestUnlinkStyle:
|
||||
|
||||
@@ -464,10 +464,14 @@ class TestShouldForceTriangulation(NewFile):
|
||||
|
||||
class TestShouldGenerateUVs(NewFile):
|
||||
def test_needs_mesh_data(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc.set(ifc)
|
||||
obj = bpy.data.objects.new("Object", None)
|
||||
assert subject.should_generate_uvs(obj) is False
|
||||
|
||||
def test_needs_nodes(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc.set(ifc)
|
||||
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
||||
material = bpy.data.materials.new("Material")
|
||||
obj.data.materials.append(material)
|
||||
@@ -475,6 +479,8 @@ class TestShouldGenerateUVs(NewFile):
|
||||
assert subject.should_generate_uvs(obj) is False
|
||||
|
||||
def test_needs_texture_coordinates_with_a_uv_output(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc.set(ifc)
|
||||
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
||||
material = bpy.data.materials.new("Material")
|
||||
obj.data.materials.append(material)
|
||||
@@ -489,6 +495,8 @@ class TestShouldGenerateUVs(NewFile):
|
||||
assert subject.should_generate_uvs(obj) is True
|
||||
|
||||
def test_accepts_a_uv_map_node(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc.set(ifc)
|
||||
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
||||
material = bpy.data.materials.new("Material")
|
||||
obj.data.materials.append(material)
|
||||
|
||||
@@ -42,42 +42,6 @@ class TestCanSupportRenderingStyle(NewFile):
|
||||
assert subject.can_support_rendering_style(obj) is False
|
||||
|
||||
|
||||
class TestCanSupportTextureStyle(NewFile):
|
||||
def test_without_nodes_we_do_not_support_textures(self):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.use_nodes = False
|
||||
assert subject.can_support_texture_style(obj) is False
|
||||
|
||||
def test_we_need_at_least_one_image_connected_to_a_bsdf(self):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.use_nodes = True
|
||||
bsdf = obj.node_tree.nodes["Principled BSDF"]
|
||||
node = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
image_path = os.path.join(cwd, "..", "files", "image.jpg")
|
||||
node.image = bpy.data.images.load(image_path)
|
||||
obj.node_tree.links.new(bsdf.inputs["Base Color"], node.outputs["Color"])
|
||||
assert subject.can_support_texture_style(obj) is True
|
||||
|
||||
def test_a_texture_without_an_image_filepath_is_not_supported(self):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.use_nodes = True
|
||||
bsdf = obj.node_tree.nodes["Principled BSDF"]
|
||||
node = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Base Color"], node.outputs["Color"])
|
||||
assert subject.can_support_texture_style(obj) is False
|
||||
|
||||
def test_the_texture_needs_to_connect_to_the_bsdf(self):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.use_nodes = True
|
||||
bsdf = obj.node_tree.nodes["Principled BSDF"]
|
||||
node = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
image_path = os.path.join(cwd, "..", "files", "image.jpg")
|
||||
node.image = bpy.data.images.load(image_path)
|
||||
assert subject.can_support_texture_style(obj) is False
|
||||
|
||||
|
||||
class TestDisableEditing(NewFile):
|
||||
def test_run(self):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
@@ -338,6 +302,14 @@ class TestGetSurfaceShadingStyle(NewFile):
|
||||
obj.BIMMaterialProperties.ifc_style_id = style.id()
|
||||
assert subject.get_surface_shading_style(obj) == style_item
|
||||
|
||||
def test_do_not_get_rendering_styles(self):
|
||||
tool.Ifc.set(ifcopenshell.file())
|
||||
style_item = tool.Ifc.get().createIfcSurfaceStyleRendering()
|
||||
style = tool.Ifc.get().createIfcSurfaceStyle(Styles=[style_item])
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.BIMMaterialProperties.ifc_style_id = style.id()
|
||||
assert subject.get_surface_shading_style(obj) is None
|
||||
|
||||
|
||||
class TestGetSurfaceTextureStyle(NewFile):
|
||||
def test_run(self):
|
||||
@@ -349,105 +321,13 @@ class TestGetSurfaceTextureStyle(NewFile):
|
||||
assert subject.get_surface_texture_style(obj) == style_item
|
||||
|
||||
|
||||
class TestGetSurfaceTextures(NewFile):
|
||||
def test_get_the_leaf_node_of_each_map_in_a_glossy_bsdf(self):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.use_nodes = True
|
||||
bsdf = obj.node_tree.nodes["Principled BSDF"]
|
||||
|
||||
obj.node_tree.nodes.remove(bsdf)
|
||||
bsdf = obj.node_tree.nodes.new(type="ShaderNodeBsdfGlossy")
|
||||
output = {n.type: n for n in obj.node_tree.nodes}.get("OUTPUT_MATERIAL", None)
|
||||
obj.node_tree.links.new(output.inputs["Surface"], bsdf.outputs["BSDF"])
|
||||
|
||||
diffuse = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Color"], diffuse.outputs["Color"])
|
||||
shininess = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Roughness"], shininess.outputs["Color"])
|
||||
normal = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Normal"], normal.outputs["Color"])
|
||||
|
||||
assert subject.get_surface_textures(obj) == {"DIFFUSE": diffuse, "SHININESS": shininess, "NORMAL": normal}
|
||||
|
||||
def test_get_the_leaf_node_of_each_map_in_a_diffuse_bsdf(self):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.use_nodes = True
|
||||
bsdf = obj.node_tree.nodes["Principled BSDF"]
|
||||
|
||||
obj.node_tree.nodes.remove(bsdf)
|
||||
bsdf = obj.node_tree.nodes.new(type="ShaderNodeBsdfDiffuse")
|
||||
output = {n.type: n for n in obj.node_tree.nodes}.get("OUTPUT_MATERIAL", None)
|
||||
obj.node_tree.links.new(output.inputs["Surface"], bsdf.outputs["BSDF"])
|
||||
|
||||
diffuse = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Color"], diffuse.outputs["Color"])
|
||||
shininess = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Roughness"], shininess.outputs["Color"])
|
||||
normal = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Normal"], normal.outputs["Color"])
|
||||
|
||||
assert subject.get_surface_textures(obj) == {"DIFFUSE": diffuse, "SHININESS": shininess, "NORMAL": normal}
|
||||
|
||||
def test_get_the_leaf_node_of_each_map_in_a_glass_bsdf(self):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.use_nodes = True
|
||||
bsdf = obj.node_tree.nodes["Principled BSDF"]
|
||||
|
||||
obj.node_tree.nodes.remove(bsdf)
|
||||
bsdf = obj.node_tree.nodes.new(type="ShaderNodeBsdfGlass")
|
||||
output = {n.type: n for n in obj.node_tree.nodes}.get("OUTPUT_MATERIAL", None)
|
||||
obj.node_tree.links.new(output.inputs["Surface"], bsdf.outputs["BSDF"])
|
||||
|
||||
diffuse = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Color"], diffuse.outputs["Color"])
|
||||
shininess = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Roughness"], shininess.outputs["Color"])
|
||||
normal = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Normal"], normal.outputs["Color"])
|
||||
|
||||
assert subject.get_surface_textures(obj) == {"DIFFUSE": diffuse, "SHININESS": shininess, "NORMAL": normal}
|
||||
|
||||
def test_get_the_leaf_node_of_each_map_in_a_emission_bsdf(self):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.use_nodes = True
|
||||
bsdf = obj.node_tree.nodes["Principled BSDF"]
|
||||
|
||||
obj.node_tree.nodes.remove(bsdf)
|
||||
bsdf = obj.node_tree.nodes.new(type="ShaderNodeEmission")
|
||||
output = {n.type: n for n in obj.node_tree.nodes}.get("OUTPUT_MATERIAL", None)
|
||||
obj.node_tree.links.new(output.inputs["Surface"], bsdf.outputs["Emission"])
|
||||
|
||||
diffuse = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Color"], diffuse.outputs["Color"])
|
||||
|
||||
assert subject.get_surface_textures(obj) == {"DIFFUSE": diffuse}
|
||||
|
||||
def test_get_the_leaf_node_of_each_map_in_a_principled_bsdf(self):
|
||||
obj = bpy.data.materials.new("Material")
|
||||
obj.use_nodes = True
|
||||
bsdf = obj.node_tree.nodes["Principled BSDF"]
|
||||
|
||||
diffuse = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Base Color"], diffuse.outputs["Color"])
|
||||
shininess = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Roughness"], shininess.outputs["Color"])
|
||||
normal = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Normal"], normal.outputs["Color"])
|
||||
specular = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Specular"], specular.outputs["Color"])
|
||||
emission = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Emission Strength"], emission.outputs["Color"])
|
||||
opacity = obj.node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
obj.node_tree.links.new(bsdf.inputs["Alpha"], opacity.outputs["Color"])
|
||||
|
||||
assert subject.get_surface_textures(obj) == {
|
||||
"DIFFUSE": diffuse,
|
||||
"SHININESS": shininess,
|
||||
"NORMAL": normal,
|
||||
"SPECULAR": specular,
|
||||
"SELFILLUMINATION": emission,
|
||||
"OPACITY": opacity,
|
||||
}
|
||||
class TestGetUVMaps(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
item = ifc.createIfcTriangulatedFaceSet()
|
||||
uv_map = ifc.createIfcIndexedTriangleTextureMap(MappedTo=item)
|
||||
representation = ifc.createIfcShapeRepresentation(Items=[item])
|
||||
assert subject.get_uv_maps(representation) == [uv_map]
|
||||
|
||||
|
||||
class TestImportSurfaceAttributes(NewFile):
|
||||
|
||||
Reference in New Issue
Block a user