Blender  V2.59
LOD_FaceNormalEditor.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: LOD_FaceNormalEditor.cpp 35147 2011-02-25 10:47:28Z jesterking $
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00020  * All rights reserved.
00021  *
00022  * The Original Code is: all of this file.
00023  *
00024  * Contributor(s): none yet.
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 // implementation of LOD_FaceNormalEditor.h
00035 
00037 #include "LOD_FaceNormalEditor.h"
00038 
00039 using namespace std;
00040 
00041 LOD_FaceNormalEditor::
00042 LOD_FaceNormalEditor(
00043         LOD_ManMesh2 & mesh
00044 ) : m_mesh(mesh) {
00045 };
00046 
00047         LOD_FaceNormalEditor *
00048 LOD_FaceNormalEditor::
00049 New(
00050         LOD_ManMesh2 &mesh
00051 ){
00052         // build a set of normals of the same size
00053         // as the number of polys in the mesh
00054 
00055         MEM_SmartPtr<LOD_FaceNormalEditor> output(new LOD_FaceNormalEditor(mesh));
00056 
00057         int face_num = mesh.FaceSet().size();
00058 
00059         MEM_SmartPtr<vector<MT_Vector3> > normals(new vector<MT_Vector3>);
00060         MEM_SmartPtr<vector<MT_Vector3> > vertex_normals(new vector<MT_Vector3>);
00061 
00062         if (output == NULL ||
00063                 normals == NULL
00064         ) {
00065                 return NULL;
00066         }       
00067 
00068         normals->reserve(face_num);
00069         vertex_normals->reserve(mesh.VertexSet().size());
00070         output->m_normals = normals.Release();
00071         output->m_vertex_normals = vertex_normals.Release();
00072 
00073         return output.Release();
00074 };
00075 
00076 
00077 // Property editor interface
00079 
00080         void
00081 LOD_FaceNormalEditor::
00082 Remove(
00083         std::vector<LOD_FaceInd> &sorted_faces
00084 ){
00085         
00086         // assumes a collection of faces sorted in descending order .
00087         
00088         vector<MT_Vector3> & normals = m_normals.Ref();
00089 
00090         vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
00091         vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
00092 
00093         for (; it_start != it_end; ++it_start) {
00094 
00095                 if (normals.size() > 0) {
00096                         MT_Vector3 temp = normals[*it_start];
00097                 
00098                         normals[*it_start] = normals.back();
00099                         normals.back() = temp;
00100 
00101                         normals.pop_back();
00102                 }
00103 
00104                 // FIXME - through exception
00105         }
00106 }
00107 
00108 
00109         void
00110 LOD_FaceNormalEditor::
00111 Add(
00112 ){
00113         MT_Vector3 zero(0.0f,0.0f,0.0f);
00114         m_normals->push_back(zero);
00115 }
00116 
00117         void
00118 LOD_FaceNormalEditor::
00119 Update(
00120         std::vector<LOD_FaceInd> &sorted_faces
00121 ){
00122 
00123         vector<MT_Vector3> & normals = m_normals.Ref();
00124 
00125         vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
00126         vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
00127 
00128         const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
00129 
00130         for (; it_start != it_end; ++it_start) {                
00131                 normals[*it_start] = ComputeNormal(faces[*it_start]);           
00132         }       
00133 };
00134 
00135 // vertex normals
00137 
00138 
00139         void
00140 LOD_FaceNormalEditor::
00141 RemoveVertexNormals(
00142         vector<LOD_VertexInd> &sorted_verts
00143 ){
00144         vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
00145 
00146         vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
00147         vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
00148 
00149         for (; it_start != it_end; ++it_start) {
00150 
00151                 if (vertex_normals.size() > 0) {
00152                         MT_Vector3 temp = vertex_normals[*it_start];
00153                 
00154                         vertex_normals[*it_start] = vertex_normals.back();
00155                         vertex_normals.back() = temp;
00156 
00157                         vertex_normals.pop_back();
00158                 }
00159 
00160                 // FIXME - through exception
00161         }
00162 };
00163 
00164         void
00165 LOD_FaceNormalEditor::
00166 UpdateVertexNormals(
00167         vector<LOD_VertexInd> &sorted_verts
00168 ){
00169         vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
00170 
00171         vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
00172         vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
00173 
00174         for (; it_start != it_end; ++it_start) {                
00175                 vertex_normals[*it_start] = ComputeVertexNormal(*it_start);             
00176         }       
00177 }
00178 
00179 
00180 
00181 // Editor specific methods
00183 
00184         void
00185 LOD_FaceNormalEditor::
00186 BuildNormals(
00187 ){
00188 
00189         const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
00190         vector<MT_Vector3> & normals = m_normals.Ref();
00191 
00192         int face_num = faces.size();
00193         int cur_face = 0;
00194 
00195         for (; cur_face < face_num; ++cur_face) {
00196 
00197                 MT_Vector3 new_normal = ComputeNormal(faces[cur_face]); 
00198                 normals.push_back(new_normal); 
00199         }
00200         // now build the vertex normals
00201 
00202         vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
00203         const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
00204 
00205         int vertex_num = verts.size();
00206         int cur_vertex = 0;
00207 
00208         for (; cur_vertex < vertex_num; ++cur_vertex) {
00209                 MT_Vector3 new_normal = ComputeVertexNormal(cur_vertex);
00210                 vertex_normals.push_back(new_normal);
00211         }
00212 }
00213 
00214 const 
00215         MT_Vector3 
00216 LOD_FaceNormalEditor::
00217 ComputeNormal(
00218         const LOD_TriFace &face
00219 ) const {
00220 
00221         const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
00222 
00223         MT_Vector3 vec1 = 
00224                 verts[face.m_verts[1]].pos - 
00225                 verts[face.m_verts[0]].pos;
00226 
00227         MT_Vector3 vec2 = 
00228                 verts[face.m_verts[2]].pos - 
00229                 verts[face.m_verts[1]].pos;
00230 
00231         vec1 = vec1.cross(vec2);
00232 
00233         if (!vec1.fuzzyZero()) {
00234                 vec1.normalize();
00235                 return (vec1);
00236         } else {                
00237                 return (MT_Vector3(1.0,0,0));
00238         }               
00239 }
00240 
00241 const 
00242         MT_Vector3 
00243 LOD_FaceNormalEditor::
00244 ComputeVertexNormal(
00245         const LOD_VertexInd v
00246 ) const {
00247 
00248         // average the face normals surrounding this
00249         // vertex and normalize
00250         const vector<MT_Vector3> & face_normals = m_normals.Ref();
00251 
00252         vector<LOD_FaceInd> vertex_faces;
00253         vertex_faces.reserve(32);
00254         
00255         m_mesh.VertexFaces(v,vertex_faces);
00256         
00257         MT_Vector3 normal(0,0,0);
00258 
00259         vector<LOD_FaceInd>::const_iterator face_it = vertex_faces.begin();
00260         vector<LOD_FaceInd>::const_iterator face_end = vertex_faces.end();
00261 
00262         for (; face_it != face_end; ++face_it) {
00263                 normal += face_normals[*face_it];
00264         }
00265         
00266         if (!normal.fuzzyZero()) {
00267                 normal.normalize();
00268                 return (normal);
00269         } else {                
00270                 return (MT_Vector3(1.0,0,0));
00271         }               
00272 }
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283         
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292