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_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