Blender V2.61 - r43446

LOD_ExternNormalEditor.cpp

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