Skip to content

Commit

Permalink
basic implementation of face maps for 4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Tarcontar committed Jan 26, 2024
1 parent 9829304 commit e3f0d78
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 16 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ jobs:
runs-on: [ ubuntu-latest ]
strategy:
matrix:
blender-version: [ '2.93', '3.6' ] #, '4.0' ]
blender-version: [ '2.93', '3.6', '4.0' ]
include:
- blender-version: '2.93'
blender-version-suffix: '13'
python-version: '3.9.16'
- blender-version: '3.6'
blender-version-suffix: '0'
python-version: '3.10.9'
#- blender-version: '4.0'
# blender-version-suffix: '0'
# python-version: '3.10.9'
- blender-version: '4.0'
blender-version-suffix: '0'
python-version: '3.10.9'

steps:
- uses: actions/checkout@v3
Expand Down
9 changes: 7 additions & 2 deletions io_mesh_w3d/common/utils/material_export.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# <pep8 compliant>
# Written by Stephan Vedder and Michael Schnabel

import bpy
from mathutils import Vector
from io_mesh_w3d.w3d.structs.mesh_structs.shader import *
from io_mesh_w3d.w3d.structs.mesh_structs.vertex_material import *
Expand Down Expand Up @@ -118,20 +119,24 @@ def retrieve_shader_material(context, material, principled, w3x=False):
header=ShaderMaterialHeader(
type_name=name),
properties=[])

color_emissive_default = Vector((0.0, 0.0, 0.0, 1.0))
if bpy.app.version >= (4, 0, 0):
color_emissive_default = Vector((1.0, 1.0, 1.0, 1.0))

if w3x:
append_property(shader_mat, 2, 'Shininess', material.specular_intensity * 200.0, 100.0)
append_property(shader_mat, 5, 'ColorDiffuse', to_vec(material.diffuse_color), Vector((0.8, 0.8, 0.8, 1.0)))
append_property(shader_mat, 5, 'ColorSpecular', to_vec(material.specular_color), Vector((0.0, 0.0, 0.0, 1.0)))
append_property(shader_mat, 5, 'ColorAmbient', to_vec(material.ambient), Vector((1.0, 1.0, 1.0, 0.0)))
append_property(shader_mat, 5, 'ColorEmissive', to_vec(principled.emission_color), Vector((0.0, 0.0, 0.0, 1.0)))
append_property(shader_mat, 5, 'ColorEmissive', to_vec(principled.emission_color), color_emissive_default)

else:
append_property(shader_mat, 2, 'SpecularExponent', material.specular_intensity * 200.0, 100.0)
append_property(shader_mat, 5, 'DiffuseColor', to_vec(material.diffuse_color), Vector((0.8, 0.8, 0.8, 1.0)))
append_property(shader_mat, 5, 'SpecularColor', to_vec(material.specular_color), Vector((0.0, 0.0, 0.0, 1.0)))
append_property(shader_mat, 5, 'AmbientColor', to_vec(material.ambient), Vector((1.0, 1.0, 1.0, 0.0)))
append_property(shader_mat, 5, 'EmissiveColor', to_vec(principled.emission_color), Vector((0.0, 0.0, 0.0, 1.0)))
append_property(shader_mat, 5, 'EmissiveColor', to_vec(principled.emission_color), color_emissive_default)

if material.texture_1:
append_property(shader_mat, 1, 'Texture_0', principled.base_color_texture)
Expand Down
11 changes: 8 additions & 3 deletions io_mesh_w3d/common/utils/mesh_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,14 @@ def retrieve_meshes(context, hierarchy, rig, container_name, force_vertex_materi
face_map_names = [map.name for map in mesh_object.face_maps]
Triangle.validate_face_map_names(context, face_map_names)

for map in mesh.face_maps:
for i, val in enumerate(map.data):
mesh_struct.triangles[i].set_surface_type(face_map_names[val.value])
for map in mesh_object.face_maps:
if bpy.app.version < (4, 0, 0):
for i, val in enumerate(map.data):
mesh_struct.triangles[i].set_surface_type(face_map_names[val.value])
else:
for val in map.value:
if val.value < len(mesh_struct.triangles):
mesh_struct.triangles[val.value].set_surface_type(map.name)

header.face_count = len(mesh_struct.triangles)

Expand Down
17 changes: 13 additions & 4 deletions io_mesh_w3d/common/utils/mesh_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,17 @@ def create_mesh(context, mesh_struct, coll):
for i, triangle in enumerate(mesh_struct.triangles):
surface_type_name = triangle.get_surface_type_name(context, i)
if surface_type_name not in mesh_ob.face_maps:
mesh_ob.face_maps.new(name=surface_type_name)

mesh_ob.face_maps[surface_type_name].add([i])
if bpy.app.version < (4, 0, 0):
mesh_ob.face_maps.new(name=surface_type_name)
else:
face_map = mesh_ob.face_maps.add()
face_map.name = surface_type_name

if bpy.app.version < (4, 0, 0):
mesh_ob.face_maps[surface_type_name].add([i])
else:
val = mesh_ob.face_maps[surface_type_name].value.add()
val.value = i

for i, mat_pass in enumerate(mesh_struct.material_passes):
create_vertex_color_layer(mesh, mat_pass.dcg, 'DCG', i)
Expand All @@ -71,7 +79,8 @@ def create_mesh(context, mesh_struct, coll):
# vertex material stuff
b_mesh = bmesh.new()
b_mesh.from_mesh(mesh)

b_mesh.faces.ensure_lookup_table()

if mesh_struct.vert_materials:
create_vertex_material(
context, principleds, mesh_struct, mesh, b_mesh, actual_mesh_name, triangles)
Expand Down
19 changes: 18 additions & 1 deletion io_mesh_w3d/custom_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import bpy
from bpy.props import *
from bpy.types import Material, PropertyGroup, Bone, Mesh, Object
from bpy.types import Material, PropertyGroup, Bone, Mesh, Object, MeshPolygon


##########################################################################
Expand Down Expand Up @@ -122,6 +122,23 @@
('DEBRIS', 'debris', 'desc: debris contact tag')],
default='DEBRIS')

##########################################################################
# Object
##########################################################################

class SurfaceType(bpy.types.PropertyGroup):
value: bpy.props.IntProperty(default=0)

bpy.utils.register_class(SurfaceType)

class FaceMap(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(name="Face Map Name", default="Unknown")
value: CollectionProperty(type=SurfaceType)

bpy.utils.register_class(FaceMap)

if bpy.app.version >= (4, 0, 0):
Object.face_maps = CollectionProperty(type=FaceMap)

##########################################################################
# PoseBone
Expand Down
1 change: 1 addition & 0 deletions tests/common/cases/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ def test_default_shader_material_properties_are_not_exported(self):
self.assertEqual(0, len(actual.properties))

actual = retrieve_shader_material(self, material, principled, w3x=True)
self.assertEqual([], actual.properties)
self.assertEqual(0, len(actual.properties))

def test_shader_material_minimal_roundtrip(self):
Expand Down
13 changes: 11 additions & 2 deletions tests/common/cases/utils/test_mesh_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,9 +652,18 @@ def test_mesh_export_invalid_surface_types(self):
mesh_ob = bpy.data.objects['mesh']
mesh_ob.face_maps.clear()

mesh_ob.face_maps.new(name='InvalidSurfaceType')
if bpy.app.version < (4, 0, 0):
mesh_ob.face_maps.new(name='InvalidSurfaceType')
else:
face_map = mesh_ob.face_maps.add()
face_map.name = 'InvalidSurfaceType'

for i, _ in enumerate(mesh.verts):
mesh_ob.face_maps[0].add([i])
if bpy.app.version < (4, 0, 0):
mesh_ob.face_maps[0].add([i])
else:
val = mesh_ob.face_maps[0].value.add()
val.value = i

with (patch.object(self, 'warning')) as report_func:
meshes, _ = retrieve_meshes(self, None, None, 'container_name')
Expand Down
2 changes: 2 additions & 0 deletions tests/common/helpers/mesh_structs/triangle.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ def get_triangle(vert_ids=None,
def compare_triangles(self, expected, actual, is_skin=False):
self.assertEqual(expected.vert_ids, actual.vert_ids)
if not self.file_format == 'W3X': # surface type is not supported in W3X file format
if expected.surface_type != actual.surface_type:
print("expected: " + str(expected.surface_type) + ", actual: " + str(actual.surface_type))
self.assertEqual(expected.surface_type, actual.surface_type)

if not is_skin: # generated/changed by blender
Expand Down

0 comments on commit e3f0d78

Please sign in to comment.