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