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()