[PYTHON] Automatically render Blender and export FBX with Git Hook

Introduction

This article is the second day of Mie University Computational Research Institute Advent Calendar 2019.

When developing games in a circle, I also managed the version of 3D model data created in Blender with Git. In order to use Blender files in game development, it is convenient to use the one exported to FBX.

Therefore, by using a function called Git Hook this time, ** image rendering for thumbnails ** and ** FBX export ** are automatically performed when Git Push is executed.

This not only automates the work, but also has the advantage of ** eliminating FBX export setting mistakes ** and ** not forgetting to update the FBX file when editing the Blend file **.

This time, I will introduce Git Hook and the work to actually perform automatic export with Blender.

What is Git Hook?

It's a standard feature of Git that allows you to run scripts when you're doing certain Git work.

As a type

And so on.

With these,

Can be done.

There is also a server side, but this time we will use ** pre-push ** on the client side so that it can be automatically rendered and exported when Git Push is performed.

What to achieve this time

In the develop branch, place the Blend file and Git Push automatically

Will be done.

The expected directory structure is as follows.

<Develop branch before Push>

├─Scripts :Put scripts for automatic rendering and FBX export. The specific contents will be described later.
└─ProjectName
    │
    ├─blend :Directory to put the blend file
    │  │ aaa.blend
    │  │ bbb.blend
    │  │ ccc.blend
    │
    └─Textures :Directory to put textures

<Develop branch after Push>

├─Scripts
└─ProjectName
    │  aaa.fbx : [Automatically generated]blend/aaa.FBX export of blend
    │  bbb.fbx : [Automatically generated]blend/bbb.FBX export of blend
    │  ccc.fbx : [Automatically generated]blend/ccc.FBX export of blend
    │
    ├─blend 
    │  │ aaa.blend
    │  │ bbb.blend
    │  │ ccc.blend
    │
    ├─image : [Automatically generated]Directory where the rendered image is located
    └─Textures :Directory to put textures

<Master branch after push>

└─ProjectName
    │  aaa.fbx 
    │  bbb.fbx 
    │  ccc.fbx 
    │
    └─Textures

Place the Blend and texture files in the develop branch and push to Rendered automatically, FBX generated, Check out the FBX and texture files to master.

Development environment

This time on Windows 10

I did it at.

Work procedure

1. Pass Path through Blender

First, pass the Path to Blender.exe. Add the Blender installation directory to the environment variable Path. If you downloaded the installer from the Blender official website and installed it, "C:\Program Files\Blender Foundation\Blender" Will be the installation directory.

How to edit environment variables https://qiita.com/sta/items/6d29da0dc7069ffaae60 I think it will be helpful.

2. Script for rendering

Next, save the following contents in Scripts / render.py as a script for rendering.

import bpy

bpy.context.scene.render.resolution_x = 1920
bpy.context.scene.render.resolution_y = 1080
bpy.context.scene.render.resolution_percentage = 25

path = bpy.context.blend_data.filepath.rstrip(bpy.path.basename(bpy.context.blend_data.filepath)) + "../image/" +  bpy.path.basename(bpy.context.blend_data.filepath).split(".")[0] +".png "
bpy.data.scenes["Scene"].render.filepath = path

bpy.ops.render.render( write_still=True )

As a result, if it is blend / aaa.blend, the rendering result will be saved in image / aaa.png.

Since this time it is a rendering for thumbnail images, the resolution is specified as 25% of 1920x1080.

3. Script for FBX export

Next, as a script for FBX export, save it in Scripts / ExportFBX.py with the following contents.

import bpy,sys

def fbx_export_geometry(arg_filepath='./export.fbx'):
  bpy.ops.export_scene.fbx(
    filepath=arg_filepath,
    object_types={'ARMATURE', 'MESH'},
    bake_anim=False,
  )
  #Type of output target
  #  'EMPTY': Empty
  #  'CAMERA':camera
  #  'LAMP':lamp
  #  'ARMATURE': Armature
  #  'MESH':mesh
  #  'OTHER': Other
  return

#Function execution
path = bpy.context.blend_data.filepath.rstrip(bpy.path.basename(bpy.context.blend_data.filepath)) + "../" +  bpy.path.basename(bpy.context.blend_data.filepath).split(".")[0] +".fbx"
fbx_export_geometry(path)

This will FBX export to aaa.fbx if it is blend / aaa.blend.

Also, here I am FBX exporting only armatures and meshes, excluding cameras and lamps.

4. Script to call two Python scripts

Now, let's prepare a script to call these two Python scripts.

Save it in Scripts / convert.sh with the following contents.

#!/bin/bash

log=$(pwd)/gitPush.sh.log

echo "[$(date)] start" >> $log

echo "[Messeage by convert.sh]cd git top level dir(" `git rev-parse --show-toplevel` ")"
cd  `git rev-parse --show-toplevel`

for raw in $(git log origin/develop..develop --stat | grep ".blend") ; do
	if [ ${raw##*.} = "blend" ]; then
		echo "[Messeage by convert.sh] blend file is ${raw}"
		echo "[Messeage by convert.sh] Start Render.py"
		blender --background ${raw} --python Scripts/Render.py
		echo "[Messeage by convert.sh] Start ExportFBX.py"
		blender --background ${raw} --python Scripts/ExportFBX.py
	fi	
done
echo '[Messeage by convert.sh] git commit -m "Auto Generate FBX/render image"'
git add *.fbx
git add *.png
git commit -am "Auto convert FBX and render image"

There is an echo line for the log, but the content is

  1. Go to Git's top level directory
  2. Get the name of the modified blend file from the git log
  3. Perform image rendering (Render.py) and FBX export (ExportFBX.py) on the modified blend file.
  4. git add the FBX file and rendered png image
  5. git commit

It has become.

Git Hook pre-push settings

Finally, let Git Hook pre-push execute the script you have created so far.

There is a .git directory in the Git repository, but save the shell script in.git / hooks /with the filename" pre-push ". Then, this script will be executed just before Git Push is executed.

You can put the file directly here, but since .git/hooks/ is not under Git monitoring, I put a symbolic link and worked on it.

By the way, how to paste a symbolic link in PowerShell on Windows is the command below.

New-Item -Type SymbolicLink .git/hooks/pre-push -Value Scripts/hooks/pre-push

Save the following contents in the pre-push file.

#!/bin/sh

remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000
 
while read local_ref local_sha remote_ref remote_sha
do
	if [[ "${remote_ref##refs/heads/}" = "develop" ]]; then
		`git rev-parse --show-toplevel`/Scripts/convert.sh
		git checkout master
		git checkout develop `git rev-parse --show-toplevel`'/ProjectName/*.fbx'
		git checkout develop `git rev-parse --show-toplevel`'/ProjectName/Textures/*'
		git commit -m "[Auto commit] Add FBX from develop"

		git checkout develop
		git push origin master
	fi
done

  1. Find out if the branch you're working on is develop
  2. Run <Git top-level directory> /Scripts/convert.sh. (Automatic rendering and FBX export are performed here)
  3. Checkout the texture file and the automatically generated FBX file to the Master branch
  4. git commit master
  5. Set master to git push

It is the contents such as.

With the above, just push the Blend file and texture to the develop branch, and it will be done automatically.

Will be done.

at the end

This time, I tried using Git Hook to create a system that automatically updates FBX when the blend file is updated.

At first I was trying GitHub Actions thinking that I need CI / CD ... but I was worried because GPU is required on the server side when rendering with Blender, but Git Hook to seniors in the circle Was introduced.

As a result, I think we have achieved what we wanted to do, and now we have a compact system that is completed on the client side.

I also tried using the Blender Python script for the first time to call it with Git Hook, but this eliminates the setting error of rendering and FBX export, especially when the lamp and camera are mistakenly included in FBX export and it is read by Unity. The problem of getting crazy is gone.

Until now, I haven't had much motivation for automation, but it was a good opportunity to gain a number of benefits from automation.

Git Hook has various other ignition timings, so I would like to use it conveniently.

References

Recommended Posts

Automatically render Blender and export FBX with Git Hook
HDA distribution from Houdini to export FBX with hierarchy and transforms
Easy modeling with Blender and Python
Automatically search and download YouTube videos with Python
Get git branch name and tag name with python