Jan 10 2012

Singular Value Decomposition (SVD) and object oriented Bounding Boxes

So a continuation of my previous post.. while trying to figure out how to implement SVD (Singular Value Decomposition) algorithm to figure out the best possible aligned bounding box for a set of points.
my friend Ghram Fyffe pointed my to a python library called “numpy” which has great SVD functions that is incredibly easy to use 🙂
seance 3ds max does not support python, i decided i would write the python code to read all the vertex information from a text file, and then overwrite the content of that text file with the resulting alignment matrix.
this method should be eazy to implement into any amp even if it does not have native python support.

i hope this code is helpful to you some one. here it is!

'''
PCA optimized axis generator generator (now threaded)

By Carlos Anguiano
this script will process a text file with point data
and generate and optimized object orient bounding box for the point set
c:\python26_64\python.exe
"C:\svnTools\trunk\S2\exchange\software\managed\pythonScripts\PCAOptOOBB\PCAOptOBB.py"
"C:\Users\SCANLI~2\AppData\Local\Temp\PointCloudData
'''
import time
import threading
import sys
import string
import numpy

import os
#this argument feed the script the folder which to parse for pointCloud data files
#PCFld = sys.argv[1]
PCFld = 'C:\Users\SCANLI~2\AppData\Local\Temp\PointCloudData'
maxThreads=8

def OptmizedTransformAxisFromPointCloadFile (infile):
     lines = open(infile,'r').readlines()
     lCount = len(lines)
     lCount
     vAr = ""
     for i in range(lCount):
         l = lines[i]
         vector = (l.rstrip())
         vAr += vector

         if i != (lCount-1):
             vAr += ";"
     #once you turn the file content into a string list (look up charArrays) the magic happens
     m = numpy.matrix(vAr)
     USV = numpy.linalg.svd(m)
     return USV[2]

def formatData(data):
     lines = []
     for i in range(3):
         A = numpy.asarray(data[i])
         x = A[0][0]
         y = A[0][1]
         z = A[0][2]
         s = "["+str(x)+","+str(y)+","+str(z)+"]\n"
         lines.append(s)
     return lines

class OptTransAxisFromPCF (threading.Thread):
     def __init__(self,filename):
         self.filename = filename
         threading.Thread.__init__(self)

     def run(self):
         filename = self.filename
         axisData = OptmizedTransformAxisFromPointCloadFile(filename)
         lines = formatData(axisData)
         f = open(filename,'w')
         f.writelines(lines)

def OptmizedTAxFromPCldFiles (Fldr):
     pcFiles = os.listdir(Fldr)
     if len(pcFiles) == 0:
         print "no files to process in this folder"
         return false

     for f in pcFiles:
         while(threading.activeCount()>=(maxThreads + 1)):
             print 'Waiting for a thread to free up...'
             time.sleep(.25)
         absF = Fldr+"\\"+f
         OptTransAxisFromPCF(absF).start()
     while(threading.activeCount() != 1):
         time.sleep(.25)

Optmiz1edTAxFromPCldFiles(PCFld)