Bone/NURBS generation script places bones/NURBS points in random positions

I’m working on a script that takes an armature, and then creates a spline to use for an IK spline constraint, as well as a new guide armature to control the position of the spline points. The armature used for testing the script is a chain of eight bones with the first being named “Bone.001”, and each bone extruded along the Y axis, so the first bone has a head location of (0, 0, 0) and a tail location of (0, 1, 0), and so on.

The trouble is that about half of the time it places the guide bones in their corect positions. Other times, all (or at least some) of the bones will be placed at (0, 0, 0), or some of the bones will be placed 1 blender unit above where it was meant to go (e.g., placed at (0, 5, 1) instead of (0, 5, 0).

Also the spline generation part is, well, weird. Most of the time points are placed at (0, 0, 0), and all but a few points has a w value of 0. The rest of the time the points are placed randomly.

import bpyfrom mathutils import Vector


def ChangeSelectedObject(formerySelected, toBeSelected, scene):
    
    bpy.ops.object.mode_set('EXEC_DEFAULT', mode='OBJECT')
    toBeSelected.select = True
    scene.objects.active = toBeSelected
    formerySelected.select = False
    
currentScene = bpy.context.scene


armObj = bpy.context.active_object


location = armObj.location


bpy.ops.object.mode_set('EXEC_DEFAULT', mode='EDIT')


armData = armObj.data


numberOfBones = len(armData.edit_bones)


pointList = []#list of points


print(armData.name)
print(armData.edit_bones.keys())


pointList.append(armData.edit_bones['Bone.001'].head)
nameList = []


for i in range(1, numberOfBones + 1):#get point positions
    
    pointList.append(armData.edit_bones['Bone.{0:03d}'.format(i)].tail)
    nameList.append('Bone.{0:003d}'.format(i))
    print('added point: {0}'.format(armData.edit_bones['Bone.{0:03d}'.format(i)].tail))


#create new guide armiture


guideArmData = bpy.data.armatures.new('GuideArmatureData')
guideArmObj = bpy.data.objects.new('GuideArmature', guideArmData)


bpy.ops.object.mode_set('EXEC_DEFAULT', mode='OBJECT')
currentScene.objects.link(guideArmObj)
guideArmObj.location = location
ChangeSelectedObject(armObj, guideArmObj, currentScene)
bpy.ops.object.mode_set('EXEC_DEFAULT', mode='EDIT')
nameList.insert(0, 'BoneParent')#place name BoneParent at the beginning of the list


for p, n in zip(pointList, nameList):
    
    eb = guideArmData.edit_bones.new(n)
    pr = p# * guideArmObj.matrix_world.inverted()
    
    print('added bone {1} with head at {0}'.format(pr, n))
    eb.head = pr
    eb.tail = (pr[0], pr[1], pr[2] + 1.0)
    
ChangeSelectedObject(armObj, guideArmObj, currentScene)


#create spline


splineData = bpy.data.curves.new('IK_SplineData', 'CURVE')
splineObj = bpy.data.objects.new('IK_Spline', splineData)


currentScene.objects.link(splineObj)


splineObj.location = location


ChangeSelectedObject(armObj, splineObj, currentScene)


bpy.ops.object.mode_set('EXEC_DEFAULT', mode='EDIT')


splineData.dimensions = '3D'
splineData.splines.clear()
splineData.splines.new('NURBS')
splineData.splines.active.use_endpoint_u = True
splineData.splines.active.points.add(len(pointList) - 1)


curveModifiers = []
hookNo = 0


bpy.ops.object.mode_set('EXEC_DEFAULT', mode='OBJECT')


for bn in nameList:
    
    mod = splineObj.modifiers.new('HookMod{0}'.format(hookNo), 'HOOK')
    hookNo+=1
    mod.object = guideArmObj
    mod.subtarget = bn
    curveModifiers.append(mod)


bpy.ops.object.mode_set('EXEC_DEFAULT', mode='EDIT')


a = pointList
b = splineData.splines.active.points


for sp in b:
    sp.select=False


print('length of nameList: {0}, pointList: {1}, curveModifiers: {2}'.format(len(nameList), len(pointList), len(curveModifiers))) 


print('Contents of nameList: {0}
Contents of pointList: {1}'.format(nameList, pointList))


for pd, sp, c in zip(a, b, curveModifiers):#matrix_world
    print('Spline point X; {0}, Y: {1}, Z: {2}'.format(pd[0], pd[1], pd[2]))
    sp.select=True
    tl = Vector((pd[0], pd[1], pd[2]))
    sp.co = (tl[0], tl[1], tl[2], 1)
    print('Spline co: {0}'.format(sp.co))
    
    #bpy.ops.object.mode_set('EXEC_DEFAULT', mode='OBJECT')
    bpy.ops.object.hook_assign(modifier=c.name)
    bpy.ops.object.hook_reset(modifier=c.name)
    #bpy.ops.object.mode_set('EXEC_DEFAULT', mode='EDIT')
    sp.select=False


#add bone constraint 


ChangeSelectedObject(splineObj, armObj, currentScene)


bpy.ops.object.mode_set('EXEC_DEFAULT', mode='POSE')


splineIK = armObj.pose.bones[nameList[len(nameList) - 1]].constraints.new('SPLINE_IK')


splineIK.influence = 1.0
splineIK.chain_count = numberOfBones
splineIK.target = splineObj


del pointList
del nameList
del curveModifiers

Thanks for your help.