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