[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