Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

HEFace.cpp

Go to the documentation of this file.
00001 
00002 /*
00003     TEDDY - General graphics application library
00004     Copyright (C) 1999-2002  Timo Suoranta
00005     tksuoran@cc.helsinki.fi
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2.1 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     $Id:  $
00022 */
00023 
00024 
00025 #if 0
00026 
00027 #include "Teddy/Models/HEFace.h"
00028 #include "Teddy/Models/Vertex.h"
00029 #include "Teddy/PhysicalComponents/Projection.h"
00030 #include "Teddy/SysSupport/Messages.h"
00031 #include <cstdio>
00032 #include <algorithm>
00033 using namespace std;
00034 
00035 
00036 namespace Teddy  {
00037 namespace Models {
00038 
00039 
00040 #define FACE_NORMAL_EPSILON (double)(0.0002)
00041 
00042 
00044 Face::Face()
00045 :
00046 Element(0)
00047 {
00048 }
00049 
00051 /*virtual*/ Face::~Face(){
00052 }
00053 
00054 
00059 void Face::insert( Vertex *v ){
00060     vertices.push_front( v );
00061     v->addFace( this );
00062 }
00063 
00064 
00069 void Face::insert( const float x, const float y, const float z ){
00070     Vertex *v = new Vertex(x,y,z);
00071     vertices.push_front( v );
00072     v->addFace( this );
00073 }
00074 
00075 
00077 void Face::append( Vertex *v ){
00078     vertices.push_back( v );
00079     v->addFace( this );
00080 }
00081 
00082 
00084 /*virtual*/ void Face::append( const float x, const float y, const float z ){
00085     Vertex *v = new Vertex(x,y,z);
00086     vertices.push_back( v );
00087     v->addFace( this );
00088 }
00089 
00090 
00092 /*virtual*/ void Face::draw( Projection *p ){
00093     p->beginPolygon();
00094 
00095     if( isEnabled(EL_USE_ELEMENT_NORMAL|EL_HAS_ELEMENT_NORMAL) ){
00096         dmsg( M_MAT, "Drawing flat face" );
00097         p->normal( normal.v[0], normal.v[1], normal.v[2] );
00098     }else{
00099         dmsg( M_MAT, "Drawing smoothed face" );
00100     }
00101 
00102     list<Vertex*>::const_iterator v_it = vertices.begin();
00103     while( v_it != vertices.end() ){
00104         (*v_it)->draw( p );
00105         v_it++;
00106     }
00107 
00108     p->end();
00109 }
00110 
00111 
00142 /*virtual*/ void Face::smooth( float max_smoothing_angle ){
00143     //  Face which has no normal calculated can not be smoothed
00144     //  Face normal is needed even if face is not smoothed
00145     if( isDisabled(EL_HAS_ELEMENT_NORMAL) ){
00146         makeNormal();
00147     }
00148 
00149     //  If the max smoothing angle is set to less or equal to zero,
00150     //  smoothing can not be applied.
00151     if( max_smoothing_angle <= 0 ){
00152         enable ( EL_USE_ELEMENT_NORMAL );
00153         disable( EL_USE_VERTEX_NORMALS );
00154         return;
00155     }
00156 
00157     int  flat_count   = 0;
00158     int  share_count  = 0;
00159     int  smooth_count = 0;
00160     bool flat         = true;
00161 
00162     //  For each vertex in the Face
00163     list<Vertex*>::iterator  v_it = vertices.begin();
00164     while( v_it != vertices.end() ){
00165         Vertex *old_vertex = *v_it;
00166 
00167         //  Make a new Vertex. We will add each normal of
00168         //  Faces that participate in the smoothing and
00169         //  normalize the normal in the end.
00170         Vertex *new_vertex = new Vertex( old_vertex );
00171 
00172         //  Set the normal of each vertex to the normal of this face in the start
00173         new_vertex->setNormal( this->getNormal() );
00174 
00175         //  For each other Face that use this Vertex,
00176         //  test the normal difference. On the way we
00177         //  also calculate the new normal the the new
00178         //  Vertex
00179         share_count  = 1;
00180         smooth_count = 0;
00181         flat_count   = 0;
00182         list<Face*>::iterator f_it = old_vertex->getFaces().begin();
00183         while( f_it != old_vertex->getFaces().end() ){
00184             Face *other = *f_it;
00185 
00186             //  Skip if same Face
00187             if( other == this ){
00188                 f_it++;             
00189                 continue;
00190             }
00191 
00192             //  Bad Face?
00193             if( other == NULL ){
00194                 emsg( M_MAT, "NULL face in vertex cross-reference" );
00195                 f_it++;
00196                 continue;
00197             }
00198 
00199             //  The other face must have a normal as well
00200             if( other->isDisabled(EL_HAS_ELEMENT_NORMAL) ){
00201                 other->makeNormal();
00202             }
00203 
00204             //  Calculate Face normal difference.
00205             //  We have earlier ensured that both Faces do have a normal.
00206             share_count++;
00207             Vector n1      = this ->getNormal();
00208             Vector n2      = other->getNormal();
00209             float  fn_ang  = (float)(  fabs( n1.angle(n2) )  );
00210             float  fn_diff = max_smoothing_angle - fn_ang;
00211 
00212             //  Is the enough different and not too much different?
00213             if( fn_ang > FACE_NORMAL_EPSILON && fn_diff > FLT_MIN ){
00214                 new_vertex->addNormal( n2 );
00215                 smooth_count++;
00216                 //  If the face was considered flat earlier,
00217                 //  we need to set normal to the vertices processed
00218                 //  so far
00219                 if( flat == true ){
00220                     flat = false;
00221 
00222                     Vector                  normal   = this->getNormal();
00223                     list<Vertex*>::iterator v_it_fix = vertices.begin();
00224                     if( v_it_fix != v_it ){
00225                         Vertex *v = *v_it_fix;
00226                         v->setNormal( normal );
00227                         v_it_fix++;
00228                     }
00229                 }
00230             }else{  //  Otherwise it is too close or too different
00231                 flat_count++;
00232             }
00233             f_it++;
00234         }
00235 
00236         //  Finalize the new Vertex normal; normalize it
00237         new_vertex->normNormal();
00238 
00239         //  If the Face is not flat, we will need to store the new Vertex normal
00240 //      if( flat == false ){
00241             dmsg( M_VERT,
00242                 "Face %ld smoothed vertices %ld flat vertices %ld faces share",
00243                 smooth_count,
00244                 flat_count,
00245                 share_count
00246             );
00247             //  If the old Vertex has no normal, we can store the normal information there
00248             if( old_vertex->isDisabled(VX_HAS_NORMAL) ){
00249                 old_vertex->setNormal( new_vertex->getNormal() );
00250                 dmsg( M_VERT,
00251                     "Old vertex %ld had no normal, setting it to (%.5f, %.5f, %.5f)",
00252                     (unsigned long)(old_vertex),
00253                     new_vertex->getNormal().v[0],
00254                     new_vertex->getNormal().v[1],
00255                     new_vertex->getNormal().v[2]
00256                     );
00257                 delete new_vertex;
00258             }else{
00259                 //  If the old Vertex normal different, replace the
00260                 //  Vertex in this Faces vertex list with the new Vertex
00261                 //  This will not change the old Vertex, and other Faces'
00262                 //  Vertex lists will not be changed.
00263                 Vector old_normal = old_vertex->getNormal();
00264                 Vector new_normal = new_vertex->getNormal();
00265                 float vn_ang  = (float)(  fabs( old_normal.angle(new_normal) )  );
00266                 if( vn_ang > FACE_NORMAL_EPSILON /*&& vn_diff > FLT_MIN*/ ){
00267                     dmsg( M_VERT,
00268                         "Old vertex %ld had different %.5f normal, replacing with copy (%.5f, %.5f, %.5f)",
00269                         old_vertex,
00270                         vn_ang,
00271                         new_vertex->getNormal().v[0],
00272                         new_vertex->getNormal().v[1],
00273                         new_vertex->getNormal().v[2]
00274                     );
00275                     //new_vertex->debug();
00276                     *v_it = new_vertex;
00277                 }else{
00278                     dmsg( M_VERT,
00279                         "Old vertex %ld had the same normal %.5f",
00280                         vn_ang,
00281                         old_vertex
00282                     );
00283                     delete new_vertex;
00284 
00285                 }
00286                 //  Otherwise, the old vertex has the same normal as the new
00287                 //  vertex and we do nothing
00288             }
00289         /*}else{
00290             delete new_vertex;
00291         } */
00292         
00293         v_it++;
00294     }
00295 
00296 
00297     if( flat == false ){
00298         disable( EL_USE_ELEMENT_NORMAL );
00299         enable ( EL_USE_VERTEX_NORMALS );
00300 
00301         list<Vertex*>::iterator  v_it_check = vertices.begin();
00302         while( v_it_check != vertices.end() ){
00303             Vertex *check_vertex = *v_it_check;
00304             if( check_vertex->isDisabled(VX_HAS_NORMAL) ){
00305                 check_vertex->debug();
00306                 dmsg( M_VERT, "This smooth Face has Vertex with no normal!" );
00307             }
00308             v_it_check++;
00309         }
00310     }else{
00311         list<Vertex*>::iterator v_it_check = vertices.begin();
00312         while( v_it_check != vertices.end() ){
00313             Vertex *check_vertex = *v_it_check;
00314             check_vertex->setNormal( this->getNormal() );
00315 /*          if( check_vertex->isDisabled(VX_HAS_NORMAL) ){
00316                 check_vertex->debug();
00317                 vert_debug_msg( "This smooth Face has Vertex with no normal!" );
00318             }*/
00319             v_it_check++;
00320         }
00321 
00322 //?     v->disable( VX_USE_THIS_NORMAL | VX_USE_PARENT_NORMAL );
00323         enable( EL_HAS_ELEMENT_NORMAL | EL_USE_ELEMENT_NORMAL );
00324         //debug_msg( "This face is now FLAT" );
00325         //debug_msg( "This face is now SMOOTH" );
00326     }
00327 }
00328 
00329 
00330 };  //  namespace Models
00331 };  //  namespace Teddy
00332 
00333 
00334 #endif  //  0
00335