diff --git a/fast_quadratic_mesh_simplifier.cpp b/fast_quadratic_mesh_simplifier.cpp index bb7985f..d1a65d4 100644 --- a/fast_quadratic_mesh_simplifier.cpp +++ b/fast_quadratic_mesh_simplifier.cpp @@ -32,11 +32,11 @@ void FastQuadraticMeshSimplifier::set_max_iteration_count(const int value) { simplify._max_iteration_count = value; } -double FastQuadraticMeshSimplifier::get_agressiveness() const { - return simplify._agressiveness; +int FastQuadraticMeshSimplifier::get_max_lossless_iteration_count() const { + return simplify._max_lossless_iteration_count; } -void FastQuadraticMeshSimplifier::set_agressiveness(const double value) { - simplify._agressiveness = value; +void FastQuadraticMeshSimplifier::set_max_lossless_iteration_count(const int value) { + simplify._max_lossless_iteration_count = value; } bool FastQuadraticMeshSimplifier::get_enable_smart_link() const { @@ -46,10 +46,10 @@ void FastQuadraticMeshSimplifier::set_enable_smart_link(const bool value) { simplify._enable_smart_link = value; } -bool FastQuadraticMeshSimplifier::get_preserve_border_dges() const { +bool FastQuadraticMeshSimplifier::get_preserve_border_edges() const { return simplify._preserve_border_dges; } -void FastQuadraticMeshSimplifier::set_preserve_border_dges(const bool value) { +void FastQuadraticMeshSimplifier::set_preserve_border_edges(const bool value) { simplify._preserve_border_dges = value; } @@ -67,6 +67,13 @@ void FastQuadraticMeshSimplifier::set_preserve_uv_foldover_edges(const bool valu simplify._preserve_uv_foldover_edges = value; } +int FastQuadraticMeshSimplifier::get_format() const { + return simplify._format; +} +void FastQuadraticMeshSimplifier::set_format(const int value) { + simplify._format = value; +} + void FastQuadraticMeshSimplifier::initialize(const Array &arrays) { simplify.initialize(arrays); } @@ -99,17 +106,17 @@ void FastQuadraticMeshSimplifier::_bind_methods() { ClassDB::bind_method(D_METHOD("set_max_iteration_count", "value"), &FastQuadraticMeshSimplifier::set_max_iteration_count); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_iteration_count"), "set_max_iteration_count", "get_max_iteration_count"); - ClassDB::bind_method(D_METHOD("get_agressiveness"), &FastQuadraticMeshSimplifier::get_agressiveness); - ClassDB::bind_method(D_METHOD("set_agressiveness", "value"), &FastQuadraticMeshSimplifier::set_agressiveness); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "agressiveness"), "set_agressiveness", "get_agressiveness"); + ClassDB::bind_method(D_METHOD("get_max_lossless_iteration_count"), &FastQuadraticMeshSimplifier::get_max_lossless_iteration_count); + ClassDB::bind_method(D_METHOD("set_max_lossless_iteration_count", "value"), &FastQuadraticMeshSimplifier::set_max_lossless_iteration_count); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_lossless_iteration_count"), "set_max_lossless_iteration_count", "get_max_lossless_iteration_count"); ClassDB::bind_method(D_METHOD("get_enable_smart_link"), &FastQuadraticMeshSimplifier::get_enable_smart_link); ClassDB::bind_method(D_METHOD("set_enable_smart_link", "value"), &FastQuadraticMeshSimplifier::set_enable_smart_link); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enable_smart_link"), "set_enable_smart_link", "get_enable_smart_link"); - ClassDB::bind_method(D_METHOD("get_preserve_border_dges"), &FastQuadraticMeshSimplifier::get_preserve_border_dges); - ClassDB::bind_method(D_METHOD("set_preserve_border_dges", "value"), &FastQuadraticMeshSimplifier::set_preserve_border_dges); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "preserve_border_dges"), "set_preserve_border_dges", "get_preserve_border_dges"); + ClassDB::bind_method(D_METHOD("get_preserve_border_edges"), &FastQuadraticMeshSimplifier::get_preserve_border_edges); + ClassDB::bind_method(D_METHOD("set_preserve_border_edges", "value"), &FastQuadraticMeshSimplifier::set_preserve_border_edges); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "preserve_border_edges"), "set_preserve_border_edges", "get_preserve_border_edges"); ClassDB::bind_method(D_METHOD("get_preserve_uv_seam_edges"), &FastQuadraticMeshSimplifier::get_preserve_uv_seam_edges); ClassDB::bind_method(D_METHOD("set_preserve_uv_seam_edges", "value"), &FastQuadraticMeshSimplifier::set_preserve_uv_seam_edges); @@ -118,4 +125,8 @@ void FastQuadraticMeshSimplifier::_bind_methods() { ClassDB::bind_method(D_METHOD("get_preserve_uv_foldover_edges"), &FastQuadraticMeshSimplifier::get_preserve_uv_foldover_edges); ClassDB::bind_method(D_METHOD("set_preserve_uv_foldover_edges", "value"), &FastQuadraticMeshSimplifier::set_preserve_uv_foldover_edges); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "preserve_uv_foldover_edges"), "set_preserve_uv_foldover_edges", "get_preserve_uv_foldover_edges"); + + ClassDB::bind_method(D_METHOD("get_format"), &FastQuadraticMeshSimplifier::get_format); + ClassDB::bind_method(D_METHOD("set_format", "value"), &FastQuadraticMeshSimplifier::set_format); + ADD_PROPERTY(PropertyInfo(Variant::INT, "format"), "set_format", "get_format"); } diff --git a/fast_quadratic_mesh_simplifier.h b/fast_quadratic_mesh_simplifier.h index fc9ebfd..209fe42 100644 --- a/fast_quadratic_mesh_simplifier.h +++ b/fast_quadratic_mesh_simplifier.h @@ -39,14 +39,14 @@ public: int get_max_iteration_count() const; void set_max_iteration_count(const int value); - double get_agressiveness() const; - void set_agressiveness(const double value); + int get_max_lossless_iteration_count() const; + void set_max_lossless_iteration_count(const int value); bool get_enable_smart_link() const; void set_enable_smart_link(const bool value); - bool get_preserve_border_dges() const; - void set_preserve_border_dges(const bool value); + bool get_preserve_border_edges() const; + void set_preserve_border_edges(const bool value); bool get_preserve_uv_seam_edges() const; void set_preserve_uv_seam_edges(const bool value); @@ -54,6 +54,9 @@ public: bool get_preserve_uv_foldover_edges() const; void set_preserve_uv_foldover_edges(const bool value); + int get_format() const; + void set_format(const int value); + void initialize(const Array &arrays); Array get_arrays(); void simplify_mesh(int target_count, double agressiveness = 7, bool verbose = false); diff --git a/simplify.h b/simplify.h index 74c4f00..5e6e71b 100644 --- a/simplify.h +++ b/simplify.h @@ -315,18 +315,10 @@ public: class FQMS { public: - // Global Variables & Strctures - enum Attributes { - NONE, - NORMAL = 2, - TEXCOORD = 4, - COLOR = 8 - }; - struct Triangle { int v[3]; double err[4]; - int deleted, dirty, attr; + int deleted, dirty; vec3f n; vec3f uvs[3]; vec3f uv2s[3]; @@ -352,7 +344,7 @@ public: std::vector materials; int _max_iteration_count; - double _agressiveness; + int _max_lossless_iteration_count; bool _enable_smart_link; bool _preserve_border_dges; bool _preserve_uv_seam_edges; @@ -360,15 +352,7 @@ public: int _format; // Helper functions - /* - double vertex_error(SymetricMatrix q, double x, double y, double z); - double calculate_error(int id_v1, int id_v2, vec3f &p_result); - bool flipped(vec3f p, int i0, int i1, Vertex &v0, Vertex &v1, std::vector &deleted); - void update_uvs(int i0, const Vertex &v, const vec3f &p, std::vector &deleted); - void update_triangles(int i0, Vertex &v, std::vector &deleted, int &deleted_triangles); - void update_mesh(int iteration); - void compact_mesh(); -*/ + // // Main simplification function // @@ -388,9 +372,8 @@ public: int deleted_triangles = 0; std::vector deleted0, deleted1; int triangle_count = triangles.size(); - //int iteration = 0; - //loop(iteration,0,100) - for (int iteration = 0; iteration < 100; iteration++) { + + for (int iteration = 0; iteration < _max_iteration_count; iteration++) { if (triangle_count - deleted_triangles <= target_count) break; // update mesh once in a while @@ -440,6 +423,8 @@ public: if (v0.border != v1.border) continue; + //if (v0.border || v1.border) continue; + // Compute vertex to collapse to vec3f p; calculate_error(i0, i1, p); @@ -453,11 +438,16 @@ public: if (flipped(p, i1, i0, v1, v0, deleted1)) continue; - if ((t.attr & TEXCOORD) == TEXCOORD) { + if ((_format & VisualServer::ARRAY_FORMAT_TEX_UV) != 0) { update_uvs(i0, v0, p, deleted0); update_uvs(i0, v1, p, deleted1); } + if ((_format & VisualServer::ARRAY_FORMAT_TEX_UV2) != 0) { + update_uv2s(i0, v0, p, deleted0); + update_uv2s(i0, v1, p, deleted1); + } + // not flipped, so remove edge v0.p = p; v0.q = v1.q + v0.q; @@ -498,9 +488,8 @@ public: int deleted_triangles = 0; std::vector deleted0, deleted1; //unsigned int triangle_count = triangles.size(); - //int iteration = 0; - //loop(iteration,0,100) - for (int iteration = 0; iteration < 9999; iteration++) { + + for (int iteration = 0; iteration < _max_lossless_iteration_count; iteration++) { // update mesh constantly update_mesh(iteration); // clear dirty flag @@ -555,11 +544,16 @@ public: if (flipped(p, i1, i0, v1, v0, deleted1)) continue; - if ((t.attr & TEXCOORD) == TEXCOORD) { + if ((_format & VisualServer::ARRAY_FORMAT_TEX_UV) != 0) { update_uvs(i0, v0, p, deleted0); update_uvs(i0, v1, p, deleted1); } + if ((_format & VisualServer::ARRAY_FORMAT_TEX_UV2) != 0) { + update_uv2s(i0, v0, p, deleted0); + update_uv2s(i0, v1, p, deleted1); + } + // not flipped, so remove edge v0.p = p; v0.q = v1.q + v0.q; @@ -642,10 +636,30 @@ public: vec3f p1 = vertices[t.v[0]].p; vec3f p2 = vertices[t.v[1]].p; vec3f p3 = vertices[t.v[2]].p; + t.uvs[r.tvertex] = interpolate(p, p1, p2, p3, t.uvs); } } + void update_uv2s(int i0, const Vertex &v, const vec3f &p, std::vector &deleted) { + for (int k = 0; k < v.tcount; ++k) { + Ref &r = refs[v.tstart + k]; + Triangle &t = triangles[r.tid]; + + if (t.deleted) + continue; + + if (deleted[k]) + continue; + + vec3f p1 = vertices[t.v[0]].p; + vec3f p2 = vertices[t.v[1]].p; + vec3f p3 = vertices[t.v[2]].p; + + t.uv2s[r.tvertex] = interpolate(p, p1, p2, p3, t.uv2s); + } + } + // Update triangle connections and edge error after a edge is collapsed void update_triangles(int i0, Vertex &v, std::vector &deleted, int &deleted_triangles) { @@ -968,7 +982,7 @@ public: if ((pindices.size() % 3) != 0) ERR_FAIL_MSG("The index array length must be a multiple of 3 in order to represent triangles."); - std::vector > uvMap; + //std::vector > uvMap; for (int i = 0; i < pindices.size(); i += 3) { Triangle t; @@ -981,8 +995,6 @@ public: t.v[1] = i1; t.v[2] = i2; - t.attr = 0; - if ((_format & VisualServer::ARRAY_FORMAT_COLOR) != 0) { t.color[0] = pcolors[i0]; t.color[1] = pcolors[i1]; @@ -1017,16 +1029,13 @@ public: t.uv2s[2] = vec3f(tv2.x, tv2.y, 0); } - std::vector indices; - indices.push_back(pindices[i]); - indices.push_back(pindices[i + 1]); - indices.push_back(pindices[i + 2]); - uvMap.push_back(indices); - - t.attr |= TEXCOORD; + //std::vector indices; + //indices.push_back(pindices[i]); + //indices.push_back(pindices[i + 1]); + //indices.push_back(pindices[i + 2]); + //uvMap.push_back(indices); t.material = 0; - //geo.triangles.push_back ( tri ); triangles.push_back(t); } @@ -1156,7 +1165,7 @@ public: FQMS() { _max_iteration_count = 100; - _agressiveness = 7.0; + _max_lossless_iteration_count = 9990; _enable_smart_link = true; _preserve_border_dges = false; _preserve_uv_seam_edges = false;