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