/*#*************************************************************************** * Visibility.h o o * * o o * * Visual Computing Group _ O _ * * IEI Institute, CNUCE Institute, CNR Pisa \/)\/ * * /\/| * * Copyright(C) 1999 by Paolo Cignoni, Paolo Pingi, Claudio Rocchini | * * All rights reserved. \ * * * * Permission to use, copy, modify, distribute and sell this software and * * its documentation for any purpose is hereby granted without fee, provided * * that the above copyright notice appear in all copies and that both that * * copyright notice and this permission notice appear in supporting * * documentation. the author makes no representations about the suitability * * of this software for any purpose. It is provided "as is" without express * * or implied warranty. * * * *****************************************************************************/ /*#************************************************************************** History 2003 Aug 26 First Working version ****************************************************************************/ #ifndef __VCG_MESH_VISIBILITY #define __VCG_MESH_VISIBILITY #include #include #include "simplepic.h" namespace vcg { template void GenNormal(int vn, std::vector > &NN) { typedef Point3 Point3x; NN.clear(); while(NN.size() class VisShader { public : enum {VisMax=MAXVIS}; VisShader(MESH_TYPE &me):m(me) { CullFlag= false; IsClosed = false; ZTWIST=1e-3; SplitNum=1; CameraViewing=false; } typedef Point3 Point3x; typedef typename MESH_TYPE::CoordType CoordType; typedef typename MESH_TYPE::ScalarType ScalarType; typedef typename MESH_TYPE::VertexType VertexType; typedef typename MESH_TYPE::VertexPointer VertexPointer; typedef typename MESH_TYPE::VertexIterator VertexIterator; typedef typename MESH_TYPE::FaceIterator FaceIterator; typedef typename MESH_TYPE::FaceType FaceType; typedef Matrix44 Matrix44x; typedef Box3 Box3x; // The Basic Data the mesh and its wrapper; MESH_TYPE &m; std::vector OMV; // Occluder Mesh Vector; // la visibilita' e' in float, per ogni entita' // 1 significa che e' totalmente visibile per una data direzione. std::vector VV; std::vector< Point3x > VN; // Vettore delle normali che ho usato per calcolare la mask e i float in W; // User defined parameters and flags bool IsClosed; float ZTWIST; bool CullFlag; // Enable the frustum culling. Useful when the splitting value is larger than 2 int SplitNum; protected: bool CameraViewing; //Camera Cam; public: /********************************************************/ // Generic functions with Specialized code for every subclass virtual void MapVisibility(float Gamma=1, float LowPass=0, float HighPass=1,bool FalseColor=false)=0; //virtual void ApplyLightingEnvironment(std::vector &W, float Gamma); virtual int GLAccumPixel( std::vector &PixSeen)=0; virtual bool ReadVisibility(const char * /*filename*/){assert( 0); return false;} virtual bool WriteVisibility(const char * /*filename*/){assert( 0); return false;} /********************************************************/ // Generic functions with same code for every subclass void Clear() { fill(VV.begin(),VV.end(),0); } void InitGL() { glPushAttrib(GL_COLOR_BUFFER_BIT ); ::glClearColor (1.0, 1.0, 1.0, 0.0); glMatrixMode (GL_PROJECTION); glPushMatrix(); glMatrixMode (GL_MODELVIEW); glPushMatrix(); } void RestoreGL() { glMatrixMode (GL_PROJECTION); glPopMatrix(); glMatrixMode (GL_MODELVIEW); glPopMatrix(); glPopAttrib(); } /* Funzione principale di conversione in visibilita' Dati i due vettori PixSeen e PixNotSeen che indicano per ogni entita' (vertice o faccia) quanti sono, rispettivamente, i pixel visibili e occlusi, questa funzione calcola un valore float per ogni entita' che indica quanto e' visibile lungo una data direzione camera == 1 significa completamente visibile == 0 significa completamente occluso. */ void AddPixelCount(std::vector &_VV, const std::vector &PixSeen) { assert(_VV.size()==PixSeen.size()); for(int i=0;i0) _VV[i]+= 1; } //void SetVisibilityMask(std::vector< std::bitset > &_VM, const std::vector &PixSeen, const int dir) // { // assert(_VM.size()==PixSeen.size()); // for(int i=0;i0) _VM[i][dir]=true; // } /******************************* Funzioni ad alto livello che computano le Visibility Mask per varie distribuzioni di direzioni *******************************/ // Funzione Generica chiamata da tutte le seguenti void Compute( CallBack *cb) { //cb(buf.format("Start to compute %i dir\n",VN.size())); InitGL(); VV.resize(m.vert.size()); vector PixSeen(VV.size(),0); for(int i=0;i nvt; GenNormal(nn*Frac,nvt); ScalarType CosConeAngle=Cos(ConeAngleRad); for(int i=0;i=CosConeAngle) VN.push_back(nvt[i]); printf("Asked %i normal, got %i normals\n",nn,VN.size()); Compute(cb); } void ComputeHalf(int nn, Point3x &dir, CallBack *cb) { string buf; VN.clear(); vector nvt; GenNormal(nn*2,nvt); for(int i=0;i0) VN.push_back(nvt[i]); printf("Asked %i normal, got %i normals\n",nn,VN.size()); Compute(cb); } void ComputeUniform(int nn, CallBack *cb) { VN.clear(); GenNormal(nn,VN); char buf[256]; sprintf(buf,"Asked %i normal, got %i normals\n",nn,VN.size()); cb(buf); Compute(cb); } void ComputeSingle(Point3x &dir, CallBack *cb) { VN.clear(); VN.push_back(dir); printf("Computing one direction (%f %f %f)\n",dir[0],dir[1],dir[2]); Compute(cb); } /**********************************************************/ int SplittedRendering(Point3x &ViewDir, std::vector &PixSeen, CallBack *cb=DummyCallBack) { int tt=0; int i,j; for(i=0;i &PixSeen, CallBack *cb=DummyCallBack) { int t0=clock(); string buf; int added=SplittedRendering(BaseDir, PixSeen,cb); int t1=clock(); printf("ComputeSingleDir %i msec\n",t1-t0); } void ComputeAverageVisibilityDirection() { int i,j; VD.resize(VM.size()); for(j=0;j &msk=VM[j]; for(i=0;i &LE, Point3x dir, ScalarType DegAngle1, ScalarType DegAngle2) { LE.clear(); LE.resize(VN.size(),0); int i; for(i=0;iDegAngle2) { LE[i]=0; continue; } LE[i] = 1.0-(a-DegAngle1)/(DegAngle2-DegAngle1); } // last step normalize the weights; ScalarType sum=0; for(i=0;i class VertexVisShader : public VisShader { public : // Function Members VertexVisShader(MESH_TYPE &me):VisShader(me) { // la mesh DEVE avere colore per vertice if(! m.HasPerVertexColor()) assert(0); } void Init() { VV.resize(m.vert.size()); AssignColorId(); } // Vis::VisMode Id() {return Vis::VMPerVert;}; void Compute(int nn); void AddPixelCount(std::vector &_VV, std::vector &PixSeen, std::vector &PixNotSeen ) { for(int i=0;iP()); glVertex((*fi).V(1)->P()); glVertex((*fi).V(2)->P()); } glEnd(); } /***************************************************************************/ //VertexVisibility // Funzione Principale restituisce per ogni entita' quanti px si vedono o no. int GLAccumPixel( std::vector &PixSeen) { SimplePic snapZ; SimplePic snapC; glClearColor(Color4b::White); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_POLYGON_BIT ); glDisable(GL_LIGHTING); glDepthRange(0.0f,1.0f); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); glDepthMask(GL_TRUE); glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); /////** Si disegnano le front face **///// glDepthRange(2.0*ZTWIST,1.0f); // glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glColor(Color4b::Red); DrawFill(m); snapC.OpenGLSnap(); // if(!IsClosed) // sono necessarie due passate in piu! //{ // /////** Si disegnano le back face shiftate in avanti di 2 epsilon **///// // glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); // glColor(Color4b::Black); // glCullFace(GL_FRONT); // glDepthRange(0.0f,1.0f-2.0*ZTWIST); // DrawFill(m); // //glw.DrawFill(); //} //if(OMV.size()>0) //{ // /////** Si disegnano le back face shiftate in avanti di 2 epsilon **///// // glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); // glColor(Color4b::Black); // glDisable(GL_CULL_FACE); // glDepthRange(0.0f,1.0f-2.0*ZTWIST); // for(unsigned int i=0;iDrawFill(); //} int cnt=0; snapZ.OpenGLSnap(GL_DEPTH_COMPONENT); snapC.OpenGLSnap(); double MM[16]; glGetDoublev(GL_MODELVIEW_MATRIX,MM); double MP[16]; glGetDoublev(GL_PROJECTION_MATRIX,MP); int VP[4]; glGetIntegerv(GL_VIEWPORT,VP); double tx,ty,tz; for(int i=0;i=0 && tx=0 && ty VV2; vector VC(VV.size(),1); VV2=VV; for(fi=m.face.begin();fi!=m.face.end();++fi) for(int i=0;i<3;++i) { VV2[(*fi).V(i)-&*m.vert.begin()] += VV[(*fi).V1(i)-&*m.vert.begin()]; ++VC[(*fi).V(i)-&*m.vert.begin()]; } for(unsigned int i=0;iHighPass) gval=HighPass; (*vi).C().SetGrayShade(pow((gval-LowPass)/(HighPass-LowPass),Gamma)); } } //void ApplyLightingEnvironment(std::vector &W, float Gamma=1) // { // assert(W.size()==VN.size()); // MESH_TYPE::VertexIterator vi; // // for(vi=m.vert.begin();vi!=m.vert.end();++vi) // { // float gray=0; // bitset &msk=VM[vi-m.vert.begin()]; // for(int i=0;i