Skip to content

Commit

Permalink
Multiple materials (#12)
Browse files Browse the repository at this point in the history
* Added support for per-frame material

* Fixed Bake Sequence for single-material sequences

* Start frame, playback speed, frame mode only show after sequence loaded

* Updated README

Closes #10
  • Loading branch information
neverhood311 authored Mar 16, 2018
1 parent 7101c56 commit 6ada248
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 39 deletions.
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Stop-motion-OBJ
A Blender add-on for importing a sequence of meshes as frames

Stop motion OBJ allows you to import a sequence of OBJ (or STL or PLY) files and render them as individual frames. Have a RealFlow animation but want to render it in Blender? This addon is for you! Currently tested for Blender 2.77.1.
Stop motion OBJ allows you to import a sequence of OBJ (or STL or PLY) files and render them as individual frames. Have a RealFlow animation but want to render it in Blender? This addon is for you! Currently tested for Blender 2.79.1.

If you find this add-on helpful, please consider donating to support development:

Expand All @@ -22,9 +22,10 @@ PayPal: https://www.paypal.me/justinj
- Supports shapes with UVs and image textures
- Variable playback speed
- Multiple playback modes
- Object can have materials
- Object can have different materials on each frame
- For instance, you can have a different MTL file for each OBJ file
- Bake sequence
- This allows the sequence to be seen on other computers without installing the addon (in a renderfarm, for example)
- This allows the sequence to be viewed on other computers without installing the addon (in a renderfarm, for example)

### Limitations
- Only absolute filepaths are supported (for now)
Expand All @@ -37,7 +38,7 @@ PayPal: https://www.paypal.me/justinj
- Sequences can now be duplicated, but they share a material. For a duplicate sequence with a different material, you have to re-import the sequence.

## Installing Stop motion OBJ
- Download mesh_sequence_controller.py and move it to Blender's addons folder (something like C:\Program Files\Blender Foundation\Blender\2.77\scripts\addons)
- Download mesh_sequence_controller.py and move it to Blender's addons folder (something like C:\Program Files\Blender Foundation\Blender\2.79\scripts\addons)
- Open Blender and open the Add-ons preferences (File > User Preferences... > Add-ons)
- In the search bar, type 'OBJ' and look for the Stop motion OBJ addon in the list
- Check the box to install it, and click 'Save User Settings'
Expand All @@ -52,15 +53,16 @@ PayPal: https://www.paypal.me/justinj
- Enter the Root Folder by clicking on the folder button and navigating to the folder where the mesh files are stored. **Make sure to UNCHECK ‘Relative Path’**
- In the File Name box, enter a common prefix of the files.
- ex: If you have frame001, frame002, frame003, you could enter ‘frame’, 'fram', or even 'f'
- If your sequence has a different material for each frame, check the "Material per Frame" checkbox. Otherwise, leave it unchecked.
- Click ‘Load Mesh Sequence’ to load.
- Depending on the number of frames, this could take a while.
- Step through a few frames to see the animation.
- You can adjust which frame the animation starts on as well as its playback speed.
- You can also decide what happens before and after the mesh sequence:
- 'Blank' will simply make the object disappear
- 'Blank' will simply make the object disappear after the end of the sequence
- 'Extend' will freeze the first and last frames before and after the mesh sequence, respectively
- 'Repeat' will repeat the animation
- 'Bounce' will play the animation in reverse once the sequence has finished
- Once your sequence is loaded, you can change the shading (smooth or flat) of the entire sequence:
- The shading buttons are found in the Mesh Sequence Settings for the object.
- Note: The normal shading buttons (in the 3D View "Tools" panel) will only affect the current frame, not the entire sequence.
- The shading buttons are found in the Mesh Sequence Settings for the object
- Note: The normal shading buttons (in the 3D View "Tools" panel) will only affect the current frame, not the entire sequence
78 changes: 46 additions & 32 deletions mesh_sequence_controller.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# Stop motion OBJ: A Mesh sequence importer for Blender
# Copyright (C) 2016-2017 Justin Jensen
# Copyright (C) 2016-2018 Justin Jensen
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -23,8 +23,8 @@
"name" : "Stop motion OBJ",
"description": "Import a sequence of OBJ (or STL or PLY) files and display them each as a single frame of animation. This add-on also supports the .STL and .PLY file formats.",
"author": "Justin Jensen",
"version": (0, 1),
"blender": (2, 78, 0),
"version": (0, 2),
"blender": (2, 79, 0),
"location": "View 3D > Add > Mesh > Mesh Sequence",
"warning": "",
"category": "Add Mesh",
Expand Down Expand Up @@ -82,6 +82,12 @@ class MeshSequenceSettings(bpy.types.PropertyGroup):
name='Frame Mode',
default='1')

#material mode (one material total or one material per frame)
perFrameMaterial = bpy.props.BoolProperty(
name='Material per Frame',
default=False
)

#playback speed
speed = bpy.props.FloatProperty(
name='Playback Speed',
Expand Down Expand Up @@ -276,11 +282,13 @@ def setFrameObj(self, _obj, _frameNum):
prev_mesh = _obj.data
#swap the meshes
_obj.data = self.getMesh(_obj, idx)
#if the previous mesh had a material, copy it to the new one
if(len(prev_mesh.materials) > 0):
prev_material = prev_mesh.materials[0]
_obj.data.materials.clear()
_obj.data.materials.append(prev_material)
# If this object doesn't have materials for each frame
if(_obj.mesh_sequence_settings.perFrameMaterial == False):
#if the previous mesh had a material, copy it to the new one
if(len(prev_mesh.materials) > 0):
prev_material = prev_mesh.materials[0]
_obj.data.materials.clear()
_obj.data.materials.append(prev_material)

#iterate over the meshes in the sequence and set their shading to smooth or flat
def shadeSequence(self, _obj, _smooth):
Expand Down Expand Up @@ -335,8 +343,6 @@ def bakeSequence(self, _obj):

#create a dictionary mapping meshes to new objects, meshToObject
meshToObject = {}
#create a placeholder for the object's material, objMaterial
objMaterial = None

meshNames = _obj.mesh_sequence_settings.meshNames.split('/')
#for each mesh (including the empty mesh):
Expand All @@ -349,9 +355,6 @@ def bakeSequence(self, _obj):
scn.objects.link(tmpObj)
#remove the fake user from the mesh
mesh.use_fake_user = False
#if the mesh has a material, store this in objMaterial
if(len(mesh.materials) > 0):
objMaterial = mesh.materials[0]
#add a dictionary entry to meshToObject, the mesh => the object
meshToObject[mesh] = tmpObj
#in the object, add keyframes at frames 0 and the last frame of the animation:
Expand All @@ -366,14 +369,21 @@ def bakeSequence(self, _obj):
#set the empty object as this object's parent
tmpObj.parent = containerObj

#if objMaterial was set:
if(objMaterial != None):
#If this is a single-material sequence, make sure the material is copied to the whole sequence
#This assumes that the first mesh in the sequence has a material
if(_obj.mesh_sequence_settings.perFrameMaterial == False):
#grab the materials from the first frame
objMaterials = bpy.data.meshes[meshNames[1]].materials
#for each mesh:
for meshName in meshNames:
iterMeshes = iter(meshNames)
next(iterMeshes) #skip the emptyMesh
next(iterMeshes) #skip the first mesh (we'll copy the material from this one into the rest of them)
for meshName in iterMeshes:
mesh = bpy.data.meshes[meshName]
#set the material to objMaterial
mesh.materials.clear()
mesh.materials.append(objMaterial)
for material in objMaterials:
mesh.materials.append(material)

#for each frame of the animation:
for frameNum in range(scn.frame_start, scn.frame_end + 1):
Expand Down Expand Up @@ -541,31 +551,35 @@ def draw(self, context):
row = layout.row()
row.prop(objSettings, "fileFormat")

#material mode (one material total or one material per frame)
row = layout.row()
row.prop(objSettings, "perFrameMaterial")

#button for loading
row = layout.row()
row.operator("ms.load_mesh_sequence")

#start frame
row = layout.row()
row.prop(objSettings, "startFrame")

#frame mode
row = layout.row()
row.prop(objSettings, "frameMode")

#playback speed
row = layout.row()
row.prop(objSettings, "speed")

#Show the shading buttons only if a sequence has been loaded
if(objSettings.loaded == True):
#start frame
row = layout.row()
row.prop(objSettings, "startFrame")

#frame mode
row = layout.row()
row.prop(objSettings, "frameMode")

#playback speed
row = layout.row()
row.prop(objSettings, "speed")

#Show the shading buttons only if a sequence has been loaded
layout.row().separator()
row = layout.row(align=True)
row.label("Shading:")
row.operator("ms.batch_shade_smooth")
row.operator("ms.batch_shade_flat")
#Show the Bake Sequence button only if a sequence has been loaded
if(objSettings.loaded == True):
#Bake Sequence button
layout.row().separator()
row = layout.row()
box = row.box()
Expand Down

0 comments on commit 6ada248

Please sign in to comment.