Blender V2.61 - r43446

LOD_NdQuadricEditor.cpp

Go to the documentation of this file.
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_NdQuadricEditor.h"
00034 #include "LOD_ExternNormalEditor.h"
00035 #include "LOD_ExternVColorEditor.h"
00036 
00037 // Creation
00039 
00040 using namespace std;
00041 
00042 
00043 LOD_NdQuadricEditor::
00044 LOD_NdQuadricEditor(
00045     LOD_ManMesh2 &mesh
00046 ) :
00047     m_quadrics(NULL),
00048     m_mesh(mesh)
00049 {
00050 };
00051 
00052     LOD_NdQuadricEditor *
00053 LOD_NdQuadricEditor::
00054 New(
00055     LOD_ManMesh2 &mesh
00056 ){
00057     //same number of quadrics as vertices in the mesh
00058 
00059     NanPtr<LOD_NdQuadricEditor> output(new LOD_NdQuadricEditor(mesh));
00060 
00061     if (output == NULL) {
00062         return NULL;
00063     }
00064     return output.Release();
00065 }
00066 
00067 
00068 // Property editor interface
00070 
00071     void
00072 LOD_NdQuadricEditor::
00073 Remove(
00074     const std::vector<LOD_VertexInd> &sorted_vertices
00075 ){
00076     vector<LOD_NdQuadric> & quadrics = *m_quadrics;
00077 
00078     vector<LOD_VertexInd>::const_iterator it_start = sorted_vertices.begin();
00079     vector<LOD_VertexInd>::const_iterator it_end = sorted_vertices.end();
00080 
00081     for (; it_start != it_end; ++it_start) {
00082 
00083         if (quadrics.size() > 0) {
00084             LOD_NdQuadric temp = quadrics[*it_start];
00085         
00086             quadrics[*it_start] = quadrics.back();
00087             quadrics.back() = temp;
00088 
00089             quadrics.pop_back();
00090         }
00091     }
00092 };
00093 
00094 
00095 // Editor specific methods
00097 
00098     bool
00099 LOD_NdQuadricEditor::
00100 BuildQuadrics(
00101     const LOD_ExternNormalEditor& normal_editor,
00102     bool preserve_boundaries
00103 ){
00104     if (m_quadrics != NULL) delete(m_quadrics);     
00105 
00106     m_quadrics =new vector<LOD_NdQuadric> (m_mesh.VertexSet().size());
00107     if (m_quadrics == NULL) return false;
00108 
00109     // iterate through the face set of the mesh
00110     // compute a quadric based upon that face and 
00111     // add it to each of it's vertices quadrics.
00112 
00113     const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
00114     const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
00115     vector<LOD_Edge> &edges = m_mesh.EdgeSet(); 
00116 
00117     const vector<MT_Vector3> &normals = normal_editor.Normals();
00118     vector<MT_Vector3>::const_iterator normal_it = normals.begin();
00119     
00120     vector<LOD_TriFace>::const_iterator face_it = faces.begin();
00121     vector<LOD_TriFace>::const_iterator face_end = faces.end();
00122 
00123     vector<LOD_NdQuadric> & quadrics = *m_quadrics;
00124 
00125 
00126     for (; face_it != face_end; ++face_it, ++normal_it) {
00127                 
00128         MT_Vector3 normal = *normal_it;
00129         MT_Scalar offset = -normal.dot(verts[face_it->m_verts[0]].pos); 
00130 
00131         LOD_NdQuadric q(normal,offset);
00132 
00133 #if 0
00134         // try something with the size of the face.
00135 
00136         MT_Vector3 vec1 = 
00137             verts[face_it->m_verts[1]].pos - 
00138             verts[face_it->m_verts[0]].pos;
00139 
00140         MT_Vector3 vec2 = 
00141             verts[face_it->m_verts[2]].pos - 
00142             verts[face_it->m_verts[1]].pos;
00143 
00144         vec1 = vec1.cross(vec2);
00145 
00146         q *= vec1.length();
00147 #endif
00148         quadrics[face_it->m_verts[0]] += q;
00149         quadrics[face_it->m_verts[1]] += q;
00150         quadrics[face_it->m_verts[2]] += q;
00151     }
00152 
00153     if (preserve_boundaries) {
00154 
00155         // iterate through the edge set and add a boundary quadric to 
00156         // each of the boundary edges vertices.
00157     
00158         vector<LOD_Edge>::const_iterator edge_it = edges.begin();
00159         vector<LOD_Edge>::const_iterator edge_end = edges.end();    
00160 
00161         for (; edge_it != edge_end; ++edge_it) {
00162             if (edge_it->BoundaryEdge()) {
00163 
00164                 // compute a plane perpendicular to the edge and the normal
00165                 // of the edges single polygon.
00166                 const MT_Vector3 & v0 = verts[edge_it->m_verts[0]].pos;
00167                 const MT_Vector3 & v1 = verts[edge_it->m_verts[1]].pos;
00168     
00169                 MT_Vector3 edge_vector = v1 - v0;
00170 
00171                 LOD_FaceInd edge_face = edge_it->OpFace(LOD_EdgeInd::Empty());
00172                 edge_vector = edge_vector.cross(normals[edge_face]);
00173 
00174                 if (!edge_vector.fuzzyZero()) {
00175                     edge_vector.normalize();
00176                 
00177                     LOD_NdQuadric boundary_q(edge_vector, - edge_vector.dot(v0));   
00178                     boundary_q *= 100;              
00179 
00180                     quadrics[edge_it->m_verts[0]] += boundary_q;
00181                     quadrics[edge_it->m_verts[1]] += boundary_q;
00182                 }
00183             }
00184         }
00185     }
00186 
00187     return true;
00188 
00189 };
00190 
00191     void
00192 LOD_NdQuadricEditor::
00193 InitializeHeapKeys(
00194     const LOD_ExternVColorEditor & color_editor
00195 ){
00196     // initiate the heap keys of the edges by computing the edge costs.
00197 
00198     vector<LOD_Edge> &edges = m_mesh.EdgeSet(); 
00199     vector<LOD_NdQuadric> & quadrics = *m_quadrics;
00200 
00201     vector<LOD_Edge>::iterator edge_it = edges.begin();
00202     vector<LOD_Edge>::const_iterator edge_end = edges.end();
00203 
00204     
00205     TNT::Vector<MT_Scalar> target(6,MT_Scalar(0));
00206 
00207     for (; edge_it != edge_end; ++edge_it)  {
00208         
00209         TargetVertex(*edge_it,target,color_editor);
00210         LOD_Edge &e = *edge_it;
00211         const LOD_NdQuadric &q0 = quadrics[e.m_verts[0]];
00212         const LOD_NdQuadric &q1 = quadrics[e.m_verts[1]];
00213 
00214 #if 0
00215         // testing print out target colors.
00216         
00217         std::cout << color_editor.IndexColor(e.m_verts[0]) << "\n";
00218         std::cout << color_editor.IndexColor(e.m_verts[1]) << "\n";
00219 
00220         MT_Vector3 target_color(target[3],target[4],target[5]);
00221 
00222         std::cout << target_color << "\n\n";
00223 #endif
00224 
00225         
00226         e.HeapKey() = -float(q0.Evaluate(target) + q1.Evaluate(target));
00227     }
00228 }
00229 
00230 
00231 
00232 
00233 
00234 
00235     void 
00236 LOD_NdQuadricEditor::
00237 TargetVertex(
00238     const LOD_Edge & e,
00239     TNT::Vector<MT_Scalar> &result,
00240     const LOD_ExternVColorEditor & color_editor
00241 ) const {
00242 
00243     // compute an edge contration target for edge ei
00244     // this is computed by summing it's vertices quadrics and 
00245     // optimizing the result.
00246     vector<LOD_Vertex> &verts = m_mesh.VertexSet();
00247     vector<LOD_NdQuadric> &quadrics = *m_quadrics;
00248 
00249     LOD_VertexInd v0 = e.m_verts[0];
00250     LOD_VertexInd v1 = e.m_verts[1];
00251 
00252     LOD_NdQuadric q0 = quadrics[v0];
00253     q0 += quadrics[v1];
00254 
00255     if (q0.Optimize(result)) {
00256         return;
00257     } else {
00258         // the quadric was degenerate -> just take the average of 
00259         // v0 and v1
00260 
00261         MT_Vector3 t_result = ((verts[v0].pos + verts[v1].pos) * 0.5);
00262         result[0] = t_result[0];
00263         result[1] = t_result[1];
00264         result[2] = t_result[2];
00265         
00266         // do the same for the colors
00267 
00268         MT_Vector3 c0 = color_editor.IndexColor(v0);
00269         MT_Vector3 c1 = color_editor.IndexColor(v0);
00270 
00271         c0 = (c0 + c1) *0.5;
00272         result[3] = c0[0];
00273         result[4] = c0[1];
00274         result[5] = c0[2];
00275 
00276         return ;
00277     }
00278 };
00279 
00280     void
00281 LOD_NdQuadricEditor::
00282 ComputeEdgeCosts(
00283     const vector<LOD_EdgeInd> &edges,
00284     const LOD_ExternVColorEditor & color_editor
00285 ){  
00286     
00287     // for each we compute the target vertex and then compute
00288     // the quadric error e = Q1(v') + Q2(v')
00289     vector<LOD_Edge> &edge_set = m_mesh.EdgeSet();
00290 
00291     vector<LOD_NdQuadric> &quadrics = *m_quadrics;
00292 
00293     vector<LOD_EdgeInd>::const_iterator edge_it = edges.begin();
00294     vector<LOD_EdgeInd>::const_iterator edge_end = edges.end();
00295 
00296     TNT::Vector<MT_Scalar> target(6,MT_Scalar(0));
00297 
00298     for (; edge_it != edge_end; ++edge_it)  {
00299         
00300         TargetVertex(edge_set[*edge_it],target,color_editor);
00301 
00302         LOD_Edge &e = edge_set[*edge_it];
00303         const LOD_NdQuadric &q0 = quadrics[e.m_verts[0]];
00304         const LOD_NdQuadric &q1 = quadrics[e.m_verts[1]];
00305         
00306         e.HeapKey() = -float(q0.Evaluate(target) + q1.Evaluate(target));
00307     }
00308 };
00309     
00310         
00311 
00312 
00313         
00314 
00315 
00316 
00317 
00318 
00319     
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339