@@ -216,6 +216,44 @@ namespace diffCheck::geometry
216216 this ->Normals .push_back (normal);
217217 }
218218
219+ void DFPointCloud::Crop (const Eigen::Vector3d &minBound, const Eigen::Vector3d &maxBound)
220+ {
221+ auto O3DPointCloud = this ->Cvt2O3DPointCloud ();
222+ auto O3DPointCloudCropped = O3DPointCloud->Crop (open3d::geometry::AxisAlignedBoundingBox (minBound, maxBound));
223+ this ->Points .clear ();
224+ for (auto &point : O3DPointCloudCropped->points_ )
225+ this ->Points .push_back (point);
226+ this ->Colors .clear ();
227+ for (auto &color : O3DPointCloudCropped->colors_ )
228+ this ->Colors .push_back (color);
229+ this ->Normals .clear ();
230+ for (auto &normal : O3DPointCloudCropped->normals_ )
231+ this ->Normals .push_back (normal);
232+ }
233+
234+ void DFPointCloud::Crop (const std::vector<Eigen::Vector3d> &corners)
235+ {
236+ if (corners.size () != 8 )
237+ throw std::invalid_argument (" The corners vector must contain exactly 8 points." );
238+ open3d::geometry::OrientedBoundingBox obb = open3d::geometry::OrientedBoundingBox::CreateFromPoints (corners);
239+ auto O3DPointCloud = this ->Cvt2O3DPointCloud ();
240+ auto O3DPointCloudCropped = O3DPointCloud->Crop (obb);
241+ this ->Points .clear ();
242+ for (auto &point : O3DPointCloudCropped->points_ )
243+ this ->Points .push_back (point);
244+ this ->Colors .clear ();
245+ for (auto &color : O3DPointCloudCropped->colors_ )
246+ this ->Colors .push_back (color);
247+ this ->Normals .clear ();
248+ for (auto &normal : O3DPointCloudCropped->normals_ )
249+ this ->Normals .push_back (normal);
250+ }
251+
252+ DFPointCloud DFPointCloud::Duplicate () const
253+ {
254+ return DFPointCloud (this ->Points , this ->Colors , this ->Normals );
255+ }
256+
219257 void DFPointCloud::UniformDownsample (int everyKPoints)
220258 {
221259 auto O3DPointCloud = this ->Cvt2O3DPointCloud ();
@@ -258,6 +296,86 @@ namespace diffCheck::geometry
258296 return bboxPts;
259297 }
260298
299+ void DFPointCloud::SubtractPoints (const DFPointCloud &pointCloud, double distanceThreshold)
300+ {
301+ if (this ->Points .size () == 0 || pointCloud.Points .size () == 0 )
302+ throw std::invalid_argument (" One of the point clouds is empty." );
303+
304+ auto O3DSourcePointCloud = this ->Cvt2O3DPointCloud ();
305+ auto O3DTargetPointCloud = std::make_shared<DFPointCloud>(pointCloud)->Cvt2O3DPointCloud ();
306+ auto O3DResultPointCloud = std::make_shared<open3d::geometry::PointCloud>();
307+
308+ open3d::geometry::KDTreeFlann threeDTree;
309+ threeDTree.SetGeometry (*O3DTargetPointCloud);
310+ std::vector<int > indices;
311+ std::vector<double > distances;
312+ for (const auto &point : O3DSourcePointCloud->points_ )
313+ {
314+ threeDTree.SearchRadius (point, distanceThreshold, indices, distances);
315+ if (indices.empty ())
316+ {
317+ O3DResultPointCloud->points_ .push_back (point);
318+ if (O3DSourcePointCloud->HasColors ())
319+ {
320+ O3DResultPointCloud->colors_ .push_back (O3DSourcePointCloud->colors_ [&point - &O3DSourcePointCloud->points_ [0 ]]);
321+ }
322+ if (O3DSourcePointCloud->HasNormals ())
323+ {
324+ O3DResultPointCloud->normals_ .push_back (O3DSourcePointCloud->normals_ [&point - &O3DSourcePointCloud->points_ [0 ]]);
325+ }
326+ }
327+ }
328+ this ->Points .clear ();
329+ for (auto &point : O3DResultPointCloud->points_ )
330+ this ->Points .push_back (point);
331+ if (O3DResultPointCloud->HasColors ())
332+ {
333+ this ->Colors .clear ();
334+ for (auto &color : O3DResultPointCloud->colors_ ){this ->Colors .push_back (color);};
335+ }
336+ if (O3DResultPointCloud->HasNormals ())
337+ {
338+ this ->Normals .clear ();
339+ for (auto &normal : O3DResultPointCloud->normals_ ){this ->Normals .push_back (normal);};
340+ }
341+ }
342+
343+ diffCheck::geometry::DFPointCloud DFPointCloud::Intersect (const DFPointCloud &pointCloud, double distanceThreshold)
344+ {
345+ if (this ->Points .size () == 0 || pointCloud.Points .size () == 0 )
346+ throw std::invalid_argument (" One of the point clouds is empty." );
347+
348+ auto O3DSourcePointCloud = this ->Cvt2O3DPointCloud ();
349+ auto O3DTargetPointCloud = std::make_shared<DFPointCloud>(pointCloud)->Cvt2O3DPointCloud ();
350+ auto O3DResultPointCloud = std::make_shared<open3d::geometry::PointCloud>();
351+
352+ open3d::geometry::KDTreeFlann threeDTree;
353+ threeDTree.SetGeometry (*O3DTargetPointCloud);
354+ std::vector<int > indices;
355+ std::vector<double > distances;
356+ for (const auto &point : O3DSourcePointCloud->points_ )
357+ {
358+ threeDTree.SearchRadius (point, distanceThreshold, indices, distances);
359+ if (!indices.empty ())
360+ {
361+ O3DResultPointCloud->points_ .push_back (point);
362+ if (O3DSourcePointCloud->HasColors ())
363+ {
364+ O3DResultPointCloud->colors_ .push_back (O3DSourcePointCloud->colors_ [&point - &O3DSourcePointCloud->points_ [0 ]]);
365+ }
366+ if (O3DSourcePointCloud->HasNormals ())
367+ {
368+ O3DResultPointCloud->normals_ .push_back (O3DSourcePointCloud->normals_ [&point - &O3DSourcePointCloud->points_ [0 ]]);
369+ }
370+ }
371+ }
372+ diffCheck::geometry::DFPointCloud result;
373+ result.Points = O3DResultPointCloud->points_ ;
374+ result.Colors = O3DResultPointCloud->colors_ ;
375+ result.Normals = O3DResultPointCloud->normals_ ;
376+ return result;
377+ }
378+
261379 void DFPointCloud::ApplyTransformation (const diffCheck::transformation::DFTransformation &transformation)
262380 {
263381 auto O3DPointCloud = this ->Cvt2O3DPointCloud ();
0 commit comments