Skip to content

Commit af0c8b8

Browse files
commit before rebase
1 parent 73888c9 commit af0c8b8

File tree

2 files changed

+139
-4
lines changed

2 files changed

+139
-4
lines changed

src/diffCheck/segmentation/DFSegmentation.cc

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,119 @@ namespace diffCheck::segmentation
9494

9595
return segments;
9696
}
97+
98+
std::tuple<std::shared_ptr<geometry::DFPointCloud>, std::vector<std::shared_ptr<geometry::DFPointCloud>>> DFSegmentation::AssociateSegments(
99+
std::vector<std::shared_ptr<geometry::DFMesh>> meshFaces,
100+
std::vector<std::shared_ptr<geometry::DFPointCloud>> segments,
101+
double associationThreshold)
102+
{
103+
std::shared_ptr<geometry::DFPointCloud> unifiedPointCloud = std::make_shared<geometry::DFPointCloud>();
104+
std::vector<std::shared_ptr<geometry::DFPointCloud>> segmentsRemainder;
105+
106+
// iterate through the mesh faces given as function argument
107+
for (std::shared_ptr<diffCheck::geometry::DFMesh> face : meshFaces)
108+
{
109+
std::shared_ptr<geometry::DFPointCloud> correspondingSegment;
110+
std::shared_ptr<open3d::geometry::TriangleMesh> o3dFace;
111+
o3dFace = face->Cvt2O3DTriangleMesh();
112+
113+
// Getting the center of the mesh face
114+
Eigen::Vector3d faceCenter;
115+
open3d::geometry::OrientedBoundingBox orientedBoundingBox = o3dFace->GetMinimalOrientedBoundingBox();
116+
faceCenter = orientedBoundingBox.GetCenter();
117+
118+
if (face->NormalsFace.size() == 0)
119+
{
120+
o3dFace->ComputeTriangleNormals();
121+
face->NormalsFace.clear();
122+
for (auto normal : o3dFace->triangle_normals_)
123+
{
124+
face->NormalsFace.push_back(normal.cast<double>());
125+
}
126+
}
127+
128+
// Getting the normal of the mesh face
129+
Eigen::Vector3d faceNormal = face->NormalsFace[0];
130+
131+
// iterate through the segments to find the closest ones compared to the face center taking the normals into account
132+
Eigen::Vector3d segmentCenter;
133+
Eigen::Vector3d segmentNormal;
134+
double faceDistance = std::numeric_limits<double>::max();
135+
for (auto segment : segments)
136+
{
137+
for (auto point : segment->Points)
138+
{
139+
segmentCenter += point;
140+
}
141+
segmentCenter /= segment->GetNumPoints();
142+
143+
for (auto normal : segment->Normals)
144+
{
145+
segmentNormal += normal;
146+
}
147+
segmentNormal.normalize();
148+
149+
double currentDistance = (faceCenter - segmentCenter).norm() / std::abs(segmentNormal.dot(faceNormal));
150+
// if the distance is smaller than the previous one, update the distance and the corresponding segment
151+
if (currentDistance < faceDistance)
152+
{
153+
correspondingSegment = segment;
154+
faceDistance = currentDistance;
155+
}
156+
}
157+
158+
// get the triangles of the face. This is to check if the point is in the face
159+
std::vector<Eigen::Vector3i> faceTriangles = o3dFace->triangles_;
160+
161+
for (Eigen::Vector3d point : correspondingSegment->Points)
162+
{
163+
bool pointInFace = false;
164+
/*
165+
To check if the point is in the face, we take into account all the triangles forming the face.
166+
We calculate the area of each triangle, then check if the sum of the areas of the tree triangles
167+
formed by two of the points of the referencr triangle and our point is equal to the reference triangle area
168+
(within a user-defined margin). If it is the case, the triangle is in the face.
169+
*/
170+
for (Eigen::Vector3i triangle : faceTriangles)
171+
{
172+
// reference triangle
173+
Eigen::Vector3d v0 = o3dFace->vertices_[triangle[0]];
174+
Eigen::Vector3d v1 = o3dFace->vertices_[triangle[1]];
175+
Eigen::Vector3d v2 = o3dFace->vertices_[triangle[2]];
176+
Eigen::Vector3d n = (v1 - v0).cross(v2 - v0);
177+
double referenceTriangleArea = n.norm()*0.5;
178+
179+
// triangle 1
180+
Eigen::Vector3d n1 = (v1 - v0).cross(point - v0);
181+
double area1 = n1.norm()*0.5;
182+
183+
// triangle 2
184+
Eigen::Vector3d n2 = (v2 - v1).cross(point - v1);
185+
double area2 = n2.norm()*0.5;
186+
187+
// triangle 3
188+
Eigen::Vector3d n3 = (v0 - v2).cross(point - v2);
189+
double area3 = n3.norm()*0.5;
190+
191+
double res = ( area1 + area2 + area3 - referenceTriangleArea) / referenceTriangleArea;
192+
if (res < associationThreshold)
193+
{
194+
pointInFace = true;
195+
break;
196+
}
197+
}
198+
if (pointInFace)
199+
{
200+
unifiedPointCloud->Points.push_back(point);
201+
}
202+
}
203+
// removing points from the segment that are in the face
204+
for(Eigen::Vector3d point : unifiedPointCloud->Points)
205+
{
206+
correspondingSegment->Points.erase(std::remove(correspondingSegment->Points.begin(), correspondingSegment->Points.end(), point), correspondingSegment->Points.end());
207+
}
208+
}
209+
return std::make_tuple(unifiedPointCloud, segments);
210+
}
211+
97212
} // namespace diffCheck::segmentation

src/diffCheckApp.cc

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,32 @@ int main()
2727
true);
2828
std::cout << "number of segments:" << segments.size()<< std::endl;
2929

30-
std::shared_ptr<diffCheck::visualizer::Visualizer> vis = std::make_shared<diffCheck::visualizer::Visualizer>();
31-
vis->RenderPcdColorNormals = false;
32-
30+
std::tuple<std::shared_ptr<diffCheck::geometry::DFPointCloud>, std::vector<std::shared_ptr<diffCheck::geometry::DFPointCloud>>> unifiedSegments =
31+
diffCheck::segmentation::DFSegmentation::AssociateSegments(meshSrc, segments, 0.15);
32+
33+
diffCheck::visualizer::Visualizer vis;
34+
vis.AddMesh(meshSrc);
3335
for (auto segment : segments)
3436
vis->AddPointCloud(segment);
3537

36-
vis->Run();
38+
}
39+
}
40+
for(auto mesh : meshSrc)
41+
{
42+
vis.AddMesh(mesh);
43+
}
44+
45+
auto unified = std::get<0>(unifiedSegments);
46+
for (int i = 0; i < unified->Points.size(); i++)
47+
{
48+
unified->Colors.push_back(Eigen::Vector3d(0, 0, 0));
49+
}
50+
vis.AddPointCloud(unified);
51+
52+
auto endTime = std::chrono::high_resolution_clock::now();
53+
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - initTime);
54+
std::cout << "Computation time:" << duration.count() << std::endl;
55+
56+
vis.Run();
3757
return 0;
3858
}

0 commit comments

Comments
 (0)