00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "meshmodifier.h"
00024
00025 #include <cassert>
00026 #include <cmath>
00027
00028
00029
00030 #ifdef VERBOSE
00031 #include <iostream>
00032 #endif // VERBOSE
00033
00034 using namespace sheep;
00035 using namespace std;
00036
00037 void MeshModifier::ComputeSmoothedVertexNormals(Real smoothing_threshold_angle) {
00038 m_compute_smoothed_vn = true;
00039 m_smoothing_threshold_angle = smoothing_threshold_angle;
00040 }
00041
00042 void MeshModifier::OptimizeMesh(Real vertex_welding_threshold_dist,
00043 Real normal_welding_threshold_angle)
00044 {
00045 m_optimize_mesh = true;
00046 m_vertex_welding_threshold_dist = vertex_welding_threshold_dist;
00047 m_normal_welding_threshold_angle = normal_welding_threshold_angle;
00048 }
00049
00050 MeshModifier::MeshModifier(IMeshBuilder &builder) :
00051 m_builder(builder)
00052 {
00053 m_compute_smoothed_vn = false;
00054 m_optimize_mesh = false;
00055 }
00056
00057 MeshModifier::~MeshModifier() {
00058 }
00059
00060
00061
00062 IMeshBuilder::IGeometryBuilder *MeshModifier::GeometryBuilder() {
00063 if(m_builder.GeometryBuilder())
00064 return this;
00065 else return 0;
00066 }
00067
00068 IMeshBuilder::IMaterialBuilder *MeshModifier::MaterialBuilder() {
00069 if(m_builder.MaterialBuilder())
00070 return this;
00071 else return 0;
00072 }
00073
00074
00075
00076 void MeshModifier::BeginSubMesh(const string &name) {
00077 m_sub_mesh = new sub_mesh();
00078 m_sub_mesh->m_name = name;
00079 m_sub_mesh->m_material = -1;
00080 }
00081
00082 void MeshModifier::EndSubMesh() {
00083
00084 if(m_optimize_mesh) {
00085 #ifdef VERBOSE
00086 cerr << "[MeshModifier] Before optimization:" << endl;
00087 cerr << "[MeshModifier] Vertices: " << m_sub_mesh->m_vertices.size() << endl;
00088 cerr << "[MeshModifier] Normals: " << m_sub_mesh->m_normals.size() << endl;
00089 cerr << "[MeshModifier] Faces: " << m_sub_mesh->m_faces.size() << endl;
00090 cerr << "[MeshModifier] Optimizing faces..." << endl;
00091 #endif // VERBOSE
00092
00093 m_sub_mesh->OptimizeFaces();
00094
00095 #ifdef VERBOSE
00096 cerr << "[MeshModifier] Optimizing vertices..." << endl;
00097 #endif // VERBOSE
00098
00099 m_sub_mesh->OptimizeVertices(m_vertex_welding_threshold_dist);
00100 }
00101
00102
00103 if(m_compute_smoothed_vn) {
00104 #ifdef VERBOSE
00105 cerr << "[MeshModifier] Computing smoothed vertex normals..." << endl;
00106 #endif // VERBOSE
00107
00108 m_sub_mesh->ComputeSmoothedVertexNormals(m_smoothing_threshold_angle);
00109 }
00110
00111
00112 if(m_optimize_mesh) {
00113 #ifdef VERBOSE
00114 cerr << "[MeshModifier] Optimizing normals..." << endl;
00115 #endif // VERBOSE
00116
00117 m_sub_mesh->OptimizeNormals(m_normal_welding_threshold_angle);
00118
00119 #ifdef VERBOSE
00120 cerr << "[MeshModifier] After optimization:" << endl;
00121 cerr << "[MeshModifier] Vertices: " << m_sub_mesh->m_vertices.size() << endl;
00122 cerr << "[MeshModifier] Normals: " << m_sub_mesh->m_normals.size() << endl;
00123 cerr << "[MeshModifier] Faces: " << m_sub_mesh->m_faces.size() << endl;
00124 #endif // VERBOSE
00125 }
00126
00127
00128 m_builder.GeometryBuilder()->BeginSubMesh(m_sub_mesh->m_name);
00129
00130
00131 for(vector<Point3>::const_iterator i = m_sub_mesh->m_vertices.begin(),
00132 e = m_sub_mesh->m_vertices.end(); i != e; ++i)
00133 {
00134 m_builder.GeometryBuilder()->AppendVertex(*i);
00135 }
00136
00137
00138 for(vector<Vector3>::const_iterator i = m_sub_mesh->m_normals.begin(),
00139 e = m_sub_mesh->m_normals.end(); i != e; ++i)
00140 {
00141 m_builder.GeometryBuilder()->AppendNormal(*i);
00142 }
00143
00144
00145 for(vector<Vector2>::const_iterator i = m_sub_mesh->m_texcoords.begin(),
00146 e = m_sub_mesh->m_texcoords.end(); i != e; ++i)
00147 {
00148 m_builder.GeometryBuilder()->AppendTexCoord(*i);
00149 }
00150
00151
00152 for(vector<sub_mesh::face>::const_iterator i = m_sub_mesh->m_faces.begin(),
00153 e = m_sub_mesh->m_faces.end(); i != e; ++i)
00154 {
00155 const FeatureId v[3] = { i->m_v0, i->m_v1, i->m_v2 };
00156 const FeatureId fid = m_builder.GeometryBuilder()->AppendFace(3, v);
00157
00158 if(i->m_n0 != -1) {
00159 const FeatureId vn[3] = { i->m_n0, i->m_n1, i->m_n2 };
00160 m_builder.GeometryBuilder()->SetFaceNormals(fid, 3, vn);
00161 }
00162
00163 if(i->m_t0 != -1) {
00164 const FeatureId vt[3] = { i->m_t0, i->m_t1, i->m_t2 };
00165 m_builder.GeometryBuilder()->SetFaceTexCoords(fid, 3, vt);
00166 }
00167 }
00168
00169 if(m_sub_mesh->m_material != -1)
00170 m_builder.GeometryBuilder()->SetMaterial(m_sub_mesh->m_material);
00171
00172
00173 m_builder.GeometryBuilder()->EndSubMesh();
00174
00175 delete m_sub_mesh;
00176 }
00177
00178 IMeshBuilder::FeatureId MeshModifier::AppendVertex(const Vector3 &v) {
00179 m_sub_mesh->m_vertices.push_back(v);
00180
00181 return m_sub_mesh->m_vertices.size() - 1;
00182 }
00183
00184 IMeshBuilder::FeatureId MeshModifier::AppendNormal(const Vector3 &vn) {
00185 if(m_compute_smoothed_vn)
00186 return -1;
00187
00188 m_sub_mesh->m_normals.push_back(vn);
00189
00190 return m_sub_mesh->m_normals.size() - 1;
00191 }
00192
00193 IMeshBuilder::FeatureId MeshModifier::AppendTexCoord(const Vector2 &vt) {
00194 m_sub_mesh->m_texcoords.push_back(vt);
00195
00196 return m_sub_mesh->m_texcoords.size() - 1;
00197 }
00198
00199 IMeshBuilder::FeatureId MeshModifier::AppendFace(int n, const FeatureId *v) {
00200 assert(n == 3);
00201 assert(v);
00202
00203 sub_mesh::face f;
00204
00205 f.m_v0 = v[0];
00206 f.m_v1 = v[1];
00207 f.m_v2 = v[2];
00208
00209 f.m_n0 = f.m_n1 = f.m_n2 = -1;
00210 f.m_t0 = f.m_t1 = f.m_t2 = -1;
00211
00212 m_sub_mesh->m_faces.push_back(f);
00213
00214 return m_sub_mesh->m_faces.size() - 1;
00215 }
00216
00217 void MeshModifier::SetFaceNormals(FeatureId face, int n, const FeatureId *vn) {
00218 assert(face >= 0 && face < m_sub_mesh->m_faces.size());
00219 assert(n == 3);
00220 assert(vn);
00221
00222 if(!m_compute_smoothed_vn) {
00223 sub_mesh::face &f = m_sub_mesh->m_faces[face];
00224
00225 f.m_n0 = vn[0];
00226 f.m_n1 = vn[1];
00227 f.m_n2 = vn[2];
00228 }
00229 }
00230
00231 void MeshModifier::SetFaceTexCoords(FeatureId face, int n, const FeatureId *vt) {
00232 assert(face >= 0 && face < m_sub_mesh->m_faces.size());
00233 assert(n == 3);
00234 assert(vt);
00235
00236 sub_mesh::face &f = m_sub_mesh->m_faces[face];
00237
00238 f.m_t0 = vt[0];
00239 f.m_t1 = vt[1];
00240 f.m_t2 = vt[2];
00241 }
00242
00243 void MeshModifier::SetMaterial(FeatureId material) {
00244 m_sub_mesh->m_material = material;
00245 }
00246
00247
00248
00249 IMeshBuilder::FeatureId MeshModifier::BeginMaterial(const string &name) {
00250 return m_builder.MaterialBuilder()->BeginMaterial(name);
00251 }
00252
00253 void MeshModifier::EndMaterial() {
00254 m_builder.MaterialBuilder()->EndMaterial();
00255 }
00256
00257 void MeshModifier::SetAmbientColor(Real r, Real g, Real b) {
00258 m_builder.MaterialBuilder()->SetAmbientColor(r, g, b);
00259 }
00260
00261 void MeshModifier::SetDiffuseColor(Real r, Real g, Real b) {
00262 m_builder.MaterialBuilder()->SetDiffuseColor(r, g, b);
00263 }
00264
00265 void MeshModifier::SetSpecularColor(Real r, Real g, Real b) {
00266 m_builder.MaterialBuilder()->SetSpecularColor(r, g, b);
00267 }
00268
00269 void MeshModifier::SetTexture(int w, int h, const unsigned char *texels) {
00270 m_builder.MaterialBuilder()->SetTexture(w, h, texels);
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
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 void MeshModifier::sub_mesh::ComputeSmoothedVertexNormals(Real smoothing_threshold_angle) {
00336 assert(smoothing_threshold_angle >= 0.0);
00337
00338 const Real cos_smoothing_threshold_angle = cos(smoothing_threshold_angle);
00339
00340 const int vertex_count = m_vertices.size();
00341 const int face_count = m_faces.size();
00342
00343
00344
00345 Vector3 *face_normals = new Vector3[face_count];
00346
00347 for(int i = 0; i < face_count; ++i) {
00348 const face &f = m_faces[i];
00349
00350 const Point3 &v0 = m_vertices[f.m_v0];
00351 const Point3 &v1 = m_vertices[f.m_v1];
00352 const Point3 &v2 = m_vertices[f.m_v2];
00353
00354 const Vector3 e0 = v1 - v0;
00355 const Vector3 e1 = v2 - v0;
00356
00357 face_normals[i] = (e0 ^ e1).Normalized();
00358 }
00359
00360
00361
00362 vector<int> *vertex_membership = new vector<int>[vertex_count];
00363
00364 for(int i = 0; i < face_count; ++i) {
00365 const face &f = m_faces[i];
00366
00367 vertex_membership[f.m_v0].push_back(i);
00368 vertex_membership[f.m_v1].push_back(i);
00369 vertex_membership[f.m_v2].push_back(i);
00370 }
00371
00372
00373
00374 vector<Vector3> smoothed_normals;
00375
00376 for(int i = 0; i < vertex_count; ++i) {
00377 const vector<int> &member_faces = vertex_membership[i];
00378
00379
00380 assert(member_faces.size() > 0);
00381
00382 for(int j = 0; j < member_faces.size(); ++j) {
00383 const int face1_index = member_faces[j];
00384 face &face1 = m_faces[face1_index];
00385 const Vector3 &face1_normal = face_normals[face1_index];
00386
00387 const int smoothed_normal_index = smoothed_normals.size();
00388 Vector3 smoothed_normal = face1_normal;
00389
00390 if(face1.m_v0 == i) face1.m_n0 = smoothed_normal_index;
00391 if(face1.m_v1 == i) face1.m_n1 = smoothed_normal_index;
00392 if(face1.m_v2 == i) face1.m_n2 = smoothed_normal_index;
00393
00394 for(int k = 0; k < member_faces.size(); ++k) {
00395 if(j != k) {
00396 const int face2_index = member_faces[k];
00397 face &face2 = m_faces[face2_index];
00398 const Vector3 &face2_normal = face_normals[face2_index];
00399
00400 if(face1_normal * face2_normal > cos_smoothing_threshold_angle) {
00401 smoothed_normal += face2_normal;
00402
00403 if(face2.m_v0 == i) face2.m_n0 = smoothed_normal_index;
00404 if(face2.m_v1 == i) face2.m_n1 = smoothed_normal_index;
00405 if(face2.m_v2 == i) face2.m_n2 = smoothed_normal_index;
00406 }
00407 }
00408 }
00409
00410 smoothed_normal.Normalize();
00411 smoothed_normals.push_back(smoothed_normal);
00412 }
00413 }
00414
00415 delete [] vertex_membership;
00416 delete [] face_normals;
00417
00418
00419 m_normals.resize(smoothed_normals.size());
00420 copy(smoothed_normals.begin(), smoothed_normals.end(), m_normals.begin());
00421 }
00422
00423 void MeshModifier::sub_mesh::OptimizeVertices(Real welding_threshold_dist) {
00424 assert(welding_threshold_dist >= 0.0);
00425
00426 const Real welding_threshold_dist2 = sq(welding_threshold_dist);
00427
00428 vector<Point3> new_vertices;
00429 int *tt = new int[m_vertices.size()];
00430
00431 for(int i = 0; i < m_vertices.size(); ++i) {
00432 const Point3 &p = m_vertices[i];
00433
00434 tt[i] = -1;
00435
00436 for(int j = 0; j < new_vertices.size(); ++j) {
00437 const Real distance2 = (p - new_vertices[j]).SquareNorm();
00438
00439 if(distance2 < welding_threshold_dist2) {
00440 tt[i] = j;
00441 break;
00442 }
00443 }
00444
00445 if(tt[i] == -1) {
00446 tt[i] = new_vertices.size();
00447 new_vertices.push_back(p);
00448 }
00449 }
00450
00451
00452 m_vertices.resize(new_vertices.size());
00453 copy(new_vertices.begin(), new_vertices.end(), m_vertices.begin());
00454
00455
00456 for(vector<face>::iterator i = m_faces.begin(), e = m_faces.end(); i != e; ++i) {
00457 i->m_v0 = tt[i->m_v0];
00458 i->m_v1 = tt[i->m_v1];
00459 i->m_v2 = tt[i->m_v2];
00460 }
00461
00462 delete [] tt;
00463 }
00464
00465 void MeshModifier::sub_mesh::OptimizeNormals(Real welding_threshold_angle) {
00466 assert(welding_threshold_angle >= 0.0);
00467
00468 const Real cos_welding_threshold_angle = cos(welding_threshold_angle);
00469
00470 vector<Vector3> new_normals;
00471 int *tt = new int[m_normals.size()];
00472
00473 for(int i = 0; i < m_normals.size(); ++i) {
00474 const Vector3 &n = m_normals[i];
00475
00476 assert(n.IsUnitLength());
00477
00478 tt[i] = -1;
00479
00480 for(int j = 0; j < new_normals.size(); ++j) {
00481 const Real cos_angle = n * new_normals[j];
00482
00483 if(cos_angle > cos_welding_threshold_angle) {
00484 tt[i] = j;
00485 break;
00486 }
00487 }
00488
00489 if(tt[i] == -1) {
00490 tt[i] = new_normals.size();
00491 new_normals.push_back(n);
00492 }
00493 }
00494
00495
00496 m_normals.resize(new_normals.size());
00497 copy(new_normals.begin(), new_normals.end(), m_normals.begin());
00498
00499
00500 for(vector<face>::iterator i = m_faces.begin(), e = m_faces.end(); i != e; ++i) {
00501 i->m_n0 = tt[i->m_n0];
00502 i->m_n1 = tt[i->m_n1];
00503 i->m_n2 = tt[i->m_n2];
00504 }
00505
00506 delete [] tt;
00507 }
00508
00509 void MeshModifier::sub_mesh::OptimizeFaces() {
00510 vector<face> new_faces;
00511
00512 for(vector<face>::iterator i = m_faces.begin(), e = m_faces.end(); i != e; ++i) {
00513 face &f = *i;
00514
00515 if( f.m_v0 != f.m_v1 &&
00516 f.m_v0 != f.m_v2 &&
00517 f.m_v1 != f.m_v2)
00518 {
00519 new_faces.push_back(f);
00520 }
00521 }
00522
00523
00524 m_faces.resize(new_faces.size());
00525 copy(new_faces.begin(), new_faces.end(), m_faces.begin());
00526 }