Add check of neighbors
Add store triangle for debug purpose
This commit is contained in:
parent
ef5c94f90a
commit
62f8ab1cbe
@ -91,6 +91,119 @@ namespace QuadricEdgeCollapse {
|
|||||||
|
|
||||||
using namespace QuadricEdgeCollapse;
|
using namespace QuadricEdgeCollapse;
|
||||||
|
|
||||||
|
// store triangle surrounding to file
|
||||||
|
void store_surround(const char * obj_filename,
|
||||||
|
size_t triangle_index,
|
||||||
|
int depth,
|
||||||
|
const indexed_triangle_set &its,
|
||||||
|
const VertexInfos & v_infos,
|
||||||
|
const EdgeInfos & e_infos)
|
||||||
|
{
|
||||||
|
std::set<size_t> triangles;
|
||||||
|
// triangle index, depth
|
||||||
|
using Item = std::pair<size_t, int>;
|
||||||
|
std::queue<Item> process;
|
||||||
|
process.push({triangle_index, depth});
|
||||||
|
|
||||||
|
while (!process.empty()) {
|
||||||
|
Item item = process.front();
|
||||||
|
process.pop();
|
||||||
|
size_t ti = item.first;
|
||||||
|
auto it = triangles.find(ti);
|
||||||
|
if (it != triangles.end()) continue;
|
||||||
|
triangles.insert(ti);
|
||||||
|
if (item.second == 0) continue;
|
||||||
|
|
||||||
|
const Vec3i &t = its.indices[ti];
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
const auto &v_info = v_infos[t[i]];
|
||||||
|
for (size_t d = 0; d < v_info.count; ++d) {
|
||||||
|
size_t ei = v_info.start + d;
|
||||||
|
const auto & e_info = e_infos[ei];
|
||||||
|
auto it = triangles.find(e_info.t_index);
|
||||||
|
if (it != triangles.end()) continue;
|
||||||
|
process.push({e_info.t_index, item.second - 1});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<size_t> trs;
|
||||||
|
trs.reserve(triangles.size());
|
||||||
|
for (size_t ti : triangles) trs.push_back(ti);
|
||||||
|
its_store_triangles(its, obj_filename, trs);
|
||||||
|
//its_write_obj(its,"original.obj");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_neighbors(const indexed_triangle_set &its,
|
||||||
|
const TriangleInfos & t_infos,
|
||||||
|
const VertexInfos & v_infos,
|
||||||
|
const EdgeInfos & e_infos)
|
||||||
|
{
|
||||||
|
VertexInfos v_infos2(v_infos.size());
|
||||||
|
size_t count_indices = 0;
|
||||||
|
|
||||||
|
for (size_t ti = 0; ti < its.indices.size(); ti++) {
|
||||||
|
if (t_infos[ti].is_deleted()) continue;
|
||||||
|
++count_indices;
|
||||||
|
const Triangle &t = its.indices[ti];
|
||||||
|
for (size_t e = 0; e < 3; e++) {
|
||||||
|
VertexInfo &v_info = v_infos2[t[e]];
|
||||||
|
++v_info.count; // triangle count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t triangle_start = 0;
|
||||||
|
for (VertexInfo &v_info : v_infos2) {
|
||||||
|
v_info.start = triangle_start;
|
||||||
|
triangle_start += v_info.count;
|
||||||
|
// set filled vertex to zero
|
||||||
|
v_info.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create reference
|
||||||
|
EdgeInfos e_infos2(count_indices * 3);
|
||||||
|
for (size_t ti = 0; ti < its.indices.size(); ti++) {
|
||||||
|
if (t_infos[ti].is_deleted()) continue;
|
||||||
|
const Triangle &t = its.indices[ti];
|
||||||
|
for (size_t j = 0; j < 3; ++j) {
|
||||||
|
VertexInfo &v_info = v_infos2[t[j]];
|
||||||
|
size_t ei = v_info.start + v_info.count;
|
||||||
|
assert(ei < e_infos2.size());
|
||||||
|
EdgeInfo &e_info = e_infos2[ei];
|
||||||
|
e_info.t_index = ti;
|
||||||
|
e_info.edge = j;
|
||||||
|
++v_info.count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t vi = 0; vi < its.vertices.size(); vi++) {
|
||||||
|
const VertexInfo &v_info = v_infos[vi];
|
||||||
|
if (v_info.is_deleted()) continue;
|
||||||
|
const VertexInfo &v_info2 = v_infos2[vi];
|
||||||
|
if (v_info.count != v_info2.count) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
EdgeInfos eis;
|
||||||
|
eis.reserve(v_info.count);
|
||||||
|
std::copy(e_infos.begin() + v_info.start,
|
||||||
|
e_infos.begin() + v_info.start + v_info.count,
|
||||||
|
std::back_inserter(eis));
|
||||||
|
auto compare = [](const EdgeInfo &ei1, const EdgeInfo &ei2) {
|
||||||
|
return ei1.t_index < ei2.t_index;
|
||||||
|
};
|
||||||
|
std::sort(eis.begin(), eis.end(), compare);
|
||||||
|
std::sort(e_infos2.begin() + v_info2.start,
|
||||||
|
e_infos2.begin() + v_info2.start + v_info2.count,
|
||||||
|
compare);
|
||||||
|
for (size_t ei = 0; ei < v_info.count; ++ei) {
|
||||||
|
if (eis[ei].t_index != e_infos2[ei + v_info2.start].t_index) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Slic3r::its_quadric_edge_collapse(
|
void Slic3r::its_quadric_edge_collapse(
|
||||||
indexed_triangle_set & its,
|
indexed_triangle_set & its,
|
||||||
uint32_t triangle_count,
|
uint32_t triangle_count,
|
||||||
@ -117,6 +230,9 @@ void Slic3r::its_quadric_edge_collapse(
|
|||||||
throw_on_cancel();
|
throw_on_cancel();
|
||||||
statusfn(status_init_size);
|
statusfn(status_init_size);
|
||||||
|
|
||||||
|
//its_store_triangle(its, "triangle.obj", 1182);
|
||||||
|
//store_surround("triangle_surround1.obj", 1182, 1, its, v_infos, e_infos);
|
||||||
|
|
||||||
// convert from triangle index to mutable priority queue index
|
// convert from triangle index to mutable priority queue index
|
||||||
std::vector<size_t> ti_2_mpqi(its.indices.size(), {0});
|
std::vector<size_t> ti_2_mpqi(its.indices.size(), {0});
|
||||||
auto setter = [&ti_2_mpqi](const Error &e, size_t index) { ti_2_mpqi[e.triangle_index] = index; };
|
auto setter = [&ti_2_mpqi](const Error &e, size_t index) { ti_2_mpqi[e.triangle_index] = index; };
|
||||||
@ -237,8 +353,7 @@ void Slic3r::its_quadric_edge_collapse(
|
|||||||
}
|
}
|
||||||
v_info0.q = q;
|
v_info0.q = q;
|
||||||
|
|
||||||
// fix neighbors
|
// fix neighbors
|
||||||
|
|
||||||
// vertex index of triangle 0 which is not vi0 nor vi1
|
// vertex index of triangle 0 which is not vi0 nor vi1
|
||||||
uint32_t vi_top0 = t0[(t_info0.min_index + 2) % 3];
|
uint32_t vi_top0 = t0[(t_info0.min_index + 2) % 3];
|
||||||
const Triangle &t1 = its.indices[ti1];
|
const Triangle &t1 = its.indices[ti1];
|
||||||
@ -264,6 +379,7 @@ void Slic3r::its_quadric_edge_collapse(
|
|||||||
t_info1.set_deleted();
|
t_info1.set_deleted();
|
||||||
// triangle counter decrementation
|
// triangle counter decrementation
|
||||||
actual_triangle_count-=2;
|
actual_triangle_count-=2;
|
||||||
|
assert(check_neighbors(its, t_infos, v_infos, e_infos));
|
||||||
}
|
}
|
||||||
|
|
||||||
// compact triangle
|
// compact triangle
|
||||||
|
@ -957,6 +957,48 @@ int its_compactify_vertices(indexed_triangle_set &its, bool shrink_to_fit)
|
|||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool its_store_triangle(const indexed_triangle_set &its,
|
||||||
|
const char * obj_filename,
|
||||||
|
size_t triangle_index)
|
||||||
|
{
|
||||||
|
if (its.indices.size() <= triangle_index) return false;
|
||||||
|
Vec3i t = its.indices[triangle_index];
|
||||||
|
indexed_triangle_set its2;
|
||||||
|
its2.indices = {{0, 1, 2}};
|
||||||
|
its2.vertices = {its.vertices[t[0]], its.vertices[t[1]],
|
||||||
|
its.vertices[t[2]]};
|
||||||
|
return its_write_obj(its2, obj_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool its_store_triangles(const indexed_triangle_set &its,
|
||||||
|
const char * obj_filename,
|
||||||
|
const std::vector<size_t> & triangles)
|
||||||
|
{
|
||||||
|
indexed_triangle_set its2;
|
||||||
|
its2.vertices.reserve(triangles.size() * 3);
|
||||||
|
its2.indices.reserve(triangles.size());
|
||||||
|
std::map<size_t, size_t> vertex_map;
|
||||||
|
for (auto ti : triangles) {
|
||||||
|
if (its.indices.size() <= ti) return false;
|
||||||
|
Vec3i t = its.indices[ti];
|
||||||
|
Vec3i new_t;
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
size_t vi = t[i];
|
||||||
|
auto it = vertex_map.find(vi);
|
||||||
|
if (it != vertex_map.end()) {
|
||||||
|
new_t[i] = it->second;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
size_t new_vi = its2.vertices.size();
|
||||||
|
its2.vertices.push_back(its.vertices[vi]);
|
||||||
|
vertex_map[vi] = new_vi;
|
||||||
|
new_t[i] = new_vi;
|
||||||
|
}
|
||||||
|
its2.indices.push_back(new_t);
|
||||||
|
}
|
||||||
|
return its_write_obj(its2, obj_filename);
|
||||||
|
}
|
||||||
|
|
||||||
void its_shrink_to_fit(indexed_triangle_set &its)
|
void its_shrink_to_fit(indexed_triangle_set &its)
|
||||||
{
|
{
|
||||||
its.indices.shrink_to_fit();
|
its.indices.shrink_to_fit();
|
||||||
|
@ -140,6 +140,10 @@ int its_remove_degenerate_faces(indexed_triangle_set &its, bool shrink_to_fit =
|
|||||||
// Remove vertices, which none of the faces references. Return number of freed vertices.
|
// Remove vertices, which none of the faces references. Return number of freed vertices.
|
||||||
int its_compactify_vertices(indexed_triangle_set &its, bool shrink_to_fit = true);
|
int its_compactify_vertices(indexed_triangle_set &its, bool shrink_to_fit = true);
|
||||||
|
|
||||||
|
// store part of index triangle set
|
||||||
|
bool its_store_triangle(const indexed_triangle_set &its, const char *obj_filename, size_t triangle_index);
|
||||||
|
bool its_store_triangles(const indexed_triangle_set &its, const char *obj_filename, const std::vector<size_t>& triangles);
|
||||||
|
|
||||||
std::vector<indexed_triangle_set> its_split(const indexed_triangle_set &its);
|
std::vector<indexed_triangle_set> its_split(const indexed_triangle_set &its);
|
||||||
|
|
||||||
bool its_is_splittable(const indexed_triangle_set &its);
|
bool its_is_splittable(const indexed_triangle_set &its);
|
||||||
|
Loading…
Reference in New Issue
Block a user