Initial revision
[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
36 #include "LOD_FaceNormalEditor.h"
37
38 using namespace std;
39
40 LOD_FaceNormalEditor::
41 LOD_FaceNormalEditor(
42         LOD_ManMesh2 & mesh
43 ) : m_mesh(mesh) {
44 };
45
46         LOD_FaceNormalEditor *
47 LOD_FaceNormalEditor::
48 New(
49         LOD_ManMesh2 &mesh
50 ){
51         // build a set of normals of the same size
52         // as the number of polys in the mesh
53
54         MEM_SmartPtr<LOD_FaceNormalEditor> output(new LOD_FaceNormalEditor(mesh));
55
56         int face_num = mesh.FaceSet().size();
57
58         MEM_SmartPtr<vector<MT_Vector3> > normals(new vector<MT_Vector3>);
59         MEM_SmartPtr<vector<MT_Vector3> > vertex_normals(new vector<MT_Vector3>);
60
61         if (output == NULL ||
62                 normals == NULL
63         ) {
64                 return NULL;
65         }       
66
67         normals->reserve(face_num);
68         vertex_normals->reserve(mesh.VertexSet().size());
69         output->m_normals = normals.Release();
70         output->m_vertex_normals = vertex_normals.Release();
71
72         return output.Release();
73 };
74
75
76 // Property editor interface
77 ////////////////////////////
78
79         void
80 LOD_FaceNormalEditor::
81 Remove(
82         std::vector<LOD_FaceInd> &sorted_faces
83 ){
84         
85         // assumes a collection of faces sorted in descending order .
86         
87         vector<MT_Vector3> & normals = m_normals.Ref();
88
89         vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
90         vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
91
92         for (; it_start != it_end; ++it_start) {
93
94                 if (normals.size() > 0) {
95                         MT_Vector3 temp = normals[*it_start];
96                 
97                         normals[*it_start] = normals.back();
98                         normals.back() = temp;
99
100                         normals.pop_back();
101                 }
102
103                 // FIXME - through exception
104         }
105 }
106
107
108         void
109 LOD_FaceNormalEditor::
110 Add(
111 ){
112         MT_Vector3 zero(0.0f,0.0f,0.0f);
113         m_normals->push_back(zero);
114 }
115
116         void
117 LOD_FaceNormalEditor::
118 Update(
119         std::vector<LOD_FaceInd> &sorted_faces
120 ){
121
122         vector<MT_Vector3> & normals = m_normals.Ref();
123
124         vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
125         vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
126
127         const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
128
129         for (; it_start != it_end; ++it_start) {                
130                 normals[*it_start] = ComputeNormal(faces[*it_start]);           
131         }       
132 };
133
134 // vertex normals
135 /////////////////
136
137
138         void
139 LOD_FaceNormalEditor::
140 RemoveVertexNormals(
141         vector<LOD_VertexInd> &sorted_verts
142 ){
143         vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
144
145         vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
146         vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
147
148         for (; it_start != it_end; ++it_start) {
149
150                 if (vertex_normals.size() > 0) {
151                         MT_Vector3 temp = vertex_normals[*it_start];
152                 
153                         vertex_normals[*it_start] = vertex_normals.back();
154                         vertex_normals.back() = temp;
155
156                         vertex_normals.pop_back();
157                 }
158
159                 // FIXME - through exception
160         }
161 };
162
163         void
164 LOD_FaceNormalEditor::
165 UpdateVertexNormals(
166         vector<LOD_VertexInd> &sorted_verts
167 ){
168         vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
169
170         vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
171         vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
172
173         for (; it_start != it_end; ++it_start) {                
174                 vertex_normals[*it_start] = ComputeVertexNormal(*it_start);             
175         }       
176 }
177
178
179
180 // Editor specific methods
181 //////////////////////////
182
183         void
184 LOD_FaceNormalEditor::
185 BuildNormals(
186 ){
187
188         const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
189         vector<MT_Vector3> & normals = m_normals.Ref();
190
191         int face_num = faces.size();
192         int cur_face = 0;
193
194         for (; cur_face < face_num; ++cur_face) {
195
196                 MT_Vector3 new_normal = ComputeNormal(faces[cur_face]); 
197                 normals.push_back(new_normal); 
198         }
199         // now build the vertex normals
200
201         vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
202         const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
203
204         int vertex_num = verts.size();
205         int cur_vertex = 0;
206
207         for (; cur_vertex < vertex_num; ++cur_vertex) {
208                 MT_Vector3 new_normal = ComputeVertexNormal(cur_vertex);
209                 vertex_normals.push_back(new_normal);
210         }
211 }
212
213 const 
214         MT_Vector3 
215 LOD_FaceNormalEditor::
216 ComputeNormal(
217         const LOD_TriFace &face
218 ) const {
219
220         const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
221
222         MT_Vector3 vec1 = 
223                 verts[face.m_verts[1]].pos - 
224                 verts[face.m_verts[0]].pos;
225
226         MT_Vector3 vec2 = 
227                 verts[face.m_verts[2]].pos - 
228                 verts[face.m_verts[1]].pos;
229
230         vec1 = vec1.cross(vec2);
231
232         if (!vec1.fuzzyZero()) {
233                 vec1.normalize();
234                 return (vec1);
235         } else {                
236                 return (MT_Vector3(1.0,0,0));
237         }               
238 }
239
240 const 
241         MT_Vector3 
242 LOD_FaceNormalEditor::
243 ComputeVertexNormal(
244         const LOD_VertexInd v
245 ) const {
246
247         // average the face normals surrounding this
248         // vertex and normalize
249         const vector<MT_Vector3> & face_normals = m_normals.Ref();
250
251         vector<LOD_FaceInd> vertex_faces;
252         vertex_faces.reserve(32);
253         
254         m_mesh.VertexFaces(v,vertex_faces);
255         
256         MT_Vector3 normal(0,0,0);
257
258         vector<LOD_FaceInd>::const_iterator face_it = vertex_faces.begin();
259         vector<LOD_FaceInd>::const_iterator face_end = vertex_faces.end();
260
261         for (; face_it != face_end; ++face_it) {
262                 normal += face_normals[*face_it];
263         }
264         
265         if (!normal.fuzzyZero()) {
266                 normal.normalize();
267                 return (normal);
268         } else {                
269                 return (MT_Vector3(1.0,0,0));
270         }               
271 }
272
273
274
275
276
277
278
279
280
281
282         
283
284
285
286
287
288
289
290
291