|
Blender
V2.59
|
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 }