Skip to content

Commit b8e0500

Browse files
authored
Merge branch 'isl-org:main' into typing-fixes
2 parents 1654970 + 594f820 commit b8e0500

File tree

3 files changed

+133
-9
lines changed

3 files changed

+133
-9
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
- Fix KDTreeFlann possibly using a dangling pointer instead of internal storage and simplified its members (PR #6734)
3838
- Fix RANSAC early stop if no inliers in a specific iteration (PR #6789)
3939
- Fix segmentation fault (infinite recursion) of DetectPlanarPatches if multiple points have same coordinates (PR #6794)
40+
- `TriangleMesh`'s `+=` operator appends UVs regardless of the presence of existing features (PR #6728)
4041
- Fix build with fmt v10.2.0 (#6783)
4142
- Fix segmentation fault (lambda reference capture) of VisualizerWithCustomAnimation::Play (PR #6804)
4243
- Add O3DVisualizer API to enable collapse control of verts in the side panel (PR #6865)

cpp/open3d/geometry/TriangleMesh.cpp

+11-7
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,12 @@ TriangleMesh &TriangleMesh::Rotate(const Eigen::Matrix3d &R,
5252

5353
TriangleMesh &TriangleMesh::operator+=(const TriangleMesh &mesh) {
5454
if (mesh.IsEmpty()) return (*this);
55-
bool add_textures = HasTriangleUvs() && HasTextures() &&
56-
HasTriangleMaterialIds() && mesh.HasTriangleUvs() &&
57-
mesh.HasTextures() && mesh.HasTriangleMaterialIds();
55+
bool is_empty = IsEmpty();
56+
bool add_triangle_uvs =
57+
mesh.HasTriangleUvs() && (HasTriangleUvs() || is_empty);
58+
bool add_textures_and_material_ids =
59+
mesh.HasTextures() && mesh.HasTriangleMaterialIds() &&
60+
((HasTextures() && HasTriangleMaterialIds()) || is_empty);
5861
size_t old_vert_num = vertices_.size();
5962
MeshBase::operator+=(mesh);
6063
size_t old_tri_num = triangles_.size();
@@ -77,19 +80,21 @@ TriangleMesh &TriangleMesh::operator+=(const TriangleMesh &mesh) {
7780
if (HasAdjacencyList()) {
7881
ComputeAdjacencyList();
7982
}
80-
if (add_textures) {
83+
if (add_triangle_uvs) {
8184
size_t old_tri_uv_num = triangle_uvs_.size();
8285
triangle_uvs_.resize(old_tri_uv_num + mesh.triangle_uvs_.size());
8386
for (size_t i = 0; i < mesh.triangle_uvs_.size(); i++) {
8487
triangle_uvs_[old_tri_uv_num + i] = mesh.triangle_uvs_[i];
8588
}
86-
89+
} else {
90+
triangle_uvs_.clear();
91+
}
92+
if (add_textures_and_material_ids) {
8793
size_t old_tex_num = textures_.size();
8894
textures_.resize(old_tex_num + mesh.textures_.size());
8995
for (size_t i = 0; i < mesh.textures_.size(); i++) {
9096
textures_[old_tex_num + i] = mesh.textures_[i];
9197
}
92-
9398
size_t old_mat_id_num = triangle_material_ids_.size();
9499
triangle_material_ids_.resize(old_mat_id_num +
95100
mesh.triangle_material_ids_.size());
@@ -98,7 +103,6 @@ TriangleMesh &TriangleMesh::operator+=(const TriangleMesh &mesh) {
98103
mesh.triangle_material_ids_[i] + (int)old_tex_num;
99104
}
100105
} else {
101-
triangle_uvs_.clear();
102106
textures_.clear();
103107
triangle_material_ids_.clear();
104108
}

cpp/tests/geometry/TriangleMesh.cpp

+121-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ namespace tests {
2222
/// \param eq_triangle_vertex_order If true then triangles are only equal if the
2323
/// order of the vertices is the same. If false any permutation of the triangle
2424
/// indices is allowed.
25-
void ExpectMeshEQ(const open3d::geometry::TriangleMesh& mesh0,
26-
const open3d::geometry::TriangleMesh& mesh1,
25+
void ExpectMeshEQ(const open3d::geometry::TriangleMesh &mesh0,
26+
const open3d::geometry::TriangleMesh &mesh1,
2727
double threshold = 1e-6,
2828
bool eq_triangle_vertex_order = true) {
2929
ExpectEQ(mesh0.vertices_, mesh1.vertices_, threshold);
@@ -599,6 +599,125 @@ TEST(TriangleMesh, OperatorADD) {
599599
}
600600
}
601601

602+
TEST(TriangleMesh, OperatorAdditionAssignment) {
603+
const size_t size = 100;
604+
const size_t texture_size = 10;
605+
606+
// Define the minimum and maximum bounds for random data generation
607+
Eigen::Vector3d dmin(0.0, 0.0, 0.0);
608+
Eigen::Vector3d dmax(1000.0, 1000.0, 1000.0);
609+
Eigen::Vector3i imin(0, 0, 0);
610+
Eigen::Vector3i imax(size - 1, size - 1, size - 1);
611+
Eigen::Vector2d uvmin(0.0, 0.0);
612+
Eigen::Vector2d uvmax(1.0, 1.0);
613+
614+
// Mesh 0 contains only UVs but no textures and material ids
615+
geometry::TriangleMesh tm0;
616+
tm0.vertices_.resize(size);
617+
tm0.triangles_.resize(size);
618+
tm0.triangle_uvs_.resize(3 * size);
619+
620+
// Mesh 1 contains all of UVS, textures and material ids
621+
geometry::TriangleMesh tm1;
622+
tm1.vertices_.resize(size);
623+
tm1.triangles_.resize(size);
624+
tm1.triangle_uvs_.resize(3 * size);
625+
tm1.triangle_material_ids_.resize(size);
626+
tm1.textures_.resize(texture_size);
627+
628+
// Mesh 2 does not contains any of UVs, textures or material ids
629+
geometry::TriangleMesh tm2;
630+
tm2.vertices_.resize(size);
631+
tm2.triangles_.resize(size);
632+
633+
// Randomly generate data for tm0, tm1 and tm2
634+
Rand(tm0.vertices_, dmin, dmax, 0);
635+
Rand(tm0.triangles_, imin, imax, 0);
636+
std::vector<Eigen::Vector2d, open3d::utility::Vector2d_allocator>
637+
tm0_triangle_uvs(3 * size);
638+
Rand(tm0_triangle_uvs, uvmin, uvmax, 0);
639+
tm0.triangle_uvs_ = std::vector<Eigen::Vector2d>(tm0_triangle_uvs.begin(),
640+
tm0_triangle_uvs.end());
641+
642+
Rand(tm1.vertices_, dmin, dmax, 0);
643+
Rand(tm1.triangles_, imin, imax, 0);
644+
std::vector<Eigen::Vector2d, open3d::utility::Vector2d_allocator>
645+
tm1_triangle_uvs(3 * size);
646+
Rand(tm1_triangle_uvs, uvmin, uvmax, 0);
647+
tm1.triangle_uvs_ = std::vector<Eigen::Vector2d>(tm1_triangle_uvs.begin(),
648+
tm1_triangle_uvs.end());
649+
for (size_t i = 0; i < texture_size; i++) {
650+
geometry::Image texture_image;
651+
texture_image.Prepare(100, 100, 3, 1);
652+
Rand(texture_image.data_, 0, 255, 0);
653+
tm1.textures_[i] = texture_image;
654+
}
655+
Rand(tm1.triangle_material_ids_, 0, texture_size, 0);
656+
657+
Rand(tm2.vertices_, dmin, dmax, 0);
658+
Rand(tm2.triangles_, imin, imax, 0);
659+
660+
geometry::TriangleMesh temp_tm0 = tm0;
661+
geometry::TriangleMesh temp_tm1 = tm1;
662+
geometry::TriangleMesh temp_tm2 = tm2;
663+
// Function to reset values of temp_tm0, temp_tm1 and temp_tm2
664+
auto reset_values = [&tm0, &tm1, &tm2](geometry::TriangleMesh &temp_tm0,
665+
geometry::TriangleMesh &temp_tm1,
666+
geometry::TriangleMesh &temp_tm2) {
667+
temp_tm0 = tm0;
668+
temp_tm1 = tm1;
669+
temp_tm2 = tm2;
670+
};
671+
672+
// Test addition of tm1 with itself
673+
temp_tm1 += tm1;
674+
EXPECT_EQ(temp_tm1.triangles_.size(), 2 * size);
675+
EXPECT_EQ(temp_tm1.triangle_uvs_.size(), 6 * size);
676+
EXPECT_EQ(temp_tm1.vertices_.size(), 2 * size);
677+
EXPECT_EQ(temp_tm1.textures_.size(), 2 * texture_size);
678+
EXPECT_EQ(temp_tm1.triangle_material_ids_.size(), 2 * size);
679+
for (size_t i = 0; i < size; i++) {
680+
ExpectEQ(temp_tm1.vertices_[i], temp_tm1.vertices_[i + size]);
681+
ExpectEQ(temp_tm1.triangles_[i],
682+
(Eigen::Vector3i)(temp_tm1.triangles_[i + size] -
683+
Eigen::Vector3i(size, size, size)));
684+
EXPECT_EQ(temp_tm1.triangle_material_ids_[i],
685+
temp_tm1.triangle_material_ids_[i + size] - texture_size);
686+
}
687+
for (size_t i = 0; i < 3 * size; i++) {
688+
ExpectEQ(temp_tm1.triangle_uvs_[i],
689+
temp_tm1.triangle_uvs_[i + 3 * size]);
690+
}
691+
for (size_t i = 0; i < texture_size; i++) {
692+
ExpectEQ(temp_tm1.textures_[i].data_,
693+
temp_tm1.textures_[i + texture_size].data_);
694+
}
695+
696+
// Test addition of tm0 and tm1
697+
reset_values(temp_tm0, temp_tm1, temp_tm2);
698+
temp_tm0 += tm1;
699+
temp_tm1 += tm0;
700+
ExpectMeshEQ(temp_tm0, temp_tm1);
701+
EXPECT_EQ(temp_tm0.textures_.size(), 0);
702+
EXPECT_EQ(temp_tm0.triangle_material_ids_.size(), 0);
703+
704+
// Test addition of tm1 and tm2
705+
reset_values(temp_tm0, temp_tm1, temp_tm2);
706+
temp_tm1 += tm2;
707+
temp_tm2 += tm1;
708+
ExpectMeshEQ(temp_tm1, temp_tm2);
709+
EXPECT_EQ(temp_tm0.textures_.size(), 0);
710+
EXPECT_EQ(temp_tm0.triangle_material_ids_.size(), 0);
711+
712+
// Test addition of tm2 and tm0
713+
reset_values(temp_tm0, temp_tm1, temp_tm2);
714+
temp_tm2 += tm0;
715+
temp_tm0 += tm2;
716+
ExpectMeshEQ(temp_tm2, temp_tm0);
717+
EXPECT_EQ(temp_tm0.textures_.size(), 0);
718+
EXPECT_EQ(temp_tm0.triangle_material_ids_.size(), 0);
719+
}
720+
602721
TEST(TriangleMesh, ComputeTriangleNormals) {
603722
std::vector<Eigen::Vector3d> ref = {{-0.119231, 0.738792, 0.663303},
604723
{-0.115181, 0.730934, 0.672658},

0 commit comments

Comments
 (0)