Merged from trunk with revision range 36835-37865,
[blender.git] / intern / decimation / intern / LOD_FaceNormalEditor.cpp
1 /*
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file decimation/intern/LOD_FaceNormalEditor.cpp
30  *  \ingroup decimation
31  */
32
33
34 // implementation of LOD_FaceNormalEditor.h
35
36 ///////////////////////////////////////
37 #include "LOD_FaceNormalEditor.h"
38
39 using namespace std;
40
41 LOD_FaceNormalEditor::
42 LOD_FaceNormalEditor(
43         LOD_ManMesh2 & mesh
44 ) : m_mesh(mesh) {
45 };
46
47         LOD_FaceNormalEditor *
48 LOD_FaceNormalEditor::
49 New(
50         LOD_ManMesh2 &mesh
51 ){
52         // build a set of normals of the same size
53         // as the number of polys in the mesh
54
55         MEM_SmartPtr<LOD_FaceNormalEditor> output(new LOD_FaceNormalEditor(mesh));
56
57         int face_num = mesh.FaceSet().size();
58
59         MEM_SmartPtr<vector<MT_Vector3> > normals(new vector<MT_Vector3>);
60         MEM_SmartPtr<vector<MT_Vector3> > vertex_normals(new vector<MT_Vector3>);
61
62         if (output == NULL ||
63                 normals == NULL
64         ) {
65                 return NULL;
66         }       
67
68         normals->reserve(face_num);
69         vertex_normals->reserve(mesh.VertexSet().size());
70         output->m_normals = normals.Release();
71         output->m_vertex_normals = vertex_normals.Release();
72
73         return output.Release();
74 };
75
76
77 // Property editor interface
78 ////////////////////////////
79
80         void
81 LOD_FaceNormalEditor::
82 Remove(
83         std::vector<LOD_FaceInd> &sorted_faces
84 ){
85         
86         // assumes a collection of faces sorted in descending order .
87         
88         vector<MT_Vector3> & normals = m_normals.Ref();
89
90         vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
91         vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
92
93         for (; it_start != it_end; ++it_start) {
94
95                 if (normals.size() > 0) {
96                         MT_Vector3 temp = normals[*it_start];
97                 
98                         normals[*it_start] = normals.back();
99                         normals.back() = temp;
100
101                         normals.pop_back();
102                 }
103
104                 // FIXME - through exception
105         }
106 }
107
108
109         void
110 LOD_FaceNormalEditor::
111 Add(
112 ){
113         MT_Vector3 zero(0.0f,0.0f,0.0f);
114         m_normals->push_back(zero);
115 }
116
117         void
118 LOD_FaceNormalEditor::
119 Update(
120         std::vector<LOD_FaceInd> &sorted_faces
121 ){
122
123         vector<MT_Vector3> & normals = m_normals.Ref();
124
125         vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
126         vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
127
128         const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
129
130         for (; it_start != it_end; ++it_start) {                
131                 normals[*it_start] = ComputeNormal(faces[*it_start]);           
132         }       
133 };
134
135 // vertex normals
136 /////////////////
137
138
139         void
140 LOD_FaceNormalEditor::
141 RemoveVertexNormals(
142         vector<LOD_VertexInd> &sorted_verts
143 ){
144         vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
145
146         vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
147         vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
148
149         for (; it_start != it_end; ++it_start) {
150
151                 if (vertex_normals.size() > 0) {
152                         MT_Vector3 temp = vertex_normals[*it_start];
153                 
154                         vertex_normals[*it_start] = vertex_normals.back();
155                         vertex_normals.back() = temp;
156
157                         vertex_normals.pop_back();
158                 }
159
160                 // FIXME - through exception
161         }
162 };
163
164         void
165 LOD_FaceNormalEditor::
166 UpdateVertexNormals(
167         vector<LOD_VertexInd> &sorted_verts
168 ){
169         vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
170
171         vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
172         vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
173
174         for (; it_start != it_end; ++it_start) {                
175                 vertex_normals[*it_start] = ComputeVertexNormal(*it_start);             
176         }       
177 }
178
179
180
181 // Editor specific methods
182 //////////////////////////
183
184         void
185 LOD_FaceNormalEditor::
186 BuildNormals(
187 ){
188
189         const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
190         vector<MT_Vector3> & normals = m_normals.Ref();
191
192         int face_num = faces.size();
193         int cur_face = 0;
194
195         for (; cur_face < face_num; ++cur_face) {
196
197                 MT_Vector3 new_normal = ComputeNormal(faces[cur_face]); 
198                 normals.push_back(new_normal); 
199         }
200         // now build the vertex normals
201
202         vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
203         const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
204
205         int vertex_num = verts.size();
206         int cur_vertex = 0;
207
208         for (; cur_vertex < vertex_num; ++cur_vertex) {
209                 MT_Vector3 new_normal = ComputeVertexNormal(cur_vertex);
210                 vertex_normals.push_back(new_normal);
211         }
212 }
213
214 const 
215         MT_Vector3 
216 LOD_FaceNormalEditor::
217 ComputeNormal(
218         const LOD_TriFace &face
219 ) const {
220
221         const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
222
223         MT_Vector3 vec1 = 
224                 verts[face.m_verts[1]].pos - 
225                 verts[face.m_verts[0]].pos;
226
227         MT_Vector3 vec2 = 
228                 verts[face.m_verts[2]].pos - 
229                 verts[face.m_verts[1]].pos;
230
231         vec1 = vec1.cross(vec2);
232
233         if (!vec1.fuzzyZero()) {
234                 vec1.normalize();
235                 return (vec1);
236         } else {                
237                 return (MT_Vector3(1.0,0,0));
238         }               
239 }
240
241 const 
242         MT_Vector3 
243 LOD_FaceNormalEditor::
244 ComputeVertexNormal(
245         const LOD_VertexInd v
246 ) const {
247
248         // average the face normals surrounding this
249         // vertex and normalize
250         const vector<MT_Vector3> & face_normals = m_normals.Ref();
251
252         vector<LOD_FaceInd> vertex_faces;
253         vertex_faces.reserve(32);
254         
255         m_mesh.VertexFaces(v,vertex_faces);
256         
257         MT_Vector3 normal(0,0,0);
258
259         vector<LOD_FaceInd>::const_iterator face_it = vertex_faces.begin();
260         vector<LOD_FaceInd>::const_iterator face_end = vertex_faces.end();
261
262         for (; face_it != face_end; ++face_it) {
263                 normal += face_normals[*face_it];
264         }
265         
266         if (!normal.fuzzyZero()) {
267                 normal.normalize();
268                 return (normal);
269         } else {                
270                 return (MT_Vector3(1.0,0,0));
271         }               
272 }
273
274
275
276
277
278
279
280
281
282
283         
284
285
286
287
288
289
290
291
292