Blender  V2.59
LOD_ExternNormalEditor.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: LOD_ExternNormalEditor.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 #include "LOD_ExternNormalEditor.h"
00035 #include <vector>
00036 
00037 using namespace std;
00038 
00039 
00040 LOD_ExternNormalEditor::
00041 LOD_ExternNormalEditor(
00042         LOD_Decimation_InfoPtr extern_info,
00043         LOD_ManMesh2 &mesh
00044 ) :
00045         m_mesh(mesh),
00046         m_extern_info (extern_info)
00047 {
00048 }
00049 
00050         LOD_ExternNormalEditor *
00051 LOD_ExternNormalEditor::
00052 New(
00053         LOD_Decimation_InfoPtr extern_info,
00054         LOD_ManMesh2 &mesh
00055 ){
00056         if (extern_info == NULL) return NULL;
00057         
00058         MEM_SmartPtr<LOD_ExternNormalEditor> output(new LOD_ExternNormalEditor(extern_info,mesh));
00059 
00060         int face_num = mesh.FaceSet().size();
00061 
00062         MEM_SmartPtr<vector<MT_Vector3> > normals(new vector<MT_Vector3>);
00063 
00064         if (output == NULL ||
00065                 normals == NULL
00066         ) {
00067                 return NULL;
00068         }       
00069 
00070         normals->reserve(face_num);
00071         output->m_normals = normals.Release();
00072 
00073         return output.Release();
00074 };
00075         
00076 
00077         void
00078 LOD_ExternNormalEditor::
00079 Remove(
00080         std::vector<LOD_FaceInd> &sorted_faces
00081 ){
00082         // assumes a collection of faces sorted in descending order .
00083         
00084         vector<MT_Vector3> & normals = m_normals.Ref();
00085 
00086         vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
00087         vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
00088 
00089         for (; it_start != it_end; ++it_start) {
00090 
00091                 if (normals.size() > 0) {
00092                         MT_Vector3 temp = normals[*it_start];
00093                 
00094                         normals[*it_start] = normals.back();
00095                         normals.back() = temp;
00096 
00097                         normals.pop_back();
00098                 }
00099 
00100                 // FIXME - throw exception
00101         }
00102 }
00103 
00104 
00105         void
00106 LOD_ExternNormalEditor::
00107 Add(
00108 ){
00109         MT_Vector3 zero(0.0f,0.0f,0.0f);
00110         m_normals->push_back(zero);
00111 };      
00112 
00113         void
00114 LOD_ExternNormalEditor::
00115 Update(
00116         std::vector<LOD_FaceInd> &sorted_faces
00117 ){
00118         vector<MT_Vector3> & normals = m_normals.Ref();
00119 
00120         vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
00121         vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
00122 
00123         const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
00124 
00125         for (; it_start != it_end; ++it_start) {                
00126                 normals[*it_start] = ComputeNormal(faces[*it_start]);           
00127         }       
00128 };
00129 
00130 
00131 
00132         
00133 // vertex normals
00135 
00136         void
00137 LOD_ExternNormalEditor::
00138 RemoveVertexNormals(
00139         std::vector<LOD_VertexInd> &sorted_verts
00140 ){
00141 
00142         float * vertex_normals = m_extern_info->vertex_normal_buffer;
00143 
00144         // assumption here that the vertexs normal number corresponds with 
00145         // the number of vertices !
00146 
00147         int vertex_normal_num = m_extern_info->vertex_num; 
00148 
00149         vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
00150         vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
00151 
00152         for (; it_start != it_end; ++it_start) {
00153 
00154                 if (vertex_normal_num > 0) {
00155                         float * vertex_normal = vertex_normals + int(*it_start)*3;
00156                         float * last_vertex = vertex_normals + ((vertex_normal_num-1)*3);
00157 
00158                         MT_Vector3 last_v(last_vertex);
00159                         last_v.getValue(vertex_normal);
00160                         vertex_normal_num--;
00161                 }
00162 
00163                 // FIXME - through exception
00164         }
00165 };
00166 
00167 
00168 
00169         void
00170 LOD_ExternNormalEditor::
00171 UpdateVertexNormals(
00172         std::vector<LOD_VertexInd> &sorted_verts
00173 ){
00174         float * vertex_normals = m_extern_info->vertex_normal_buffer;
00175 
00176         vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
00177         vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
00178 
00179         for (; it_start != it_end; ++it_start) {                
00180                 MT_Vector3 temp = ComputeVertexNormal(*it_start);               
00181                 float * vertex_normal = vertex_normals + int(*it_start)*3;
00182                 temp.getValue(vertex_normal);
00183         }
00184 }
00185 
00186 // Editor specific methods
00188 
00189         void
00190 LOD_ExternNormalEditor::
00191 BuildNormals(
00192 ) {
00193         const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
00194         vector<MT_Vector3> & normals = m_normals.Ref();
00195 
00196         int face_num = faces.size();
00197         int cur_face = 0;
00198 
00199         for (; cur_face < face_num; ++cur_face) {
00200 
00201                 MT_Vector3 new_normal = ComputeNormal(faces[cur_face]); 
00202                 normals.push_back(new_normal); 
00203         }
00204 }
00205 
00206 const 
00207         MT_Vector3 
00208 LOD_ExternNormalEditor::
00209 ComputeNormal(
00210         const LOD_TriFace &face
00211 ) const {
00212 
00213         const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
00214 
00215         MT_Vector3 vec1 = 
00216                 verts[face.m_verts[1]].pos - 
00217                 verts[face.m_verts[0]].pos;
00218 
00219         MT_Vector3 vec2 = 
00220                 verts[face.m_verts[2]].pos - 
00221                 verts[face.m_verts[1]].pos;
00222 
00223         vec1 = vec1.cross(vec2);
00224 
00225         if (!vec1.fuzzyZero()) {
00226                 vec1.normalize();
00227                 return (vec1);
00228         } else {                
00229                 return (MT_Vector3(1.0,0,0));
00230         }               
00231 }
00232 
00233 const 
00234         MT_Vector3 
00235 LOD_ExternNormalEditor::
00236 ComputeVertexNormal(
00237         const LOD_VertexInd v
00238 ) const {
00239 
00240         // average the face normals surrounding this
00241         // vertex and normalize
00242         // vector<LOD_Vertex> &verts = m_mesh.VertexSet(); /*unused*/
00243         const vector<MT_Vector3> & face_normals = m_normals.Ref();
00244 
00245         vector<LOD_FaceInd> vertex_faces;
00246         vertex_faces.reserve(32);
00247         
00248         m_mesh.VertexFaces(v,vertex_faces);
00249         
00250         MT_Vector3 normal(0,0,0);
00251 
00252         vector<LOD_FaceInd>::const_iterator face_it = vertex_faces.begin();
00253         vector<LOD_FaceInd>::const_iterator face_end = vertex_faces.end();
00254 
00255         for (; face_it != face_end; ++face_it) {
00256                 normal += face_normals[*face_it];
00257         }
00258         
00259         if (!normal.fuzzyZero()) {
00260                 normal.normalize();
00261                 return (normal);
00262         } else {                
00263                 return (MT_Vector3(1.0,0,0));
00264         }               
00265 }