Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

vuNormalTable.cpp

Go to the documentation of this file.
00001 #include "vuNormalTable.h"
00002 
00010 class BList
00011 {
00012 public:
00014     vuNormalBlock* m_data;
00016     BList* m_next;
00017 };
00018 
00019 vuNormalTable::vuNormalTable()
00020 {
00021     m_Table = new float[768];
00022     m_Block = 0;
00023     m_Size  = 0;
00024 }
00025 
00026 vuNormalTable::vuNormalTable(const vuNormalTable& inst)
00027 {
00028     dword i;
00029 
00030     m_Table = new float[768];
00031     for(i=0;i<768;++i)
00032         m_Table[i] = inst.m_Table[i];
00033 
00034     m_Block = new vuNormalBlock;
00035     *m_Block = *inst.m_Block;
00036 
00037     m_Size = inst.m_Size;
00038 }
00039 
00040 vuNormalTable::~vuNormalTable()
00041 {
00042     if (m_Table)
00043         delete [] m_Table;
00044     if (m_Block)
00045         delete [] m_Block;
00046 }
00047 
00048 void vuNormalTable::setCollection(const float* n, dword size)
00049 {
00050     dword i;
00051 
00052     if (m_Block)
00053         delete [] m_Block;
00054     m_Block = new vuNormalBlock;
00055     m_Block->setSize(size);
00056     m_Size = 0;
00057 
00058     for(i=0;i<size;++i)
00059         m_Block->addNormal(&n[i*3]);
00060 }
00061 
00062 void vuNormalTable::initCollection(dword size)
00063 {
00064     if (m_Block)
00065         delete [] m_Block;
00066     m_Block = new vuNormalBlock;
00067     m_Block->setSize(size);
00068     m_Size = 0;
00069 }
00070 
00071 void vuNormalTable::addToCollection(const float* n)
00072 {
00073     m_Block->addNormal(n);
00074 }
00075 
00076 void vuNormalTable::computeTable(void)
00077 {
00078     vuNormalBlock* left;
00079     vuNormalBlock* right;
00080     BList* head;
00081     BList* iter;
00082     BList* split;
00083     bool  cansplit;
00084     dword i;
00085 
00086     m_Block->computeStats();
00087 
00088     head = new BList;
00089     head->m_data = m_Block;
00090     head->m_next = 0;
00091     m_Block = 0;
00092 
00093     //
00094     // Split normals according to groups that are close
00095     // together (using range and standard deviation).
00096     //
00097     m_Size = 1;
00098     cansplit = true;
00099     while((m_Size<256) && cansplit)
00100     {
00101         split = head;
00102         iter = head->m_next;
00103         while(iter != 0)
00104         {
00105             if (iter->m_data->getRange() > split->m_data->getRange())
00106                 split = iter;
00107             else if (iter->m_data->getRange() == split->m_data->getRange())
00108             {
00109                 if (iter->m_data->getStdDev() > split->m_data->getStdDev())
00110                     split = iter;
00111             }
00112             iter = iter->m_next;
00113         }
00114         left = new vuNormalBlock;
00115         right = new vuNormalBlock;
00116         if (split->m_data->medianSplit(*left, *right))
00117         {
00118             delete split->m_data;
00119             split->m_data = left;
00120             iter = split->m_next;
00121             split->m_next = new BList;
00122             split->m_next->m_data = right;
00123             split->m_next->m_next = iter;
00124             ++m_Size;
00125         }
00126         else
00127         {
00128             delete left;
00129             delete right;
00130             cansplit = false;
00131         }
00132     }
00133 
00134     //
00135     // Compute the average normal in each group.
00136     //
00137     i = 0;
00138     iter = head->m_next;
00139     while(iter != 0)
00140     {
00141         iter->m_data->computeAverage(&m_Table[i]);
00142         iter = iter->m_next;
00143         i += 3;
00144     }
00145 
00146     //
00147     // Destroy the list that we computed.
00148     //
00149     iter = head->m_next;
00150     while(iter != 0)
00151     {
00152         delete iter->m_data;
00153         split = iter;
00154         iter = iter->m_next;
00155         delete split;
00156     }
00157 }
00158 
00159 void vuNormalTable::destroyTable(void)
00160 {
00161     if (m_Table)
00162     {
00163         delete [] m_Table;
00164         m_Table = 0;
00165     }
00166 }
00167 
00168 dword vuNormalTable::findNearest(const float* n)
00169 {
00170     float d;
00171     float min;
00172     dword index=0;
00173     dword i;
00174 
00175     min = 1000000.0f;
00176     for(i=0;i<m_Size*3;i+=3)
00177     {
00178         d = ((n[0]-m_Table[i])*(n[0]-m_Table[i])) + 
00179             ((n[1]-m_Table[i+1])*(n[1]-m_Table[i+1])) + 
00180             ((n[2]-m_Table[i+2])*(n[2]-m_Table[i+2]));
00181         if (d < min)
00182         {
00183             index = i/3;
00184             min = d;
00185         }
00186     }
00187 
00188     return index;
00189 }
00190 
00191 vuNormalTable& vuNormalTable::operator=(const vuNormalTable& rhs)
00192 {
00193     if (this != &rhs)
00194     {
00195         dword i;
00196 
00197         for(i=0;i<768;++i)
00198             m_Table[i] = rhs.m_Table[i];
00199 
00200         if (m_Block)
00201             delete [] m_Block;
00202         m_Block = new vuNormalBlock;
00203         *m_Block = *rhs.m_Block;
00204     }
00205     return *this;
00206 }
00207 
00208 const float* vuNormalTable::operator[](dword index)
00209 {
00210     return &m_Table[index*3];
00211 }

Generated on Wed Dec 15 21:20:35 2004 for vuVolume by  doxygen 1.3.9.1