#based on the MEL procedure "createAnnotation" from Alias
  
#create annotation for each light in the scene
  
#if the lights' name has been changed, user need to re-excute the script to update the annotation name
  
#refined on Jun 15th, fixed some dull bugs such as:
#if the lights has more than one children node, the script will have error
  
import maya.cmds as cmds
import string
  
def ling_addLights_annotation():
  
    #get all the light from the scene
    lightShapeList = cmds.ls(typ='light')
    lightList = cmds.listRelatives(lightShapeList , p=1)
  
    
    for i in range(len(lightList)):
        cmds.select(lightList[i],r=1)
        relatives = cmds.listRelatives(lightList[i],fullPath=1,ad=1)
  
        relativesString = string.join(relatives)
        if ((string.find(relativesString, 'annotationShape' )) == -1):
            ling_createAnnotation(lightList[i])
        else:
        #it has annotation already, just update the light name when necessary        
            for rela in relatives:
                type = cmds.nodeType(rela)
                if (type=='camera'):
                    cmds.delete(rela)
                if (type =='annotationShape'):
                    annotationName = cmds.getAttr(rela+'.text')
                    if(lightList[i] != annotationName ):
                        cmds.setAttr(rela+'.text', lightList[i], type='string')
  
    cmds.select(clear=1)
  
def ling_createAnnotation(annotation):
  
    #get the object to annotate
    object= cmds.ls(sl=1)
    
    #make sure it's a valid transform node
    checkIfTransform= cmds.ls(object[0],sl=1, typ= 'transform')
    if (1 == len(checkIfTransform)):
  
        #carry on if it is and calculate the offset for the annotation
        #based on the object's bounding box
        bbox = cmds.xform(object[0], q=1, ws=1, bb=1 )
        x = abs(bbox[3] - bbox[0])
        y = abs(bbox[4] - bbox[1])
        z = abs(bbox[5] - bbox[2])
  
        #create a locator for easier manipulation
        locator = cmds.spaceLocator(n= "ling_light_annotationLocator#" );
        cmds.xform( ws=1 ,t =( (bbox[0]+(x/2)) , (bbox[1]+(y/2)), (bbox[2]+(z/2))) )
        cmds.parent(locator, object[0])
        
        x=1
        y=3
        z=2
        #sort the sides of the bounding box from lowest to highest so 
        #that the annotation has a more predictable and consistent offset
        xyz = sorted([x,y,z])
        
        #add annotation
        cmds.select(locator,r=1)
        annotationNode = cmds.annotate(locator, tx = annotation, p= ( (bbox[0]+xyz[2]) , (bbox[1]+xyz[2]) ,(bbox[2]+xyz[2]) ) )
  
        #get parent transform of annotation
        transform = cmds.listRelatives(annotationNode,p=1)
  
        #parent annotation to locator
        cmds.parent(transform[0], locator)
        cmds.select(annotationNode,r=1)
    else:
        print("error: Please select the transform node")
  
  
ling_addLights_annotation()