My script is taking 12 hours+ any suggestions?

Ideasman cpbarton at pacific.net.au
Sat Aug 30 19:08:24 CEST 2003


Hi I have a made a script that process normals for a flat shaded 3D mesh's.
It compares every vert with every other vert to look for verts that can 
share normals and It takes ages.

I'm not asking anyone to rewrite the script- just have a look for any 
stupid errors that might be sucking up time.








#!/usr/bin/python
##############
# AUTOSMOOTH #
##############
import sys
import os
import string
import math

# Used to write floats that dont' contain letters/
def saneFloat(float):
	#return '%(float)b' % vars()  # 6 fp as house.hqx
	return '%f' % float # 10 fp



#Open file from the command line, turn into a list and close it.
file = open(sys.argv[-1], 'r')
fileLineList = file.readlines()
file.close

# Remember the number of lines for progress indication.
fileLen = len(fileLineList)

# Autosmooth value. Higher will autosmooth larger angles.
maxDiff = 1.66

# Loop through the lines.
lineIndex = 0
while lineIndex < len(fileLineList):
	
	#Find Geom TAG..
	if str(fileLineList[lineIndex])[0:8] == 'Geometry':
		lineIndex += 1
		# break if looping beyong the file,
		if lineIndex > len(fileLineList):
			break
			
		# Here we remember lines that have been processed.
		# it needs to be reset for each geom object.
		listOfDoneLines = []
		
		# Start a new loop that checks the current vert against all the others
		newLoopindex = lineIndex
		while len(string.split(fileLineList[newLoopindex])) == 12:
			print '\n', fileLen, newLoopindex,
			
			#vertexnum = newLoopindex - lineIndex
			
			# Compare the 2 lines
			newCompareLoopindex = newLoopindex + 1 # compare the current vert to 
this new one.
			thisPassDoneLines = [] # act apon this after comparing with each vert
			thisPassDoneNormals = []
			while len(string.split(fileLineList[newCompareLoopindex])) == 12:
					
				# Speed up the process by using 2 if's, splitting the string only if 
it has not been evaluated already.
				if newCompareLoopindex not in listOfDoneLines:
					comp1 = string.split(fileLineList[newLoopindex])
					comp2 = string.split(fileLineList[newCompareLoopindex])
					
					if [comp1[0], comp1[1], comp1[2]] == [comp2[0], comp2[1], comp2[2]]:
					
						if newLoopindex not in listOfDoneLines: # Only needs to be added once
							listOfDoneLines.append(newLoopindex)
						
						if newLoopindex not in thisPassDoneLines: # Only needs to be added 
once
							thisPassDoneLines.append(newLoopindex)
							thisPassDoneNormals.append([eval(comp1[8]),  eval(comp1[9]), 
eval(comp1[10])])

						listOfDoneLines.append(newCompareLoopindex)
						thisPassDoneLines.append(newCompareLoopindex)
						thisPassDoneNormals.append([eval(comp2[8]),  eval(comp2[9]), 
eval(comp2[10])])
						print '#',
						
				newCompareLoopindex += 1
			
			
			
			if len(thisPassDoneLines) > 1: # Ok We have some verts to smooth.
				
				
				# This loops through all verts and assigns each a new normal.
				for tempLineIndex in thisPassDoneLines:
					
					tempSplitLine = string.split(fileLineList[tempLineIndex])
					
					# We add to these for every vert that is similar, then devide them 
to get an average.
					NormX = 0
					NormY = 0
					NormZ = 0					
					
					# A list of vert line indicies that we will create to store verts 
that have normals close to ours.
					thisVertFrendsCount = 0
					
					# This compares the current vert with all the others, if they are 
close then add to vertFrends.
					for tNorm in thisPassDoneNormals: # tNorm is just used for one of 
the normals in the thisPassDoneNormals
						
						if abs(eval(tempSplitLine[8]) - tNorm[0]) + 
abs(eval(tempSplitLine[9]) - tNorm[1]) + abs(eval(tempSplitLine[10]) 
-tNorm[2])< maxDiff:
						
							#maxDiff	
							NormX += tNorm[0]
							NormY += tNorm[1]
							NormZ += tNorm[2]
							
							thisVertFrendsCount += 1
							
					
					#Now devide the normals by the number of frends.
					NormX /= thisVertFrendsCount
					NormY /= thisVertFrendsCount
					NormZ /= thisVertFrendsCount

					# make unit length vector.
					d = NormX*NormX + NormY*NormY + NormZ*NormZ
					if d>0:
						d = math.sqrt(d)
						NormX/=d;   NormY/=d;   NormZ/=d


					# Write the normal to the current line
					tempSplitLine[8] = str(saneFloat(NormX))
					tempSplitLine[9] = str(saneFloat(NormY))
					tempSplitLine[10] = str(saneFloat(NormZ))					
					
					fileLineList[tempLineIndex] = string.join(tempSplitLine) + '\n'
							
			
			
			newLoopindex += 1

	lineIndex += 1	


# Writing to file
# file to write
file = open(sys.argv[-1], 'w')
file.writelines(fileLineList)
file.close()





More information about the Python-list mailing list