Skip to content

Commit

Permalink
Create Tex node from PNG file in ShaderNodeTexImage
Browse files Browse the repository at this point in the history
  • Loading branch information
1r3n33 committed Aug 18, 2020
1 parent a2cc624 commit 22005c3
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 7 deletions.
43 changes: 38 additions & 5 deletions blend2niff/exporter.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
"""Create .nif file from Blender data."""

import bpy
from bpy.types import (Camera, Light, Mesh)
from bpy.types import (Camera, Light, Mesh, ShaderNodeTexImage)

import png

from blend2niff.niff2.niff2_anim import (
niff2_anim_list_header_builder, niff2_anim_list_header_writer,
niff2_anim_group_builder, niff2_anim_group_writer,
Expand Down Expand Up @@ -108,6 +111,31 @@ def create_name(self, name):
self.names.append(name_node)
return name_node

def create_textures(self, objs):
"""
Create and register all textures.
"""
meshes = [obj.data for obj in objs if isinstance(obj.data, Mesh)]

for mesh in meshes:
for mat in mesh.materials:
if mat.use_nodes and mat.node_tree:
tex_img_nodes = [node for node in mat.node_tree.nodes if isinstance(
node, ShaderNodeTexImage)]
for tex_img_node in tex_img_nodes:
filepath = bpy.path.abspath(
tex_img_node.image.filepath, library=tex_img_node.image.library)
png_reader = png.Reader(filepath)
image = png_reader.read()

tex_name = self.create_name(
bpy.path.display_name_from_filepath(filepath)+".tex")
tex = niff2_tex_node_builder(len(self.textures),
tex_name.index(),
width=image[0],
height=image[1])
self.textures.append(tex)

def create_materials(self, objs):
"""
Create and register all scene materials including the default material (index 0).
Expand Down Expand Up @@ -439,6 +467,8 @@ def write_niff2(data, filepath):

scene_name = exporter.create_name(filename+".scene")

exporter.create_textures(mesh_objs)

exporter.create_materials(mesh_objs)

exporter.create_vertex_groups(mesh_objs)
Expand Down Expand Up @@ -495,8 +525,11 @@ def write_niff2(data, filepath):
exporter.objs.append(eye_obj)

lookat_obj_name = exporter.create_name(cam.name+".lookat.obj")
lookat_obj = niff2_obj_node_builder(
len(exporter.objs), lookat_obj_name.index(), BAD_INDEX, BAD_INDEX, lookat_anim_group.index())
lookat_obj = niff2_obj_node_builder(len(exporter.objs),
lookat_obj_name.index(),
BAD_INDEX,
BAD_INDEX,
lookat_anim_group.index())
exporter.objs.append(lookat_obj)

up_obj_name = exporter.create_name(cam.name+".up.obj")
Expand Down Expand Up @@ -552,7 +585,7 @@ def write_niff2(data, filepath):
st_list_header = niff2_st_list_header_builder(exporter.st_groups)
part_list_header = niff2_part_list_header_builder(exporter.parts)
mat_list_header = niff2_mat_list_header_builder(exporter.materials)
tex_list_header = niff2_tex_list_header_builder([])
tex_list_header = niff2_tex_list_header_builder(exporter.textures)
tex_img_list_header = niff2_tex_img_list_header_builder()
anim_list_header = niff2_anim_list_header_builder(exporter.anim_groups)
coll_list_header = niff2_coll_list_header_builder()
Expand Down Expand Up @@ -687,7 +720,7 @@ def write_niff2(data, filepath):
for mat in exporter.materials:
niff2_mat_node_writer(mat, buf)

niff2_tex_list_header_writer(tex_list_header, [], buf)
niff2_tex_list_header_writer(tex_list_header, exporter.textures, buf)
for tex in exporter.textures:
niff2_tex_node_writer(tex, buf)

Expand Down
55 changes: 53 additions & 2 deletions tests/test_exporter.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
"""Tests about creating .nif data from Blender data."""

import unittest
from bpy.types import (Material,
from unittest.mock import Mock

import bpy
from bpy.types import (Image,
Material,
Mesh,
MeshLoop,
MeshLoopColor,
Expand All @@ -10,7 +14,12 @@
MeshUVLoop,
MeshUVLoopLayer,
MeshVertex,
Object)
NodeTree,
Object,
ShaderNodeTexImage)

import png

from blend2niff.exporter import Exporter


Expand All @@ -22,6 +31,48 @@ def test_create_name(self):

self.assertEqual(exporter.names, [hello, world])

def test_create_textures(self):
image = Image()
image.filepath = "//test/image/path.png"
image.library = "//test/image/library"

node = ShaderNodeTexImage()
node.image = image

material = Material()
material.name = "material"
material.diffuse_color = [1.0, 1.0, 1.0, 1.0]
material.use_nodes = True
material.node_tree = NodeTree()
material.node_tree.nodes = [node]

mesh = Mesh()
mesh.materials = [material]

obj = Object()
obj.data = mesh

bpy.path.abspath = Mock(return_value=image.filepath)
bpy.path.display_name_from_filepath = Mock(return_value="texture")

reader = Mock()
reader.read = Mock(return_value=[12, 34])
png.Reader = Mock(return_value=reader)

exporter = Exporter()
exporter.create_textures([obj])

bpy.path.abspath.assert_called_once_with(
"//test/image/path.png", library="//test/image/library")
bpy.path.display_name_from_filepath.assert_called_once_with(
"//test/image/path.png")
png.Reader.assert_called_once_with("//test/image/path.png")
reader.read.assert_called_once()

self.assertEqual(exporter.names[0].node_name, "texture.tex")
self.assertEqual(exporter.textures[0].tex_img_width, 12)
self.assertEqual(exporter.textures[0].tex_img_height, 34)

def test_create_materials(self):
not_a_mesh = Object()
mesh_with_0_mat = Object()
Expand Down

0 comments on commit 22005c3

Please sign in to comment.