@@ -97,4 +97,90 @@ namespace diffCheck::segmentation
9797
9898 return segments;
9999 }
100+
101+ std::tuple<std::shared_ptr<geometry::DFPointCloud>, std::vector<std::shared_ptr<geometry::DFPointCloud>>> DFSegmentation::AssociateSegments (
102+ std::vector<std::shared_ptr<geometry::DFMesh>> meshFaces,
103+ std::vector<std::shared_ptr<geometry::DFPointCloud>> segments,
104+ double associationThreshold)
105+ {
106+ std::shared_ptr<geometry::DFPointCloud> unifiedPointCloud = std::make_shared<geometry::DFPointCloud>();
107+ std::vector<std::shared_ptr<geometry::DFPointCloud>> segmentsRemainder;
108+
109+ // iterate through the mesh faces given as function argument
110+ for (auto face : meshFaces)
111+ {
112+ std::shared_ptr<geometry::DFPointCloud> correspondingSegment;
113+
114+ // Getting the center of the mesh face
115+ Eigen::Vector3d faceCenter = Eigen::Vector3d::Zero ();
116+ for (auto vertex : face->Vertices ){faceCenter += vertex;}
117+ faceCenter /= face->GetNumVertices ();
118+
119+ if (face->NormalsFace .size () == 0 )
120+ {
121+ std::cout << " face has no normals, computing normals" << std::endl;
122+ std::shared_ptr<open3d::geometry::TriangleMesh> o3dFace = face->Cvt2O3DTriangleMesh ();
123+ o3dFace->ComputeTriangleNormals ();
124+ face->NormalsFace .clear ();
125+ for (auto normal : o3dFace->triangle_normals_ )
126+ {
127+ face->NormalsFace .push_back (normal.cast <double >());
128+ }
129+ }
130+
131+ // Getting the normal of the mesh face
132+ Eigen::Vector3d faceNormal = face->NormalsFace [0 ];
133+
134+ // iterate through the segments to find the closest ones compared to the face center taking the normals into account
135+ Eigen::Vector3d segmentCenter = Eigen::Vector3d::Zero ();
136+ Eigen::Vector3d segmentNormal = Eigen::Vector3d::Zero ();
137+ double faceDistance = (segments[0 ]->Points [0 ] - faceCenter).norm () / std::pow (std::abs (segments[0 ]->Normals [0 ].dot (faceNormal)), 2 );
138+ int segmentIndex = 0 ;
139+ for (auto segment : segments)
140+ {
141+ for (auto point : segment->Points )
142+ {
143+ segmentCenter += point;
144+ }
145+ segmentCenter /= segment->GetNumPoints ();
146+
147+ if (segment->Normals .size () == 0 )
148+ {
149+ std::shared_ptr<open3d::geometry::PointCloud> o3dSegment = segment->Cvt2O3DPointCloud ();
150+ o3dSegment->EstimateNormals ();
151+ segment->Normals .clear ();
152+ for (auto normal : o3dSegment->normals_ )
153+ {
154+ segment->Normals .push_back (normal.cast <double >());
155+ }
156+ }
157+ for (auto normal : segment->Normals )
158+ {
159+ segmentNormal += normal;
160+ }
161+ segmentNormal.normalize ();
162+
163+ double currentDistance = (faceCenter - segmentCenter).norm () / std::pow (std::abs (segmentNormal.dot (faceNormal)), 2 );
164+ // if the distance is smaller than the previous one, update the distance and the corresponding segment
165+ if (currentDistance < faceDistance)
166+ {
167+ correspondingSegment = segment;
168+ // storing previous segment in the remainder vector
169+ faceDistance = currentDistance;
170+ }
171+ segmentIndex++;
172+ }
173+ // remove the segment fron the segments vector
174+ segments.erase (std::remove (segments.begin (), segments.end (), correspondingSegment), segments.end ());
175+
176+ // Add the closest points of the corresponding segment to the unified point cloud
177+ for (auto point : correspondingSegment->Points )
178+ {
179+ unifiedPointCloud->Points .push_back (point);
180+ correspondingSegment->Points .erase (std::remove (correspondingSegment->Points .begin (), correspondingSegment->Points .end (), point), correspondingSegment->Points .end ());
181+ }
182+ }
183+ return std::make_tuple (unifiedPointCloud, segments);
184+ }
185+
100186} // namespace diffCheck::segmentation
0 commit comments