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

Volume/Regular/Unimodal/3d/1B/Intensity/vuTFDesignSpec.cpp

Go to the documentation of this file.
00001 #include "vuColour31a.h"
00002 #include "vuColour7a.h"
00003 #include "vuColour9a.h"
00004 #include "vuColourXYZa.h"
00005 #include "vuTFDesignSpec.h"
00006 
00007 //#define NORMALIZE_LIGHTS      //normalize lights on initializing palette
00008 
00009 //void vuTFDesignSpec::getRGBa(dword i, vuColourRGBa& rgba)
00010 //{
00011 //}
00012 
00013 void vuTFDesignSpec::generateFunction()
00014 {
00015   vuTFDesign::generateFunction();
00016   // Do own stuff to manipulate the transfer function. Or not.
00017 }
00018 
00019 //----------------------------------------------------------------------------
00020 void vuTFDesignSpec::generateOpacities()
00021 {
00022     dword index;
00023     //dword numColours = m_Colours.getLength();
00024     dword numOpacities = m_Opacities.getLength();
00025     if(false)
00026     {
00027         
00028     }
00029     
00030     //First set up the arrays representing the intensity function
00031     //Note that we always have at least two Nodes
00032     index = 0;
00033     for (dword i = 0; i < numOpacities-1; i++)
00034     {
00035         float slope = float(m_Opacities[i+1].opacity - m_Opacities[i].opacity) /
00036             float(m_Opacities[i+1].intensity - m_Opacities[i].intensity);
00037         
00038         for (; index <= m_Opacities[i+1].intensity; index ++)
00039             m_Table[index*m_NComp+(m_NComp-1)] = m_Opacities[i].opacity +
00040                 slope * (index-m_Opacities[i].intensity);
00041     }
00042     
00043 /*
00044                 opacity = getLightNode(i).col[m_NComp];
00045                 float opacity2 = getLightNode(i+1).col[m_NComp];
00046                 slope = float(opacity2 - opacity) /
00047                     float(m_Colours[i+1].intensity - m_Colours[i].intensity);
00048             } else if(getNumLights()>0)
00049                 opacity = getLightNode(getNumLights()-1).col[m_NComp];
00050             
00051             for (; index <= m_Colours[i+1].intensity; index ++)
00052                 m_Table[index*m_NComp+(m_NComp-1)] = opacity +
00053                     slope * (index-m_Colours[i].intensity);
00054         }
00055 */
00056 }
00057 
00058 //----------------------------------------------------------------------------
00059 //------------------------- public addLight() -------------------------------
00060 //----------------------------------------------------------------------------
00061 
00062 dword vuTFDesignSpec::addLight(const float* _col)
00063 {
00064     //Create the light node
00065     LightNode cp(0.f,m_NComp,_col);
00066     
00067     //Add the new light node.
00068     m_Lights.add(cp);
00069     return m_Lights.getLength()-1;
00070 }
00071 
00072 //----------------------------------------------------------------------------
00073 //------------------------- public getNumLights -----------------------------
00074 //----------------------------------------------------------------------------
00075 
00076 dword vuTFDesignSpec::getNumLights() const
00077 {
00078     return m_Lights.getLength();
00079 }
00080 
00081 //----------------------------------------------------------------------------
00082 //------------------------- public getLightNode() ----------------------------
00083 //----------------------------------------------------------------------------
00084 
00085 const vuTFDesignSpec::LightNode& 
00086 vuTFDesignSpec::getLightNode(dword index) const
00087 {
00088     return m_Lights[index];
00089 }
00090 //----------------------------------------------------------------------------
00091 //------------------------- public setLightWeight() --------------------------
00092 //----------------------------------------------------------------------------
00093 
00094 void vuTFDesignSpec::setLightWeight(dword index, float _weight)
00095 {
00096   m_Lights[index].weight = _weight;
00097 }
00098 
00099 //----------------------------------------------------------------------------
00100 //------------------------- public weightLights() ----------------------------
00101 //----------------------------------------------------------------------------
00102 
00103 void vuTFDesignSpec::weightLights(const float* weights)
00104 {
00105   dword llen = getNumLights();
00106   for(dword l=0;l<llen;l++) {
00107     setLightWeight(l, weights[l]);
00108   }
00109   generateLight();
00110 }
00111 
00112 //----------------------------------------------------------------------------
00113 //------------------------- public weightLights() ----------------------------
00114 //----------------------------------------------------------------------------
00115 
00116 void vuTFDesignSpec::generateLight()
00117 {
00118     if(m_NComp == 32) {
00119         vuColour31a lcol(0.0f);
00120         dword llen = getNumLights();
00121         for(dword l=0;l<llen;l++) {
00122             vuColour31a lamp(m_Lights[l].col);
00123             lamp *= m_Lights[l].weight;
00124             lcol += lamp;
00125         }
00126 
00127         //lcol*= m_LightIntensity/vuColourXYZa(lcol)[1];
00128         lcol*= m_LightIntensity;
00129         
00130         const float *fpc=lcol.getData();
00131         for(dword c=0;c<32;c++,fpc++)
00132             m_Light[c] = *fpc;
00133         
00134     } else if(m_NComp == 8) {
00135         
00136         vuColour7a lcol(0.0f);
00137         dword llen = getNumLights();
00138         for(dword l=0;l<llen;l++) {
00139             vuColour7a lamp(m_Lights[l].col);
00140             lamp *= m_Lights[l].weight;
00141             lcol += lamp;
00142         }
00143         for(dword c=0;c<8;c++)
00144             m_Light[c] = lcol[c]*m_LightIntensity;
00145     } else if(m_NComp == 10) {
00146         vuColour9a lcol(0.0f);
00147         dword llen = getNumLights();
00148         for(dword l=0;l<llen;l++) {
00149             vuColour9a lamp(m_Lights[l].col);
00150             lamp *= m_Lights[l].weight;
00151             lcol += lamp;
00152         }
00153         for(dword c=0;c<10;c++)
00154             m_Light[c] = lcol[c]*m_LightIntensity;
00155     } else { 
00156         cout<<"Transfer functions with inherent light sources only supported for 31 and 7 component model."
00157             <<endl<<"This transfer function has "<<m_NComp<<" components."<<endl;
00158     } // add support for other colour models here
00159 }
00160 
00161 //----------------------------------------------------------------------------
00162 void vuTFDesignSpec::setLightOpacityNode(word lindex, int intensity)
00163 {
00164     if(lindex < getNumLights())
00165     {
00166         int oind;
00167         for(oind = int(getNumOpacities())-1;oind>=0;oind--)
00168             if(int(m_Opacities[oind].intensity) <= intensity) break;
00169 
00170         if(oind > -1)
00171         {
00172             for(int lind = getNumLights()-1;lind>=0;lind--)
00173                 if(m_Lights[lind].wopade == oind) m_Lights[lind].wopade = -1;
00174         }
00175         m_Lights[lindex].wopade = oind; // -1 will be recognized as disabled
00176     }
00177 }
00178 
00179 //----------------------------------------------------------------------------
00180 void vuTFDesignSpec::setupMtlTriAlphaNodes()
00181 {
00182     word numOpacities = m_Opacities.getLength();
00183     word numColours = m_Colours.getLength();
00184     word nnumOpacities = numColours*3+2;
00185     if(numOpacities > nnumOpacities) m_Opacities.removeRange(nnumOpacities, numOpacities);
00186     else
00187     {
00188         for(word opac = numOpacities; opac < numColours*3+2; opac++)
00189             m_Opacities.insert(m_Opacities.getLength()-2,OpacityNode(0,0));
00190     }
00191     
00192     numOpacities = m_Opacities.getLength();
00193     //if(numOpacities != nnumOpacities) cout << "rethink setupMtlTriAlphaNodes()"<<endl;
00194 
00195 //adjust positions (intensities)
00196     word lint = 0;
00197     for(word c = 0; c < numColours; c++)
00198     {
00199         word cind = 1+3*c;
00200         word nint = m_Colours[c].intensity;
00201         word cint = (lint+nint)/2;
00202         
00203         //word nint = (c<numColours-1) ? m_Colours[c+1].intensity : m_Range-1;
00204         word tmpint  = word(0.9*lint + 0.1*cint);
00205         if(tmpint == lint) tmpint++;
00206         m_Opacities[cind].intensity = tmpint;
00207         m_Opacities[cind+1].intensity = cint;
00208         tmpint  = word(0.1*cint + 0.9*nint);
00209         if(tmpint == nint) tmpint--;
00210         m_Opacities[cind+2].intensity = word(tmpint);
00211         lint = m_Colours[c].intensity;
00212     }
00213     m_Opacities[numOpacities-1].intensity = m_Range-1;
00214 }
00215 
00216 //----------------------------------------------------------------------------
00217 void vuTFDesignSpec::setAlphaByLight()
00218 {
00219     word numOpacities = m_Opacities.getLength();
00220     word numLights = m_Lights.getLength();
00221     /* // old automatic choice of nodes (now user controlled)
00222     word numColours = m_Colours.getLength();
00223     word nnumOpacities = numColours*3+2;
00224     if(nnumOpacities != numOpacities) {
00225         cout << "number of opacity nodes doesn't fit.";
00226         return;
00227     }
00228     word numAlphaNodes = numLights<numColours ? numLights : numColours;
00229     for(word l=0;l<numAlphaNodes; l++)
00230     {
00231         m_Opacities[1+l*3+1].opacity = m_Lights[l].weight;
00232     }
00233     */
00234     for(word l=0;l<numLights;l++)
00235     {
00236         int oind = m_Lights[l].wopade;
00237         if(oind >= 0 && oind<numOpacities)
00238             m_Opacities[oind].opacity = m_Lights[l].weight;
00239     }
00240     
00241 }
00242 
00243 //----------------------------------------------------------------------------
00244 // functions for saving
00245 
00246 void vuTFDesignSpec::writeTFunc(ofstream &ofp) const
00247 {
00248     writeNComp(ofp);
00249     writeOpacities(ofp);
00250     writeColours(ofp);
00251     writeLights(ofp);
00252 }
00253 
00254 bool vuTFDesignSpec::writeLights(ofstream &ofp) const
00255 {
00256   //lights
00257   word ncol = getNumLights();
00258   for(dword o=0;o<ncol;o++) {
00259     ofp<<"light(";
00260     for(dword c=0;c<m_NComp-1;c++) {
00261       if(c)ofp<<", ";
00262       ofp<<getLightNode(o).col[c];
00263     }
00264     ofp<<")"<<endl<<endl;
00265   }
00266   return true;
00267 }
00268 
00269 void vuTFDesignSpec::clearAllNodes()
00270 {
00271     m_Lights.removeRange(0,m_Lights.getLength());
00272     vuTFDesign::clearAllNodes();
00273 }
00274 
00275 
00276 //----------------------------------------------------------------------------
00277 // functions for the parser
00278 
00279 void vuTFDesignSpec::parseTFunc()
00280 {
00281   clearAllNodes();
00282   
00283   bool read = true;
00284   while (read) {
00285     read = false;
00286     if ( readOpacity() ) { read = true; }
00287     else if ( readColour() ) { read = true; }
00288     else if ( readLight() ) { read = true; }
00289     else if ( readNComp() ) { read = true; };
00290   }
00291   //if(m_NComp>4) setupMtlTriAlphaNodes();
00292   m_Palette.reset();
00293   updatePalette();
00294 }
00295 
00296 //----------------------------------------------------------------------------
00297 bool vuTFDesignSpec::readLight()
00298 {
00299   if( readString("light") ) {
00300     float col[32];
00301     if(!readNumber(" ( ",col[0])) throw "Error reading light.";
00302     bool read = true;
00303     dword c = 1;
00304     while (read && c<32) {
00305       read = false;
00306       if(readNumber(" , ",col[c])) {
00307         read = true;
00308         c++;
00309       } else if(readString(" ) ")) read = false;
00310     }
00311     if(c==32) readString(" ) ");
00312     else if(c==0) throw "Error reading light components";
00313     while(c<32) col[c++] = 0.0f;
00314     addLight(col);
00315     return true;
00316   } else return false;
00317 }
00318 
00319 //----------------------------------------------------------------------------
00321 void vuTFDesignSpec::updatePalette()
00322 {
00323     while(m_Palette.getNLights() < getNumLights())
00324                 m_Palette.addLight(vuColour31a());
00325     while(m_Palette.getNRefls() < getNumColours())
00326                 m_Palette.addReflectance(vuColour31a());
00327     
00328     for(dword i=0;i<getNumLights() && i<m_Palette.getNLights();i++)
00329     {
00330                 vuColour31a light(m_Lights[i].col);
00331 #ifdef NORMALIZE_LIGHTS         //we shouldn't do that
00332                 light /= SVector(light).norm();
00333 #endif
00334                 m_Palette.getSpec(-1,i) = light;
00335     }
00336 
00337     for(dword i=0;i<getNumColours() && i<m_Palette.getNRefls();i++)
00338                 m_Palette.getSpec(i,-1) = vuColour31a(m_Colours[i].col);
00339 
00340     m_Palette.matchDesignColours();
00341 }
00342 
00343 //----------------------------------------------------------------------------
00345 void vuTFDesignSpec::updateFromPalette()
00346 {
00347     for(dword i=0;i<m_Palette.getNLights();i++)
00348     {
00349                 if(i<getNumLights())
00350                         memcpy(m_Lights[i].col,m_Palette.getSpec(-1,i).getData(),
00351                                    sizeof(float)*31);
00352                 else{
00353                         addLight(m_Palette.getSpec(-1,i).getData());
00354                 }
00355     }
00356     
00357     for(dword i=0;i<m_Palette.getNRefls() && i<getNumColours();i++)
00358     {
00359                 memcpy(m_Colours[i].col,m_Palette.getSpec(i,-1).getData(),
00360                            sizeof(float)*31);
00361     }
00362 }
00363 
00364 //----------------------------------------------------------------------------
00365 
00366 
00367 
00368 
00369 
00370 
00371 

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