Skip to content

Commit 1c3bf35

Browse files
authored
w3d properties internal rename, multiple material per mesh object support, alpha transparency support, empty data object error fix (#261)
* __init__.py: blend_mode fixed to blend_method Renamed from blend_mode to blend_method in accordance with blender internals * material_import.py: Alpha Clip blend method for working transparency * material_import.py: Added support for Multiple Materials per Mesh Object Based on makarenk0's implementation, now with alpha transparency support. * Update mesh_import.py: Multiple Material per Mesh Object support +1 Argument to create_vertex_material in \material_import.py * material_import.py: alpha clip blend mode for multiple material meshes * Create an empty UV Map on early return This is to ensure no export errors due to empty object data in certain formats. (One example would be an error thrown on Airfield Imports due to the HOUSECOLOR01 material not having an UV Map attached.) * material_import.py: Fixed material duplication, node_tree manipulation * autopep8 action fixes * helpers.py : create_uvlayer, check if mesh exists * Update material_pass.py * Update material_pass.py * tests/material_pass.py get_texture_stage() : attempt at per face texture id enumeration * Update material_pass.py * Update material_import.py * Update material_import.py * Update material_import.py * autopep8 action fixes --------- Co-authored-by: rizzntine <rizzntine@users.noreply.github.com>
1 parent 7eccd38 commit 1c3bf35

5 files changed

Lines changed: 71 additions & 23 deletions

File tree

io_mesh_w3d/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ def draw(self, context):
298298
col = layout.column()
299299
col.prop(mat, 'surface_type')
300300
col = layout.column()
301-
col.prop(mat, 'blend_mode')
301+
col.prop(mat, 'blend_method')
302302
col = layout.column()
303303
col.prop(mat, 'ambient')
304304

@@ -370,7 +370,7 @@ def draw(self, context):
370370
col = layout.column()
371371
col.prop(mat, 'damaged_texture')
372372
col = layout.column()
373-
col.prop(mat, 'secondary_texture_blend_mode')
373+
col.prop(mat, 'secondary_texture_blend_method')
374374
col = layout.column()
375375
col.prop(mat, 'tex_coord_mapper_0')
376376
col = layout.column()

io_mesh_w3d/common/utils/helpers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ def create_uvlayer(context, mesh, b_mesh, tris, mat_pass):
8282
context.warning('only one texture stage per material pass supported')
8383

8484
if tx_coords is None:
85+
if mesh is not None:
86+
uv_layer = mesh.uv_layers.new(do_init=False)
8587
return
8688

8789
uv_layer = mesh.uv_layers.new(do_init=False)
@@ -96,6 +98,7 @@ def create_uvlayer_2(context, mesh, b_mesh, tris, mat_pass):
9698
if mat_pass.tx_coords_2:
9799
tx_coords_2 = mat_pass.tx_coords_2
98100
else:
101+
uv_layer = mesh.uv_layers.new(do_init=False)
99102
return
100103

101104
uv_layer = mesh.uv_layers.new(do_init=False)

io_mesh_w3d/common/utils/material_import.py

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,71 @@
1313
# vertex material
1414
##########################################################################
1515

16-
def create_vertex_material(context, principleds, structure, mesh, b_mesh, name, triangles):
17-
for vertMat in structure.vert_materials:
18-
(material, principled) = create_material_from_vertex_material(name, vertMat)
19-
mesh.materials.append(material)
20-
principleds.append(principled)
21-
22-
for mat_pass in structure.material_passes:
23-
create_uvlayer(context, mesh, b_mesh, triangles, mat_pass)
24-
create_uvlayer_2(context, mesh, b_mesh, triangles, mat_pass)
25-
26-
if mat_pass.tx_stages:
27-
tx_stage = mat_pass.tx_stages[0]
28-
mat_id = mat_pass.vertex_material_ids[0]
29-
tex_id = tx_stage.tx_ids[0][0]
16+
def create_vertex_material(context, principleds, structure, mesh, b_mesh, name, triangles, mesh_ob):
17+
18+
if len(structure.material_passes) == 1 and len(
19+
structure.textures) > 1: # condition for multiple materials per single mesh object
20+
# Create the same amount of materials as textures used for this mesh
21+
source_mat = structure.vert_materials[0]
22+
for texture in structure.textures:
23+
source_mat.vm_name = texture.id
24+
(material, principled) = create_material_from_vertex_material(name, source_mat)
25+
mesh.materials.append(material)
26+
principleds.append(principled)
27+
28+
create_uvlayer(context, mesh, b_mesh, triangles, structure.material_passes[0])
29+
30+
# Load textures
31+
for tex_id, texture in enumerate(structure.textures):
3032
texture = structure.textures[tex_id]
3133
tex = find_texture(context, texture.file, texture.id)
32-
principleds[mat_id].base_color_texture.image = tex
33-
principleds[mat_id].base_color_texture.image.name = texture.file
34+
node_tree = mesh.materials[tex_id].node_tree
35+
bsdf_node = node_tree.nodes.get('Principled BSDF')
36+
texture_node = node_tree.nodes.new('ShaderNodeTexImage')
37+
texture_node.image = tex
38+
texture_node.location = (-350, 300)
39+
links = node_tree.links
40+
links.new(texture_node.outputs['Color'], bsdf_node.inputs['Base Color'])
41+
links.new(texture_node.outputs['Alpha'], bsdf_node.inputs['Alpha'])
42+
43+
# Assign material to appropriate object faces
44+
bpy.ops.object.mode_set(mode='EDIT')
45+
bm = bmesh.from_edit_mesh(mesh_ob.data)
46+
bm.faces.ensure_lookup_table()
47+
for i, face in enumerate(bm.faces):
48+
if(i < len(structure.material_passes[0].tx_stages[0].tx_ids[0])):
49+
bm.faces[i].material_index = structure.material_passes[0].tx_stages[0].tx_ids[0][i]
50+
else:
51+
bm.faces[i].material_index = structure.material_passes[0].tx_stages[0].tx_ids[0][0]
52+
bpy.ops.object.mode_set(mode='OBJECT')
53+
else:
54+
for vertMat in structure.vert_materials:
55+
(material, principled) = create_material_from_vertex_material(name, vertMat)
56+
mesh.materials.append(material)
57+
principleds.append(principled)
58+
59+
for mat_pass in structure.material_passes:
60+
create_uvlayer(context, mesh, b_mesh, triangles, mat_pass)
61+
62+
if mat_pass.tx_stages:
63+
tx_stage = mat_pass.tx_stages[0]
64+
mat_id = mat_pass.vertex_material_ids[0]
65+
tex_id = tx_stage.tx_ids[0][0]
66+
texture = structure.textures[tex_id]
67+
tex = find_texture(context, texture.file, texture.id)
68+
node_tree = mesh.materials[tex_id].node_tree
69+
bsdf_node = node_tree.nodes.get('Principled BSDF')
70+
texture_node = node_tree.nodes.new('ShaderNodeTexImage')
71+
texture_node.image = tex
72+
texture_node.location = (-350, 300)
73+
links = node_tree.links
74+
links.new(texture_node.outputs['Color'], bsdf_node.inputs['Base Color'])
75+
links.new(texture_node.outputs['Alpha'], bsdf_node.inputs['Alpha'])
76+
77+
# Iterate through all materials and set their blend mode to Alpha Clip for transparency
78+
for material in mesh.materials:
79+
if material:
80+
material.blend_method = 'CLIP'
3481

3582

3683
def create_material_from_vertex_material(name, vert_mat):
@@ -43,7 +90,6 @@ def create_material_from_vertex_material(name, vert_mat):
4390
material = bpy.data.materials.new(name)
4491
material.material_type = 'VERTEX_MATERIAL'
4592
material.use_nodes = True
46-
material.blend_method = 'BLEND'
4793
material.show_transparent_back = False
4894

4995
attributes = {'DEFAULT'}
@@ -91,7 +137,6 @@ def create_material_from_shader_material(context, name, shader_mat):
91137
material = bpy.data.materials.new(name)
92138
material.material_type = 'SHADER_MATERIAL'
93139
material.use_nodes = True
94-
material.blend_method = 'BLEND'
95140
material.show_transparent_back = False
96141

97142
material.technique = shader_mat.header.technique

io_mesh_w3d/common/utils/mesh_import.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,14 @@ def create_mesh(context, mesh_struct, coll):
8383

8484
if mesh_struct.vert_materials:
8585
create_vertex_material(
86-
context, principleds, mesh_struct, mesh, b_mesh, actual_mesh_name, triangles)
86+
context, principleds, mesh_struct, mesh, b_mesh, actual_mesh_name, triangles, mesh_ob)
8787

8888
for i, shader in enumerate(mesh_struct.shaders):
8989
set_shader_properties(mesh.materials[min(i, len(mesh.materials) - 1)], shader)
9090

9191
elif mesh_struct.prelit_vertex:
9292
create_vertex_material(context, principleds, mesh_struct.prelit_vertex,
93-
mesh, b_mesh, actual_mesh_name, triangles)
93+
mesh, b_mesh, actual_mesh_name, triangles, mesh_ob)
9494

9595
for i, shader in enumerate(mesh_struct.prelit_vertex.shaders):
9696
set_shader_properties(mesh.materials[i], shader)

tests/w3d/helpers/mesh_structs/material_pass.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def get_per_face_txcoords():
3030

3131
def get_texture_stage(index=0):
3232
return TextureStage(
33-
tx_ids=[[index]],
33+
tx_ids=[[index] + [index] * max(0, index - 1)],
3434
per_face_tx_coords=[get_per_face_txcoords()],
3535
tx_coords=[get_uvs()])
3636

0 commit comments

Comments
 (0)