[Bf-blender-cvs] [2307f4f05d1] newboolean: More boolean tests pass.
Howard Trickey
noreply at git.blender.org
Sat Jun 13 17:12:15 CEST 2020
Commit: 2307f4f05d1758d67612fad8e1e177115113ecd9
Author: Howard Trickey
Date: Sat Jun 13 11:11:02 2020 -0400
Branches: newboolean
https://developer.blender.org/rB2307f4f05d1758d67612fad8e1e177115113ecd9
More boolean tests pass.
Fixed bug re confusion of how to sort triangles around an edge.
Fixed bug in first tettet test (inconsistent normals in input).
===================================================================
M source/blender/blenlib/intern/boolean.cc
M source/blender/bmesh/tools/bmesh_boolean.c
M tests/gtests/blenlib/BLI_boolean_test.cc
===================================================================
diff --git a/source/blender/blenlib/intern/boolean.cc b/source/blender/blenlib/intern/boolean.cc
index ae2fea81cb1..96e789d5d97 100644
--- a/source/blender/blenlib/intern/boolean.cc
+++ b/source/blender/blenlib/intern/boolean.cc
@@ -551,7 +551,7 @@ static int sort_tris_class(const IndexedTriangle &tri,
const Edge e,
const mpq3 *extra_coord)
{
- const int dbg_level = 0;
+ const int dbg_level = 1;
if (dbg_level > 0) {
std::cout << "classify e = " << e << "\n";
}
@@ -621,7 +621,7 @@ static Array<int> sort_tris_around_edge(const TriMesh &tm,
* be only 3 or 4 - so OK to make copies of arrays instead of swapping
* around in a single array.
*/
- const int dbg_level = 0;
+ const int dbg_level = 2;
if (tris.size() == 0) {
return Array<int>();
}
@@ -682,9 +682,9 @@ static Array<int> sort_tris_around_edge(const TriMesh &tm,
int *p = ans.begin();
if (tris[0] == t0) {
p = std::copy(g1.begin(), g1.end(), p);
- p = std::copy(g3.begin(), g3.end(), p);
+ p = std::copy(g4.begin(), g4.end(), p);
p = std::copy(g2.begin(), g2.end(), p);
- std::copy(g4.begin(), g4.end(), p);
+ std::copy(g3.begin(), g3.end(), p);
}
else {
p = std::copy(g3.begin(), g3.end(), p);
@@ -710,7 +710,7 @@ static void find_cells_from_edge(const TriMesh &tm,
CellsInfo &cinfo,
const Edge e)
{
- const int dbg_level = 0;
+ const int dbg_level = 2;
if (dbg_level > 0) {
std::cout << "find_cells_from_edge " << e << "\n";
}
@@ -755,7 +755,11 @@ static void find_cells_from_edge(const TriMesh &tm,
cell.add_patch(r_index);
cell.add_patch(rnext_index);
if (dbg_level > 0) {
- std::cout << " assigned new cell " << c << " to both\n";
+ std::cout << " made new cell " << c << "\n";
+ std::cout << " p" << r_index << "." << (r_flipped ? "cell_below" : "cell_above") << " = c"
+ << c << "\n";
+ std::cout << " p" << rnext_index << "." << (rnext_flipped ? "cell_above" : "cell_below")
+ << " = c" << c << "\n";
}
}
else if (*r_follow_cell != -1 && *rnext_prev_cell == -1) {
@@ -763,7 +767,8 @@ static void find_cells_from_edge(const TriMesh &tm,
*rnext_prev_cell = c;
cinfo.cell(c).add_patch(rnext_index);
if (dbg_level > 0) {
- std::cout << " assigned r_follow_cell " << c << " to other";
+ std::cout << " p" << r_index << "." << (r_flipped ? "cell_below" : "cell_above") << " = c"
+ << c << "\n";
}
}
else if (*r_follow_cell == -1 && *rnext_prev_cell != -1) {
@@ -771,7 +776,8 @@ static void find_cells_from_edge(const TriMesh &tm,
*r_follow_cell = c;
cinfo.cell(c).add_patch(r_index);
if (dbg_level > 0) {
- std::cout << " assigned rnext_prev_cell " << c << " to other";
+ std::cout << " p" << rnext_index << "." << (rnext_flipped ? "cell_above" : "cwll_below")
+ << " = c" << c << "\n";
}
}
else {
@@ -894,7 +900,7 @@ static int find_ambient_cell(const TriMesh &tm,
int dummy_index = p_sorted_dummy - sorted_tris.begin();
int prev_tri = (dummy_index == 0) ? sorted_tris[sorted_tris.size() - 1] :
sorted_tris[dummy_index - 1];
- int next_tri = (dummy_index == static_cast<int>(sorted_tris.size())) ?
+ int next_tri = (dummy_index == static_cast<int>(sorted_tris.size() - 1)) ?
sorted_tris[0] :
sorted_tris[dummy_index + 1];
if (dbg_level > 0) {
@@ -1136,7 +1142,23 @@ static TriMesh self_boolean(const TriMesh &tm_in, int bool_optype)
extern "C" Boolean_trimesh_output *BLI_boolean_trimesh(const Boolean_trimesh_input *input,
int bool_optype)
{
- constexpr int dbg_level = 1;
+ constexpr int dbg_level = 2;
+ if (dbg_level > 0) {
+ std::cout << "BLI_BOOLEAN_TRIMESH op=";
+ switch (bool_optype) {
+ case BOOLEAN_NONE:
+ std::cout << "none\n";
+ break;
+ case BOOLEAN_ISECT:
+ std::cout << "intersect\n";
+ break;
+ case BOOLEAN_UNION:
+ std::cout << "union\n";
+ break;
+ case BOOLEAN_DIFFERENCE:
+ std::cout << "difference\n";
+ }
+ }
blender::meshintersect::TriMesh tm_in;
tm_in.vert = blender::Array<blender::mpq3>(input->vert_len);
for (int v = 0; v < input->vert_len; ++v) {
@@ -1148,6 +1170,19 @@ extern "C" Boolean_trimesh_output *BLI_boolean_trimesh(const Boolean_trimesh_inp
tm_in.tri[t] = blender::meshintersect::IndexedTriangle(
input->tri[t][0], input->tri[t][1], input->tri[t][2], t);
}
+ if (dbg_level > 1) {
+ std::cout << "Input:\n";
+ std::cout << tm_in.vert.size() << " verts:\n";
+ for (uint v = 0; v < tm_in.vert.size(); ++v) {
+ std::cout << v << ": " << tm_in.vert[v] << "\n";
+ }
+ std::cout << "\n" << tm_in.tri.size() << " tris:\n";
+ for (uint t = 0; t < tm_in.tri.size(); ++t) {
+ std::cout << t << ": " << tm_in.tri[t] << "\n";
+ }
+ std::cout << "\n";
+ blender::meshintersect::write_obj_trimesh(tm_in.vert, tm_in.tri, "boolean_input");
+ }
blender::meshintersect::TriMesh tm_out = self_boolean(tm_in, bool_optype);
if (dbg_level > 0) {
blender::meshintersect::write_html_trimesh(
diff --git a/source/blender/bmesh/tools/bmesh_boolean.c b/source/blender/bmesh/tools/bmesh_boolean.c
index af51f8235fe..ce314dcb854 100644
--- a/source/blender/bmesh/tools/bmesh_boolean.c
+++ b/source/blender/bmesh/tools/bmesh_boolean.c
@@ -68,6 +68,25 @@ static void free_trimesh_input(Boolean_trimesh_input *in)
MEM_freeN(in);
}
+static void apply_trimesh_output_to_bmesh(BMesh *bm, Boolean_trimesh_output *out)
+{
+ /* For now, for testing, just create new BMesh elements for returned subdivided mesh. */
+ int v, t;
+
+ if (out->vert_len > 0 && out->tri_len > 0) {
+ BMVert **new_bmv = MEM_malloc_arrayN(out->vert_len, sizeof(BMVert *), __func__);
+ for (v = 0; v < out->vert_len; v++) {
+ new_bmv[v] = BM_vert_create(bm, out->vert_coord[v], NULL, BM_CREATE_NOP);
+ }
+ for (t = 0; t < out->tri_len; t++) {
+ BMVert *v0 = new_bmv[out->tri[t][0]];
+ BMVert *v1 = new_bmv[out->tri[t][1]];
+ BMVert *v2 = new_bmv[out->tri[t][2]];
+ BM_face_create_quad_tri(bm, v0, v1, v2, NULL, NULL, BM_CREATE_NOP);
+ }
+ }
+}
+
bool BM_mesh_boolean(BMesh *bm,
struct BMLoop *(*looptris)[3],
const int looptris_tot,
@@ -81,9 +100,11 @@ bool BM_mesh_boolean(BMesh *bm,
bm, looptris, looptris_tot, test_fn, user_data);
Boolean_trimesh_output *out = BLI_boolean_trimesh(in, boolean_mode);
BLI_assert(out != NULL);
+ bool intersections_found = out->vert_len != in->vert_len || out->tri_len != in->tri_len;
+ apply_trimesh_output_to_bmesh(bm, out);
free_trimesh_input(in);
BLI_boolean_trimesh_free(out);
- return false;
+ return intersections_found;
}
bool BM_mesh_boolean_knife(BMesh *bm,
@@ -94,27 +115,13 @@ bool BM_mesh_boolean_knife(BMesh *bm,
const bool UNUSED(use_self),
const bool UNUSED(use_separate_all))
{
- int v, t;
-
Boolean_trimesh_input *in = trimesh_input_from_bm(
bm, looptris, looptris_tot, test_fn, user_data);
Boolean_trimesh_output *out = BLI_boolean_trimesh(in, BOOLEAN_NONE);
-
- /* For now, for testing, just create new BMesh elements for returned subdivided mesh. */
- if (out->vert_len > 0 && out->tri_len > 0) {
- BMVert **new_bmv = MEM_malloc_arrayN(out->vert_len, sizeof(BMVert *), __func__);
- for (v = 0; v < out->vert_len; v++) {
- new_bmv[v] = BM_vert_create(bm, out->vert_coord[v], NULL, BM_CREATE_NOP);
- }
- for (t = 0; t < out->tri_len; t++) {
- BMVert *v0 = new_bmv[out->tri[t][0]];
- BMVert *v1 = new_bmv[out->tri[t][1]];
- BMVert *v2 = new_bmv[out->tri[t][2]];
- BM_face_create_quad_tri(bm, v0, v1, v2, NULL, NULL, BM_CREATE_NOP);
- }
- }
-
+ BLI_assert(out != NULL);
+ bool intersections_found = out->vert_len != in->vert_len || out->tri_len != in->tri_len;
+ apply_trimesh_output_to_bmesh(bm, out);
free_trimesh_input(in);
BLI_boolean_trimesh_free(out);
- return false;
+ return intersections_found;
}
diff --git a/tests/gtests/blenlib/BLI_boolean_test.cc b/tests/gtests/blenlib/BLI_boolean_test.cc
index b2b6fa308aa..dd3778d7db2 100644
--- a/tests/gtests/blenlib/BLI_boolean_test.cc
+++ b/tests/gtests/blenlib/BLI_boolean_test.cc
@@ -152,14 +152,14 @@ TEST(eboolean, TetTet)
2.0 0.0 1.0
1.0 2.0 1.0
1.0 1.0 3.0
- 0 1 2
- 0 3 1
- 1 3 2
- 2 3 0
- 4 5 6
- 4 7 5
- 5 7 6
- 6 7 4
+ 0 2 1
+ 0 1 3
+ 1 2 3
+ 2 0 3
+ 4 6 5
+ 4 5 7
+ 5 6 7
+ 6 4 7
)";
BT_input bti(spec);
Boolean_trimesh_output *out = BLI_boolean_trimesh(bti.input(), BOOLEAN_NONE);
@@ -178,3 +178,34 @@ TEST(eboolean, TetTet)
}
BLI_boolean_trimesh_free(out2);
}
+
+TEST(eboolean, TetTet2)
+{
+ const char *spec = R"(8 8
+ 0.0 1.0 -1.0
+ 0.875 -0.5 -1.0
+ -0.875 -0.5 -1.0
+ 0.0 0.0 1.0
+ 0.0 1.0 0.0
+ 0.875 -0.5 0.0
+ -0.875 -0.5 0.0
+ 0.0 0.0 2.0
+ 0 3 1
+ 0 1 2
+ 1 3 2
+ 2 3 0
+ 4 7 5
+ 4 5 6
+ 5 7 6
+ 6 7 4
+ )";
+
+ BT_input bti(spec);
+ Boolean_trimesh_output *out = BLI_boolean_trimesh(bti.input(), BOOLEAN_UNION);
+ EXPECT_EQ(out->vert_len, 10);
+ EXPECT_EQ(out->tri_len, 16);
+ if (DO_OBJ) {
+ write_obj(out, "tettet2_union");
+ }
+ BLI_boolean_trimesh_free(out);
+}
More information about the Bf-blender-cvs
mailing list