That absolutely does it, creating a DAT file that works perfectly in Blender and leaving the original files as they were. Straight off the top, thank you very much, that is truly amazing and I now see I can eventually create such ideas with speed and accuracy.
I will continue reading the books and learning Python because I only read about the WITH keyword yesterday, so am well behind understanding what you have done, but I will get it figured out, that is not an issue.
For additional fun and info, here is a screenshot of Blender showing the DAT importer GUI on the left of the window with the head (and the test Final.DAT result with accurate timeline plotting below)
[Image: datImport.jpg]
What I want to do with the importer is have it so:
I can select a folder (Current addon only selects a file)
Every DAT in the folder gets the options GUI in a stack for individual control but there is a Global option box with a radio button that turns off individual options if such fine tuning is not needed.
Options can be turned on per DAT file even with Global options controlling remainder.
There is one master PLOT KEYS TO TIMELINE button that iterates the entire stack.
Offset is not needed if filename technique is used, but if not using filename, offset option is required per DAT file.
There is one more option that would be handy but confusing to explain. Here is an attempt. Audacity is what I export the audio clips from. Audacity only displays 24 or 30 frames per second markers. The Papagayo and Blender project may be in a different frame rate, such as 12 frames per second or even 29.97fps. It is fast to note the numbers Audacity displays when exporting the audio clips and skip the little bit of math. Once the DAT is created with Papagayo and then imported into Blender, it would be useful to globally set the Audacity framerate the audio was sourced at, enter the frame # Audacity displayed, and let the Blender addon calculate the actual offset based off the project's fps. This would actually be useful even using the filename technique, as Audacity's frame number could be the filename, allowing for the project's fps to be determined later.
The following is my bastardized version of the Blender addon code, posted simply for completeness of this project's original plan. Hey, it got me studying Python!
Original Importer found here
https://wiki.blender.org/index.php/Exten...c_Importer
bl_info = {
"name": "TREPANING",
"author": "blazilla",
"version": (0, 5, 1),
"blender": (2, 77, 0),
"location": "3D window > Tool Shelf",
"description": "Plot Moho (Papagayo dat) file to frames",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Import-Export"}
import bpy, re, os
from bpy.props import *
from bpy.props import IntProperty, FloatProperty, StringProperty
global lastPhoneme
lastPhoneme="nothing"
datFile = os.listdir('C:\\dat')
# -------------------------------------------------------------------------------
# reading imported file & creating keys
def lipsyncer():
obj = bpy.context.object
scn = bpy.context.scene
f = open(scn.fpath) # importing file
f.readline() # reading the 1st line that we don"t need
for line in f:
# removing new lines
lsta = re.split("\n+", line)
# building a list of frames & shapes indexes
lst = re.split(":? ", lsta[0])# making a list of a frame & number
frame = int(lst[0])
for key in obj.data.shape_keys.key_blocks:
if lst[1] == key.name:
createShapekey(key.name, frame)
# creating keys with offset and eases for a phonem @ the frame
def createShapekey(phoneme, frame):
global lastPhoneme
scn = bpy.context.scene
obj = bpy.context.object
objSK = obj.data.shape_keys
offst = scn.offset # offset value
skVlu = scn.skscale # shape key value
#in case of Papagayo format
if scn.regMenuTypes.enumFileTypes == '0' :
frmIn = scn.easeIn # ease in value
frmOut = scn.easeOut # ease out value
hldIn = scn.holdGap # holding time value
# inserting the In key only when phonem change or when blinking
if lastPhoneme!=phoneme or eval(scn.regMenuTypes.enumModeTypes) == 1:
objSK.key_blocks[phoneme].value=0.0
objSK.key_blocks[phoneme].keyframe_insert("value",
-1, offst+frame-frmIn, "Lipsync")
objSK.key_blocks[phoneme].value=skVlu
objSK.key_blocks[phoneme].keyframe_insert("value",
-1, offst+frame, "Lipsync")
objSK.key_blocks[phoneme].value=skVlu
objSK.key_blocks[phoneme].keyframe_insert("value",
-1, offst+frame+hldIn, "Lipsync")
objSK.key_blocks[phoneme].value=0.0
objSK.key_blocks[phoneme].keyframe_insert("value",
-1, offst+frame+hldIn+frmOut, "Lipsync")
lastPhoneme = phoneme
# lipsyncer operation start
class btn_lipsyncer(bpy.types.Operator):
bl_idname = 'lipsync.go'
bl_label = 'Start Processing'
bl_description = 'Plots the voice file keys to timeline'
def execute(self, context):
scn = context.scene
obj = context.active_object
# testing if object is valid
if obj!=None:
if obj.type=="MESH":
if obj.data.shape_keys!=None:
if scn.fpath!='': lipsyncer()
else: print ("select a Moho file")
else: print("No shape keys")
else: print ("Object is not a mesh")
else: print ("Select object")
return {'FINISHED'}
#defining custom enumeratos
class menuTypes(bpy.types.PropertyGroup):
enumFileTypes = EnumProperty(items =(('0', 'Papagayo', ''),
),
name = 'Choose FileType',
default = '0')
enumModeTypes = EnumProperty(items =(('0', 'Lipsyncer',''),
),
name = 'The Mode is',
default = '0')
# drawing the user interface
class LipSyncUI(bpy.types.Panel):
bl_space_type = "VIEW_3D"
bl_region_type = "TOOL_PROPS"
bl_label = "Dat TREPANING LipSync Importer"
newType= bpy.types.Scene
newType.fpath = StringProperty(name="Import File ", description="Select your voice file", subtype="FILE_PATH")
newType.skscale = FloatProperty(description="Smoothing shape key values", min=0.1, max=1.0, default=0.8)
newType.offset = IntProperty(description="Offset your frames", default=0)
newType.easeIn = IntProperty(description="Smoothing In curve", min=1, default=2)
newType.easeOut = IntProperty(description="Smoothing Out curve", min=1, default=2)
newType.holdGap = IntProperty(description="Holding for slow keys", min=0, default=3)
def draw(self, context):
obj = bpy.context.active_object
scn = bpy.context.scene
layout = self.layout
col = layout.column()
# showing the current object type
if obj != None:
if obj.type == "MESH":
split = col.split(align=True)
split.label(text="The active object is: ", icon="OBJECT_DATA")
split.label(obj.name, icon="EDITMODE_HLT")
else:
col.label(text="The active object is not a Mesh!", icon="OBJECT_DATA")
else:
layout.label(text="No object is selected", icon="OBJECT_DATA")
col.row().prop(scn.regMenuTypes, 'enumModeTypes')
col.separator()
# the lipsyncer panel
if scn.regMenuTypes.enumModeTypes == '0':
# Papagayo panel
col.prop(context.scene, "fpath")
split = col.split(align=True)
split.label("Frame Offset :")
split.prop(context.scene, "offset")
#split = col.split(align=True)
# split.label("Key Value :")
# split.prop(context.scene, "skscale")
split = col.split(align=True)
split.prop(context.scene, "easeIn", "Ease In")
split.prop(context.scene, "holdGap", "Hold Gap")
split.prop(context.scene, "easeOut", "Ease Out")
col.operator('lipsync.go', text='Plot Keys to the Timeline')
# clearing vars
def clear_properties():
# can happen on reload
if bpy.context.scene is None:
return
props = ["fpath", "skscale", "offset", "easeIn", "easeOut", "holdGap"]
for p in props:
if p in bpy.types.Scene.bl_rna.properties:
exec("del bpy.types.Scene."+p)
if p in bpy.context.scene:
del bpy.context.scene[p]
# registering the script
def register():
bpy.utils.register_module(__name__)
bpy.types.Scene.regMenuTypes = PointerProperty(type = menuTypes)
def unregister():
bpy.utils.unregister_module(__name__)
del bpy.context.scene.regMenuTypes
clear_properties()
if __name__ == "__main__":
register()