[Tutor] Recursive function calling
Bernard Lebel
3dbernard at gmail.com
Wed Aug 24 22:28:01 CEST 2005
Hello,
Sorry in advance for the long email.
I have a two-part script. The first parts creates a structure made of
nested lists. Some of these lists have only strings, other have other
lists. Anyway the point is to ultimately write this structure as a XML
file.
Here is the script that builds the structure:
for oCharacter in oCharacters:
# --------------------------
# < bb_file >
aFileTag = []
aFileTag.append( 'bb_file' )
aFileTag.append( [ ( 'type', '"bb_characterxml"' ), (
'character_name', '""' ), ( 'character_version', '""' ), (
'syntax_version', '"1.0"' ) ] )
# --------------------------
# < model >
aModelTag = []
aModelTag.append( 'model' )
aModelTag.append( [] ) # No options
aModelTag.append( [ str( oCharacter.fullname ) ] )
# --------------------------
# < objects >
aObjectsTag = []
aObjectsTag.append( 'objects' )
aObjectsTag.append( [] ) # No options
# --------------------------
# < object >
# Get renderable character children
oChildren = xsifactory.CreateObject( 'XSI.Collection' )
oChildren.additems( oCharacter.findchildren() )
oRenderable = xsiHandler.process( 20, oChildren, '01_02_01', (1,0),
23, bVerbose )
for oObject in oRenderable:
aObjectTag = []
aObjectTag.append( 'object' )
aObjectTag.append( [ ( 'objectname', '"' + str( oObject.name ) + '"' ) ] )
# --------------------------
# < material >
aMaterialTag = []
aMaterialTag.append( 'material' )
aMaterialTag.append( [ ( 'stylename', '"styleX"' ) ] )
aMaterialTag.append( [ str( oObject.material.name ) ] )
aObjectTag.append( aMaterialTag )
# --------------------------
# < clusters >
if hasattr( oObject.activeprimitive.geometry, 'clusters' ) == False: pass
else:
aClustersTag = []
aClustersTag.append( 'clusters' )
aClustersTag.append( [] ) # No options
# < cluster >
aClusterTags = []
for oCluster in oObject.activeprimitive.geometry.clusters:
# < cluster >
aClusterTag = []
aClusterTag.append( 'cluster' )
aClusterTag.append( [ ( 'clustername', str( oCluster.name ) ), (
'clustertype', str( oCluster.type ) ) ] )
# Check if cluster has material
if oCluster.localproperties.count > 0:
for oLocalProp in oCluster.localproperties:
if oCluster.type == 'poly' and oLocalProp.type == c.siMaterialType:
# < clustermaterial >
aClusterMaterialTag = []
aClusterMaterialTag.append( 'clustermaterial' )
aClusterMaterialTag.append( [ ( 'stylename', '"styleX"' ) ] )
aClusterMaterialTag.append( [ str( oLocalProp.name ) ] )
aClusterTag.append( [ aClusterMaterialTag ] )
elif oCluster.type == 'sample' and oLocalProp.type ==
c.siClsUVSpaceTxtType:
# < uvset >
aUVsetTag = []
aUVsetTag.append( 'uvset' )
aUVsetTag.append( [ ( 'stylename', '"sytleX"' ) ] )
aUVsetTag.append( [ str( oLocalProp.name ) ] )
aClusterTag.append( [ aUVsetTag ] )
# Add this cluster tag to list of cluster tags
aClusterTags.append( aClusterTag )
# Add list of cluster tags to clusters tag (!)
aClustersTag.append( aClusterTags )
# Add cluster tag to object tag
aObjectTag.append( aClustersTag )
# Add object tag to list of objects tag (!)
aObjectsTag.append( aObjectTag )
# Add tags under file tags to file tag
aFileTag.append( [ aModelTag, aObjectsTag ] )
#aFileTag.append( [ aModelTag, aRenderingStylesTag, aObjectsTag,
aMaterialLibraryTag ] )
printTag( aFileTag, 0 )
So I get my structure, and to this point I'm 100% positive the
structure is in the appropriate state. I can confirm this by simply
print the structure as a string, and then reorganize this string in a
tree-view. This gives:
[
'bb_file',
[
('type', '"bb_characterxml"'),
('character_name', '""'),
('character_version', '""'),
('syntax_version', '"1.0"')
],
[
[
'model',
[],
[
'Model'
]
],
[
'objects',
[],
[
'object',
[
('objectname', '"sphere"')
],
[
'material',
[
('stylename', '"styleX"')
],
[
'Scene_Material'
]
],
[
'clusters',
[],
[
[
'cluster',
[
('clustername', u'Polygon'),
('clustertype', u'poly')
],
[
[
'clustermaterial',
[
('stylename', '"styleX"')
],
[
'Material'
]
]
]
],
[
'cluster',
[
('clustername', u'Texture_Coordinates_AUTO'),
('clustertype', u'sample')
],
[
[
'uvset',
[
('stylename', '"sytleX"')
],
[
'Texture_Projection'
]
]
]
]
]
]
]
]
]
]
In XML format, the file I'm trying to output is:
<bb_file type="bb_characterxml" character_name="" character_version=""
syntax_version="1.0">
<model>Model fullname</model>
<objects>
<object objectname="object name">
<material stylename="style name">Material name</material>
<clusters>
<cluster clustername="cluster name" clustertype="cluster type">
<clustermaterial stylename="style name">Material name</clustermaterial>
</cluster>
<cluster clustername="cluster name" clustertype="cluster type">
<uvset stylename="style name">Texture projection name</uvset>
<uvset stylename="style name">Texture projection name</uvset>
</cluster>
</clusters>
</object>
</objects>
<renderingstyles>
<renderstyle stylename="style name">Library fullname</renderstyle>
<renderstyle stylename="style name">Library fullname</renderstyle>
</renderingstyles>
<materiallibraries>
<materiallibrary libraryname="library fullname">
<material>Material name</material>
<material>Material name</material>
</materiallibrary>
</materiallibraries>
</bb_file>
To this point, everything works fine. Now to the step of writing this
in XML format. The last line of the script calls this function:
def printTag( aTag, i ):
# --------------------------
# Opening tag
sTag = aTag[0]
aTagOptions = aTag[1]
# Check if we have subtags
if len( aTagOptions ) > 0:
sOptions = ''
sSpace = ' '
sEqual = '='
for tOption in aTagOptions:
sOption = '%s%s%s' % ( tOption[0], '=', tOption[1] )
sOptions += ' %s' % sOption
sHeader = '%s%s' % ( sTag, sOptions )
else:
sHeader = sTag
sOpen = '%s%s%s' % ( '<', sHeader, '>' )
sClose = '%s%s%s%s' % ( '<', '/', sTag, '>' )
# --------------------------
# Tag value
aTagValue = aTag[2]
# Extract value, wich is always a list
# The list contains only a string, or a list of tags
aValue = aTagValue[0]
# Is the tag empty?
if len( aValue ) < 1:
sString = '%s%s%s' % ( '\t' * i, sOpen, sClose )
xsi.logmessage( sString )
else:
# Is the tag value a string?
if type( aValue ) == types.StringType:
sString = '%s%s%s%s' % ( '\t' * i, sOpen, aValue, sClose )
# Is the tag value a list?
elif type( aValue ) == types.ListType:
sOpenString = '%s%s' % ( '\t' * i, sOpen )
sCloseString = '%s%s' % ( '\t' * i, sClose )
xsi.logmessage( sOpenString )
#xsi.logmessage( 'len( aTagValue ): ' + str( len( aTagValue ) ) )
# Iterate sub tags
for oTag in aTagValue:
printTag( oTag, i + 1 )
xsi.logmessage( sCloseString )
# No valid value!
else: pass
So far so good. If you notice near the end, the function checks if
there are "tags" contained in the value list. If so, I want it to
recursively call itself, so it prints each tags in the entire
structure.
However, the problem is that it doesn't go further than the second level........
Any suggestion?
Thanks in advance
Bernard
More information about the Tutor
mailing list