2 new python functions for the NLA.

action.getChannelNames() and action.renameChannel(from, to)

editaction.c - maximum new name length was too short
This commit is contained in:
Campbell Barton 2007-04-20 23:33:56 +00:00
parent cbfeab7e45
commit d76778f0e4
4 changed files with 231 additions and 223 deletions

@ -152,16 +152,37 @@ def write_header(file):
def write_scene(file, sce, world):
def write_camera_switch():
def write_object_tx(ob, loc):
'''
We have loc to set the location if non blender objects that have a location
'''
if not loc:
if ob: loc = tuple(ob.getLocation('worldspace'))
else: loc = 0,0,0
file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % loc)
if ob:
file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % tuple([degrees(a) for a in ob.getEuler('worldspace')]))
file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % tuple(ob.getSize('worldspace')))
else:
file.write('''
Property: "Lcl Rotation", "Lcl Rotation", "A+",0,0,0
Property: "Lcl Scaling", "Lcl Scaling", "A+",1,1,1''')
def write_object_props(ob=None, loc=None):
# if the type is 0 its an empty otherwise its a mesh
# only difference at the moment is one has a color
file.write('''
Model: "Model::Camera Switcher", "CameraSwitcher" {
Version: 232
Properties60: {
Property: "QuaternionInterpolate", "bool", "",0
Property: "Visibility", "Visibility", "A+",0
Property: "Lcl Translation", "Lcl Translation", "A+",0,0,0
Property: "Lcl Rotation", "Lcl Rotation", "A+",0,0,0
Property: "Lcl Scaling", "Lcl Scaling", "A+",1,1,1
Property: "Visibility", "Visibility", "A+",1''')
write_object_tx(ob, loc)
file.write('''
Property: "RotationOffset", "Vector3D", "",0,0,0
Property: "RotationPivot", "Vector3D", "",0,0,0
Property: "ScalingOffset", "Vector3D", "",0,0,0
@ -222,9 +243,25 @@ def write_scene(file, sce, world):
Property: "GeometricScaling", "Vector3D", "",1,1,1
Property: "LookAtProperty", "object", ""
Property: "UpVectorProperty", "object", ""
Property: "Show", "bool", "",0
Property: "Show", "bool", "",1
Property: "NegativePercentShapeSupport", "bool", "",1
Property: "DefaultAttributeIndex", "int", "",0
Property: "DefaultAttributeIndex", "int", "",0''')
if ob:
# Only mesh objects have color
file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8')
file.write('\n\t\t\tProperty: "Size", "double", "",100')
file.write('\n\t\t\tProperty: "Look", "enum", "",1')
file.write('\n\t\t}\n')
def write_camera_switch():
file.write('''
Model: "Model::Camera Switcher", "CameraSwitcher" {
Version: 232'''
write_object_props()
file.write('''
Property: "Color", "Color", "A",0.8,0.8,0.8
Property: "Camera Index", "Integer", "A+",100
}
@ -243,75 +280,8 @@ def write_scene(file, sce, world):
def write_camera(name, loc, near, far, proj_type, up):
file.write('\n\tModel: "Model::%s", "Camera" {\n' % name )
file.write('\t\tVersion: 232\n')
file.write('\t\tProperties60: {\n')
file.write('\t\t\tProperty: "QuaternionInterpolate", "bool", "",0\n')
file.write('\t\t\tProperty: "Visibility", "Visibility", "A+",0\n')
file.write('\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.6f,%.6f,%.6f\n' % loc)
file.write('\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",0,0,0\n')
file.write('\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",1,1,1\n')
file.write('\t\t\tProperty: "RotationOffset", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "RotationPivot", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "ScalingOffset", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "ScalingPivot", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "TranslationActive", "bool", "",0\n')
file.write('\t\t\tProperty: "TranslationMin", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "TranslationMax", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "TranslationMinX", "bool", "",0\n')
file.write('\t\t\tProperty: "TranslationMinY", "bool", "",0\n')
file.write('\t\t\tProperty: "TranslationMinZ", "bool", "",0\n')
file.write('\t\t\tProperty: "TranslationMaxX", "bool", "",0\n')
file.write('\t\t\tProperty: "TranslationMaxY", "bool", "",0\n')
file.write('\t\t\tProperty: "TranslationMaxZ", "bool", "",0\n')
file.write('\t\t\tProperty: "RotationOrder", "enum", "",0\n')
file.write('\t\t\tProperty: "RotationSpaceForLimitOnly", "bool", "",0\n')
file.write('\t\t\tProperty: "AxisLen", "double", "",10\n')
file.write('\t\t\tProperty: "PreRotation", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "PostRotation", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "RotationActive", "bool", "",0\n')
file.write('\t\t\tProperty: "RotationMin", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "RotationMax", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "RotationMinX", "bool", "",0\n')
file.write('\t\t\tProperty: "RotationMinY", "bool", "",0\n')
file.write('\t\t\tProperty: "RotationMinZ", "bool", "",0\n')
file.write('\t\t\tProperty: "RotationMaxX", "bool", "",0\n')
file.write('\t\t\tProperty: "RotationMaxY", "bool", "",0\n')
file.write('\t\t\tProperty: "RotationMaxZ", "bool", "",0\n')
file.write('\t\t\tProperty: "RotationStiffnessX", "double", "",0\n')
file.write('\t\t\tProperty: "RotationStiffnessY", "double", "",0\n')
file.write('\t\t\tProperty: "RotationStiffnessZ", "double", "",0\n')
file.write('\t\t\tProperty: "MinDampRangeX", "double", "",0\n')
file.write('\t\t\tProperty: "MinDampRangeY", "double", "",0\n')
file.write('\t\t\tProperty: "MinDampRangeZ", "double", "",0\n')
file.write('\t\t\tProperty: "MaxDampRangeX", "double", "",0\n')
file.write('\t\t\tProperty: "MaxDampRangeY", "double", "",0\n')
file.write('\t\t\tProperty: "MaxDampRangeZ", "double", "",0\n')
file.write('\t\t\tProperty: "MinDampStrengthX", "double", "",0\n')
file.write('\t\t\tProperty: "MinDampStrengthY", "double", "",0\n')
file.write('\t\t\tProperty: "MinDampStrengthZ", "double", "",0\n')
file.write('\t\t\tProperty: "MaxDampStrengthX", "double", "",0\n')
file.write('\t\t\tProperty: "MaxDampStrengthY", "double", "",0\n')
file.write('\t\t\tProperty: "MaxDampStrengthZ", "double", "",0\n')
file.write('\t\t\tProperty: "PreferedAngleX", "double", "",0\n')
file.write('\t\t\tProperty: "PreferedAngleY", "double", "",0\n')
file.write('\t\t\tProperty: "PreferedAngleZ", "double", "",0\n')
file.write('\t\t\tProperty: "InheritType", "enum", "",0\n')
file.write('\t\t\tProperty: "ScalingActive", "bool", "",0\n')
file.write('\t\t\tProperty: "ScalingMin", "Vector3D", "",1,1,1\n')
file.write('\t\t\tProperty: "ScalingMax", "Vector3D", "",1,1,1\n')
file.write('\t\t\tProperty: "ScalingMinX", "bool", "",0\n')
file.write('\t\t\tProperty: "ScalingMinY", "bool", "",0\n')
file.write('\t\t\tProperty: "ScalingMinZ", "bool", "",0\n')
file.write('\t\t\tProperty: "ScalingMaxX", "bool", "",0\n')
file.write('\t\t\tProperty: "ScalingMaxY", "bool", "",0\n')
file.write('\t\t\tProperty: "ScalingMaxZ", "bool", "",0\n')
file.write('\t\t\tProperty: "GeometricTranslation", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "GeometricRotation", "Vector3D", "",0,0,0\n')
file.write('\t\t\tProperty: "GeometricScaling", "Vector3D", "",1,1,1\n')
file.write('\t\t\tProperty: "LookAtProperty", "object", ""\n')
file.write('\t\t\tProperty: "UpVectorProperty", "object", ""\n')
file.write('\t\t\tProperty: "Show", "bool", "",0\n')
file.write('\t\t\tProperty: "NegativePercentShapeSupport", "bool", "",1\n')
file.write('\t\t\tProperty: "DefaultAttributeIndex", "int", "",0\n')
write_object_props(None, loc)
file.write('\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8\n')
file.write('\t\t\tProperty: "Roll", "Roll", "A+",0\n')
file.write('\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",40\n')
@ -399,105 +369,70 @@ def write_scene(file, sce, world):
def write_camera_default():
# This sucks but to match FBX converter its easier to
# write the cameras though they are not needed.
write_camera('Producer Perspective', (0,71.3,287.5), 10, 4000, 0, (0,1,0))
write_camera('Producer Top', (0,4000,0), 1, 30000, 1, (0,0,-1))
write_camera('Producer Bottom', (0,-4000,0), 1, 30000, 1, (0,0,-1))
write_camera('Producer Front', (0,0,4000), 1, 30000, 1, (0,1,0))
write_camera('Producer Back', (0,0,-4000), 1, 30000, 1, (0,1,0))
write_camera('Producer Right', (4000,0,0), 1, 30000, 1, (0,1,0))
write_camera('Producer Left', (-4000,0,0), 1, 30000, 1, (0,1,0))
def write_object_props(ob):
# if the type is 0 its an empty otherwise its a mesh
# only difference at the moment is one has a color
file.write('''
Properties60: {
Property: "QuaternionInterpolate", "bool", "",0
Property: "Visibility", "Visibility", "A+",1''')
if ob:
file.write('\n\t\t\tProperty: "Lcl Translation", "Lcl Translation", "A+",%.15f,%.15f,%.15f' % tuple(ob.getLocation('worldspace')))
file.write('\n\t\t\tProperty: "Lcl Rotation", "Lcl Rotation", "A+",%.15f,%.15f,%.15f' % tuple([degrees(a) for a in ob.getEuler('worldspace')]))
file.write('\n\t\t\tProperty: "Lcl Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % tuple(ob.getSize('worldspace')))
else:
file.write('''
Property: "Lcl Translation", "Lcl Translation", "A+",0,0,0
Property: "Lcl Rotation", "Lcl Rotation", "A+",0,0,0
Property: "Lcl Scaling", "Lcl Scaling", "A+",1,1,1''')
file.write('''
Property: "RotationOffset", "Vector3D", "",0,0,0
Property: "RotationPivot", "Vector3D", "",0,0,0
Property: "ScalingOffset", "Vector3D", "",0,0,0
Property: "ScalingPivot", "Vector3D", "",0,0,0
Property: "TranslationActive", "bool", "",0
Property: "TranslationMin", "Vector3D", "",0,0,0
Property: "TranslationMax", "Vector3D", "",0,0,0
Property: "TranslationMinX", "bool", "",0
Property: "TranslationMinY", "bool", "",0
Property: "TranslationMinZ", "bool", "",0
Property: "TranslationMaxX", "bool", "",0
Property: "TranslationMaxY", "bool", "",0
Property: "TranslationMaxZ", "bool", "",0
Property: "RotationOrder", "enum", "",0
Property: "RotationSpaceForLimitOnly", "bool", "",0
Property: "AxisLen", "double", "",10
Property: "PreRotation", "Vector3D", "",0,0,0
Property: "PostRotation", "Vector3D", "",0,0,0
Property: "RotationActive", "bool", "",0
Property: "RotationMin", "Vector3D", "",0,0,0
Property: "RotationMax", "Vector3D", "",0,0,0
Property: "RotationMinX", "bool", "",0
Property: "RotationMinY", "bool", "",0
Property: "RotationMinZ", "bool", "",0
Property: "RotationMaxX", "bool", "",0
Property: "RotationMaxY", "bool", "",0
Property: "RotationMaxZ", "bool", "",0
Property: "RotationStiffnessX", "double", "",0
Property: "RotationStiffnessY", "double", "",0
Property: "RotationStiffnessZ", "double", "",0
Property: "MinDampRangeX", "double", "",0
Property: "MinDampRangeY", "double", "",0
Property: "MinDampRangeZ", "double", "",0
Property: "MaxDampRangeX", "double", "",0
Property: "MaxDampRangeY", "double", "",0
Property: "MaxDampRangeZ", "double", "",0
Property: "MinDampStrengthX", "double", "",0
Property: "MinDampStrengthY", "double", "",0
Property: "MinDampStrengthZ", "double", "",0
Property: "MaxDampStrengthX", "double", "",0
Property: "MaxDampStrengthY", "double", "",0
Property: "MaxDampStrengthZ", "double", "",0
Property: "PreferedAngleX", "double", "",0
Property: "PreferedAngleY", "double", "",0
Property: "PreferedAngleZ", "double", "",0
Property: "InheritType", "enum", "",0
Property: "ScalingActive", "bool", "",0
Property: "ScalingMin", "Vector3D", "",1,1,1
Property: "ScalingMax", "Vector3D", "",1,1,1
Property: "ScalingMinX", "bool", "",0
Property: "ScalingMinY", "bool", "",0
Property: "ScalingMinZ", "bool", "",0
Property: "ScalingMaxX", "bool", "",0
Property: "ScalingMaxY", "bool", "",0
Property: "ScalingMaxZ", "bool", "",0
Property: "GeometricTranslation", "Vector3D", "",0,0,0
Property: "GeometricRotation", "Vector3D", "",0,0,0
Property: "GeometricScaling", "Vector3D", "",1,1,1
Property: "LookAtProperty", "object", ""
Property: "UpVectorProperty", "object", ""
Property: "Show", "bool", "",1
Property: "NegativePercentShapeSupport", "bool", "",1
Property: "DefaultAttributeIndex", "int", "",0''')
if ob:
# Only mesh objects have color
file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8')
file.write('\n\t\t\tProperty: "Size", "double", "",100')
file.write('\n\t\t\tProperty: "Look", "enum", "",1')
file.write('\n\t\t}\n')
write_camera('Producer Perspective', (0,71.3,287.5), 10, 4000, 0, (0,1,0))
write_camera('Producer Top', (0,4000,0), 1, 30000, 1, (0,0,-1))
write_camera('Producer Bottom', (0,-4000,0), 1, 30000, 1, (0,0,-1))
write_camera('Producer Front', (0,0,4000), 1, 30000, 1, (0,1,0))
write_camera('Producer Back', (0,0,-4000), 1, 30000, 1, (0,1,0))
write_camera('Producer Right', (4000,0,0), 1, 30000, 1, (0,1,0))
write_camera('Producer Left', (-4000,0,0), 1, 30000, 1, (0,1,0))
def write_light(ob, name):
light = ob.data
file.write('\n\tModel: "Model::%s", "Light" {' % name)
file.write('\n\t\tVersion: 232')
write_object_props(ob)
# Why are these values here twice?????? - oh well, follow the holy sdk's output
# Blender light types match FBX's, funny coincidence, we just need to
# be sure that all unsupported types are made into a point light
#ePOINT,
#eDIRECTIONAL
#eSPOT
light_type = light.type
if light_type > 3: light_type = 0
file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1')
file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1')
file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0')
file.write('\n\t\t\tProperty: "GoboProperty", "object", ""')
file.write('\n\t\t\tProperty: "Color", "Color", "A+",1,1,1')
file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (light.energy*100))
file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % light.spotSize)
file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
file.write('\n\t\t\tProperty: "Color", "Color", "A",%.2f,%.2f,%.2f' % tuple(light.col))
file.write('\n\t\t\tProperty: "Intensity", "Intensity", "A+",%.2f' % (light.energy*100))
file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % light.spotSize)
file.write('\n\t\t\tProperty: "Fog", "Fog", "A+",50')
file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1')
file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1')
file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0')
file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
file.write('\n\t\t\tProperty: "GoboProperty", "object", ""')
file.write('\n\t\t\tProperty: "DecayType", "enum", "",0')
file.write('\n\t\t\tProperty: "DecayStart", "double", "",%.2f' % light.dist)
file.write('\n\t\t\tProperty: "EnableNearAttenuation", "bool", "",0')
file.write('\n\t\t\tProperty: "NearAttenuationStart", "double", "",0')
file.write('\n\t\t\tProperty: "NearAttenuationEnd", "double", "",0')
file.write('\n\t\t\tProperty: "EnableFarAttenuation", "bool", "",0')
file.write('\n\t\t\tProperty: "FarAttenuationStart", "double", "",0')
file.write('\n\t\t\tProperty: "FarAttenuationEnd", "double", "",0')
file.write('\n\t\t\tProperty: "CastShadows", "bool", "",0')
file.write('\n\t\t\tProperty: "ShadowColor", "ColorRGBA", "",0,0,0,1')
file.write('\n\t\t}')
file.write('\n\t\tMultiLayer: 0')
file.write('\n\t\tMultiTake: 0')
file.write('\n\t\tShading: Y')
file.write('\n\t\tCulling: "CullingOff"')
file.write('\n\t\tTypeFlags: "Light"')
file.write('\n\t\tGeometryVersion: 124')
file.write('\n\t}')
# Material Settings
if world:
@ -658,45 +593,54 @@ def write_scene(file, sce, world):
Cropping: 0,0,0,0
}''')
objects = []
ob_meshes = []
ob_lights = []
materials = {}
textures = {}
armatures = [] # We should export standalone armatures also
armatures_totbones = 0 # we need this because each bone is a model
for ob in sce.objects.context:
if ob.type == 'Mesh': me = ob.getData(mesh=1)
else: me = BPyMesh.getMeshFromObject(ob)
ob_type = ob.type
if me:
mats = me.materials
for mat in mats:
# 2.44 use mat.lib too for uniqueness
if mat: materials[mat.name] = mat
if ob_type == 'Lamp':
ob_lights.append((sane_obname(ob), ob))
else:
if ob_type == 'Mesh': me = ob.getData(mesh=1)
else: me = BPyMesh.getMeshFromObject(ob)
if me.faceUV:
uvlayer_orig = me.activeUVLayer
for uvlayer in me.getUVLayerNames():
me.activeUVLayer = uvlayer
for f in me.faces:
img = f.image
if img: textures[img.name] = img
me.activeUVLayer = uvlayer_orig
arm = BPyObject.getObjectArmature(ob)
if arm:
armname = sane_armname(arm)
bones = arm.bones.values()
armatures_totbones += len(bones)
armatures.append((arm, armname, bones))
else:
armname = None
#### me.transform(ob.matrixWorld) # Export real ob coords.
#### High Quality, not realy needed for now.
#BPyMesh.meshCalcNormals(me) # high quality normals nice for realtime engines.
objects.append( (sane_obname(ob), ob, me, mats, arm, armname) )
if me:
mats = me.materials
for mat in mats:
# 2.44 use mat.lib too for uniqueness
if mat: materials[mat.name] = mat
if me.faceUV:
uvlayer_orig = me.activeUVLayer
for uvlayer in me.getUVLayerNames():
me.activeUVLayer = uvlayer
for f in me.faces:
img = f.image
if img: textures[img.name] = img
me.activeUVLayer = uvlayer_orig
arm = BPyObject.getObjectArmature(ob)
if arm:
armname = sane_armname(arm)
bones = arm.bones.values()
armatures_totbones += len(bones)
armatures.append((arm, armname, bones))
else:
armname = None
#### me.transform(ob.matrixWorld) # Export real ob coords.
#### High Quality, not realy needed for now.
#BPyMesh.meshCalcNormals(me) # high quality normals nice for realtime engines.
ob_meshes.append( (sane_obname(ob), ob, me, mats, arm, armname) )
del ob_type
materials = [(sane_matname(mat), mat) for mat in materials.itervalues()]
textures = [(sane_texname(img), img) for img in textures.itervalues()]
@ -729,17 +673,17 @@ def write_scene(file, sce, world):
Definitions: {
Version: 100
Count: %i''' % (1+1+camera_count+len(objects)+len(armatures)+armatures_totbones+len(materials)+(len(textures)*2))) # add 1 for the root model 1 for global settings
Count: %i''' % (1+1+camera_count+len(ob_meshes)+len(ob_lights)+len(armatures)+armatures_totbones+len(materials)+(len(textures)*2))) # add 1 for the root model 1 for global settings
file.write('''
ObjectType: "Model" {
Count: %i
}''' % (1+camera_count+len(objects)+len(armatures)+armatures_totbones)) # add 1 for the root model
}''' % (1+camera_count+len(ob_meshes)+len(ob_lights)+len(armatures)+armatures_totbones)) # add 1 for the root model
file.write('''
ObjectType: "Geometry" {
Count: %i
}''' % len(objects))
}''' % len(ob_meshes))
if materials:
file.write('''
@ -778,7 +722,7 @@ Objects: {''')
file.write('''
Model: "Model::blend_root", "Null" {
Version: 232''')
write_object_props(None)
write_object_props()
file.write(\
''' MultiLayer: 0
MultiTake: 1
@ -786,9 +730,12 @@ Objects: {''')
Culling: "CullingOff"
TypeFlags: "Null"
}''')
for obname, ob, me, mats, arm, armname in objects:
for obname, ob in ob_lights:
write_light(ob, obname)
for obname, ob, me, mats, arm, armname in ob_meshes:
file.write('\n\tModel: "Model::%s", "Mesh" {\n' % sane_obname(ob))
file.write('\t\tVersion: 232') # newline is added in write_object_props
write_object_props(ob)
@ -906,9 +853,6 @@ Objects: {''')
# Write UV and texture layers.
uvlayers = []
if me.faceUV:
@ -1164,8 +1108,10 @@ Relations: {
''')
file.write('\tModel: "Model::blend_root", "Null" {\n\t}\n')
for obname, ob in ob_lights:
file.write('\tModel: "Model::%s", "Light" {\n\t}\n' % obname)
for obname, ob, me, mats, arm, armname in objects:
for obname, ob, me, mats, arm, armname in ob_meshes:
file.write('\tModel: "Model::%s", "Mesh" {\n\t}\n' % obname)
file.write(''' Model: "Model::Producer Perspective", "Camera" {
@ -1207,16 +1153,19 @@ Connections: {
# write the fake root node
file.write('\tConnect: "OO", "Model::blend_root", "Model::Scene"\n')
for obname, ob, me, mats, arm, armname in objects:
for obname, ob in ob_lights:
file.write('\tConnect: "OO", "Model::%s", "Model::blend_root"\n' % obname)
for obname, ob, me, mats, arm, armname in objects:
for obname, ob, me, mats, arm, armname in ob_meshes:
file.write('\tConnect: "OO", "Model::%s", "Model::blend_root"\n' % obname)
for obname, ob, me, mats, arm, armname in ob_meshes:
# Connect all materials to all objects, not good form but ok for now.
for mat in mats:
file.write(' Connect: "OO", "Material::%s", "Model::%s"\n' % (sane_matname(mat), obname))
if textures:
for obname, ob, me, mats, arm, armname in objects:
for obname, ob, me, mats, arm, armname in ob_meshes:
for texname, tex in textures:
file.write('\tConnect: "OO", "Texture::%s", "Model::%s"\n' % (texname, obname))

@ -88,6 +88,8 @@ struct PyMethodDef M_NLA_methods[] = {
static PyObject *Action_setActive( BPy_Action * self, PyObject * args );
static PyObject *Action_getFrameNumbers(BPy_Action *self);
static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * args );
static PyObject *Action_getChannelNames( BPy_Action * self );
static PyObject *Action_renameChannel( BPy_Action * self, PyObject * args );
static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * args );
static PyObject *Action_removeChannel( BPy_Action * self, PyObject * args );
static PyObject *Action_getAllChannelIpos( BPy_Action * self );
@ -107,6 +109,10 @@ static PyMethodDef BPy_Action_methods[] = {
"() - get the frame numbers at which keys have been inserted"},
{"getChannelIpo", ( PyCFunction ) Action_getChannelIpo, METH_VARARGS,
"(str) -get the Ipo from a named action channel in this action"},
{"getChannelNames", ( PyCFunction ) Action_getChannelNames, METH_NOARGS,
"() -get the channel names for this action"},
{"renameChannel", ( PyCFunction ) Action_renameChannel, METH_VARARGS,
"(from, to) -rename the channel from string to string"},
{"verifyChannel", ( PyCFunction ) Action_verifyChannel, METH_VARARGS,
"(str) -verify the channel in this action"},
{"removeChannel", ( PyCFunction ) Action_removeChannel, METH_VARARGS,
@ -283,6 +289,44 @@ static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * args )
return Ipo_CreatePyObject( chan->ipo );
}
static PyObject *Action_getChannelNames( BPy_Action * self )
{
PyObject *list = PyList_New( BLI_countlist(&(self->action->chanbase)) );
bActionChannel *chan = NULL;
int index=0;
for( chan = self->action->chanbase.first; chan; chan = chan->next ) {
PyList_SetItem( list, index, PyString_FromString(chan->name) );
index++;
}
return list;
}
static PyObject *Action_renameChannel( BPy_Action * self, PyObject * args )
{
char *chanFrom, *chanTo;
bActionChannel *chan;
if( !PyArg_ParseTuple( args, "ss", &chanFrom, &chanTo ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"2 strings expected" );
chan = get_action_channel( self->action, chanFrom );
if( !chan )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"no channel with that name" );
if (strlen(chanTo) > 31)
return EXPP_ReturnPyObjError( PyExc_ValueError,
"new name greater then 31 characters long" );
if (get_action_channel( self->action, chanTo ))
return EXPP_ReturnPyObjError( PyExc_ValueError,
"channel target name alredy exists" );
strcpy(chan->name, chanTo);
Py_RETURN_NONE;
}
/*----------------------------------------------------------------------*/
static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * args )
{

@ -109,6 +109,21 @@ class Action:
@return: the Ipos for all the channels in the action
"""
def getChannelNames():
"""
Returns a list of channel names
@rtype: list
@return: the channel names that match bone and constraint names.
"""
def renameChannel(nameFrom, nameTo):
"""
rename an existing channel to a new name.
if the nameFrom channel dosnt exist or the nameTo exists, an error will be raised.
@return: None
"""
import id_generics
Action.__doc__ += id_generics.attributes

@ -2964,8 +2964,8 @@ static void clever_achannel_names(short *mval)
strcpy(str, achan->name);
protect= (achan->flag & ACHAN_PROTECTED);
expand = (achan->flag & ACHAN_EXPANDED);
add_numbut(but++, TEX, "ActChan: ", 0, 24, str, "Name of Action Channel");
add_numbut(but++, TEX, "ActChan: ", 0, 31, str, "Name of Action Channel");
add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Channel is Expanded");
add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
}
@ -2975,7 +2975,7 @@ static void clever_achannel_names(short *mval)
strcpy(str, conchan->name);
protect= (conchan->flag & CONSTRAINT_CHANNEL_PROTECTED);
add_numbut(but++, TEX, "ConChan: ", 0, 24, str, "Name of Constraint Channel");
add_numbut(but++, TEX, "ConChan: ", 0, 29, str, "Name of Constraint Channel");
add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
}
#if 0 /* tempolarily disabled until there is actually something to display */