Subject: CGAL users discussion list
List archive
[cgal-discuss] Fwd: How to do the nearest neighbor search on a Point_set_3 with properties
Chronological Thread
- From: Yaoyu Hu <>
- To:
- Subject: [cgal-discuss] Fwd: How to do the nearest neighbor search on a Point_set_3 with properties
- Date: Wed, 2 Mar 2022 22:06:41 -0500
- Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None ; spf=Pass ; spf=None
- Ironport-data: A9a23:x0+iv6MZuuVNpSHvrR2fkcFynXyQoLVcMsEvi/4bfWQNrUoj3mYGz mIbX2/XOquOZmqkf91/bovi90IG6pKBy95hT3M5pCpnJ55ogZqcVI7Bdi8cHAvLc5adFBo/h yk6QoOdRCzhZiaE/n9BCpC48T8kk/jgqoPUUIYoAAgoLeNfYHpn2EoLd9IR2NYy24DiW1nV5 bsenuWGULOb824sWo4rw/nbwP9flKyaVOQw4zTSzdgS1LPvvyF94KA3fcldHFOkKmVgJdNWc s6YpF2PEsw1yD92Yj+tuu6TnkTn2dc+NyDW4pZdc/DKbhSvOkXe345jXMfwZ3u7hB2yjftJ7 +VcqaeAWDo4EvLsiOcPQQVxRnQW0a1uoNcrIFC6uM2XilXCKj7imqo1Sk4xOoIc96B8BmQmG f4wcmhcKEDewbjvnPTiFbIEascLdKEHOKsfp2BpyiDEVKd2H7jMRqzL4ZlT2zJYasVmR6qHP pdDOGAHgBLoZhdqP2YdFYkFxPaC21b+dx1AuF6JnP9ii4TU5FUpjOKF3MDuUteFTMEQkkeDr X/d5EziExQCPZqezyCE+zSinIfycTjTXYsTEPig8qcvjgTMnSocDxoZUVb9qv684qKjZz5BA 3cG0RIJnbkuz3y6c8jRAD2oo2yWojdJDrK8DNYGwA2Kz6PV5SOQCW4FUiNNZbQaWCkeFWxCO rihz4OBONB/jFGGYSnCqerM/FteLQBQfDBSP3ZVJecQy4C7+Nlbs/7Zcjp0/EeIYjDdHDjxx 3WSqHF7iexM1ogE0KK0+V2BiDWpznQocuLXzlWLNo5GxlkhDGJAW2BOwQaDhRqnBNjBJmRtR FBex6CjABkmVPlhbhClTuQXB62O7P2YKjDailMHN8B/q2r3pyPzJdgLvmEWyKJV3iAsKW+Bj Kj76VM52XOvFCbCgVJfP9joUJxzlcAM6/y8D66FMrKinaSdhCfepH00DaJh92/ql0conMkC1 WSzIK6R4YIhIf0/llKeHr9DuZdyn3hW7TqKGfjTkkr6uZLDOyb9YepUaDOmM7FihIvZ8VW92 4gEbKOilU4PONASlwGNrub/23hRfSZlbX03wuQLHtO+zv1OQzlwW6eMmup6I+SIXc19z4/1w 510YWcAoHKXuJENAVjihqlLZOy9UJBhg2g8OCBwb1+k12JyM4mq5aYbMZAweOB/puBkyPd1S dgDetmBUqwfEGSZp2xFYMmvtpFmeTSqmRmKYHiobT05SJhqGF7E99riSQ3w+XRcFSGwr8Y// +at21qDE5oOTghvFujMb/erww/jtHQRgrMgUE7BI90Vc0LpqdA4Jyv0h/4xAscNNRSTnmvAh 1jKWU8V/LCfrZU0/d/FgbG/g72oS+YuTFBHG2T77KqtMXaI82emx7hGWrnacD3YUlTy5/z+N +hYyvfLMMoHkkxPhIxyHus51qk5/dbu++ZXwwk4TnXGa1OnVuFpLnWch5Uds6RMwvpBvVLzV BvQoZ9VPrKGPM6jG1kUfVJ3YuOG3PASuz/T8fVlfxmgtXEvpOKKARdIIh2BqC1BN78pYokr9 uEs5ZwN4Aulhxt2b9uL0nJO+2KXIiBSWqkrrMtGUoriiw5u0lUbJJKFVXSw75aIZNFBdEItJ 2bM1qbFgr1dwGvEcmYyRSeRh7sD3cxWtUAY1kIGKnSIhsHB2q090ipX/GllVQ9S1BhGj79+N 2UD25eZ/klSE+qERfSvXlxA3ylEDRydv1T1kh4HzTKCCUavUWPJISs2PuPlEIX1NY5DVmAzw V1a4D+NvfXWkAXZ0S47WEojoPvmJTC03hOXg9ipRqxpALFjCQcIQcaSia4gpB7uAMd3j0rCz QWvECCcdoWjXRMtT2YH50V2GFjepN1o5ICPfB25wJ40IA==
- Ironport-hdrordr: A9a23:T8F0IKD5Mn1pPMvlHemV55DYdb4zR+YMi2TDtnoBMCC9F/bzqy nApoV/6faZskdyZJhko6HiBEDiexLhHPxOkO0s1N6ZNWGMhILrFuFfBODZslrd8kPFh4hgPG RbH5SWyuecMbG3t6nHCcCDfeod/A==
- Ironport-phdr: A9a23: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
- Ironport-sdr: XO5nXcOG7x7y/WQgMTGVGzj+UtYD6YiKWpBtXnRHnIGzcpbX4eoq+Gxs2Bhy40gULKcgSs2one qBmoUBk8DY4Ax8kLmqPR10R82SnS29cI6e4YaRmP0ktqaWcquUsP8KT5XXJSI7g0sPgVLBuhSk O4HcE5fAvASglPsVED63IGvc5f13cXY9NsjyMjHAy5fmJsbI0BDM5ysINmB7Dbfbikv9dcqaCG H2ZhKQ6Ow/p6glB6X55w0TbDRC0oAwx74KhQRocDErqhr8K0w7Srevxsz+2QTrb1t4D62U7GJD cxIQyAH5+rTdHA9UXgIpHF2t
I was so dumb that the compiling error in my previous email is due to a typo.
I have updated the sample code, now it compiles. Get the updated code here
Now I have a new problem. If I run the code, I got the following outputs. It seems that the search does not work for me. I must have done something wrong.
========== Outputs. ==========
Hello, test_point_set_nearest_neighbor!
index = 0, point: [ 0 0 0 ], color: [ 100, 100, 100 ]
index = 1, point: [ 0.1 0.1 0.1 ], color: [ 101, 101, 101 ]
index = 2, point: [ 0.2 0.2 0.2 ], color: [ 102, 102, 102 ]
index = 3, point: [ 0.3 0.3 0.3 ], color: [ 103, 103, 103 ]
index = 4, point: [ 0.4 0.4 0.4 ], color: [ 104, 104, 104 ]
index = 5, point: [ 0.5 0.5 0.5 ], color: [ 105, 105, 105 ]
index = 6, point: [ 0.6 0.6 0.6 ], color: [ 106, 106, 106 ]
index = 7, point: [ 0.7 0.7 0.7 ], color: [ 107, 107, 107 ]
index = 8, point: [ 0.8 0.8 0.8 ], color: [ 108, 108, 108 ]
index = 9, point: [ 0.9 0.9 0.9 ], color: [ 109, 109, 109 ]
Found nearest point of 0 0 0:
index = 6, distance = 0, point: [0.6 0.6 0.6 ]
color = [ 106, 106, 106 ]
index = 0, point: [ 0 0 0 ], color: [ 100, 100, 100 ]
index = 1, point: [ 0.1 0.1 0.1 ], color: [ 101, 101, 101 ]
index = 2, point: [ 0.2 0.2 0.2 ], color: [ 102, 102, 102 ]
index = 3, point: [ 0.3 0.3 0.3 ], color: [ 103, 103, 103 ]
index = 4, point: [ 0.4 0.4 0.4 ], color: [ 104, 104, 104 ]
index = 5, point: [ 0.5 0.5 0.5 ], color: [ 105, 105, 105 ]
index = 6, point: [ 0.6 0.6 0.6 ], color: [ 106, 106, 106 ]
index = 7, point: [ 0.7 0.7 0.7 ], color: [ 107, 107, 107 ]
index = 8, point: [ 0.8 0.8 0.8 ], color: [ 108, 108, 108 ]
index = 9, point: [ 0.9 0.9 0.9 ], color: [ 109, 109, 109 ]
Found nearest point of 0 0 0:
index = 6, distance = 0, point: [0.6 0.6 0.6 ]
color = [ 106, 106, 106 ]
========== Outputs end. ==========
Any help is appreciated.
Yaoyu
---------- Forwarded message ---------
From: Yaoyu Hu <>
Date: Wed, Mar 2, 2022 at 6:07 PM
Subject: How to do the nearest neighbor search on a Point_set_3 with properties
To: <>
From: Yaoyu Hu <>
Date: Wed, Mar 2, 2022 at 6:07 PM
Subject: How to do the nearest neighbor search on a Point_set_3 with properties
To: <>
Hi,
On CGAL v5.4, Ubuntu 20.04, g++ 9.3.0.
I'm trying to do the nearest neighbor search on a Point_set_3 object by "dD Spatial Searching". The Point_set_3 has a property for point color. I am trying to follow the example "Using a Point Property Map of a Polygonal Mesh " https://doc.cgal.org/latest/Spatial_searching/index.html#Spatial_searchingUsingSurfaceMesh
The reason for referring to the above example is that I suppose points and colors are saved as property maps in Point_set_3 objects and I need to get the Index of a point from the Point_set_3 object, such that I can use the Index object to retrieve a color object saved in the property map. It looks like the relationship between mesh vertex descriptor and mesh point property.
I have two major questions based on my understanding of how Point_set_3 and "dD Spatial Searching
" work:
(1) Do I need an explicit Point_set_3::Index value to be able to retrieve a property from a property_map of a Point_set_3 object? My current understanding is yes, I need to have a Point_set_3::Index value because the property_map is indexed by Point_set_3::Index objects.
(2) When doing a search by "dD Spatial Searching", if I want to have a Point_set_3::Index as the search result, I need to use things like CGAL::Search_traits_adapter such that the search tree will store Point_set_3::Index for me.
Based on the above thoughts, I have composed a sample code, which currently has some compile errors. I also created a GitHub gist if that is more convenient.
The compile error is shown after the code. The error says that CGAL::Search_traits_adapter needs three template arguments but I only give it one. I cannot understand why it gives this error since there are three template arguments already. I failed to proceed any further and I think it's better to ask for help from experts. I am also uncertain if my usage of "tree" and "search" is correct in the reset of the code.
Can someone help me to resolve the compile error and identify any other errors regarding "tree" and "search"? Thank you so much!
========== Code begins. ==========
#include <array>
#include <iostream>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Orthogonal_k_neighbor_search.h>
#include <CGAL/Search_traits_3.h>
#include <CGAL/Search_traits_adapter.h>
template < typename CloudT, typename ColorMapT >
typename boost::property_traits<ColorMapT>::value_type nearest_color(
const CloudT& cloud,
const ColorMapT& color_map,
const typename CloudT::Point_3& query) {
typedef typename boost::property_traits<ColorMapT>::value_type Color_t;
typedef typename CGAL::Kernel_traits<typename CloudT::Point_3>::Kernel CloudKernel_t;
typedef CGAL::Search_traits_3<CloudKernel_t> SearchTraits_base_t;
typedef CGAL::Search_traits_adapter<
typename CloutT::Index,
typename CloudT::Point_map,
SearchTraits_base_t
> SearchTraits_t;
typedef CGAL::Orthogonal_k_neighbor_search<SearchTraits_t> CloudSearch_t;
typedef CloudSearch_t::Tree CloudSearchTree_t;
typedef CloudSearchTree_t::Splitter CloudSearchSplitter_t;
typedef CloudSearch_t::Distance CloudSearchDistance_t;
// Set up a search tree.
CloudSearchTree_t tree(
cloud.begin(), cloud.end(),
CloudSearchSplitter_t(),
SearchTraits_t( cloud.point_map() ) );
// Search.
CloudSearchDistance_t distance( cloud.point_map() );
CloudSearch_t search( tree, query, 1, 0, true, distance );
const auto& neighbor_point_index = search.begin()->first;
auto& cloud_neighbor_color = color_map[neighbor_point_index];
return cloud_neighbor_color;
}
int main(int argc, char** argv) {
std::cout << "Hello, test_point_set_nearest_neighbor! \n";
typedef std::array< unsigned char, 3 > Color_t;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel_t;
typedef Kernel_t::Point_3 Point_t;
typedef CGAL::Point_set_3<Point_t> PointSet_t;
PointSet_t cloud;
auto [ color_map, flag_added ] = cloud.add_property_map<Color_t>("color");
// Populate the point cloud with color.
#include <iostream>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Orthogonal_k_neighbor_search.h>
#include <CGAL/Search_traits_3.h>
#include <CGAL/Search_traits_adapter.h>
template < typename CloudT, typename ColorMapT >
typename boost::property_traits<ColorMapT>::value_type nearest_color(
const CloudT& cloud,
const ColorMapT& color_map,
const typename CloudT::Point_3& query) {
typedef typename boost::property_traits<ColorMapT>::value_type Color_t;
typedef typename CGAL::Kernel_traits<typename CloudT::Point_3>::Kernel CloudKernel_t;
typedef CGAL::Search_traits_3<CloudKernel_t> SearchTraits_base_t;
typedef CGAL::Search_traits_adapter<
typename CloutT::Index,
typename CloudT::Point_map,
SearchTraits_base_t
> SearchTraits_t;
typedef CGAL::Orthogonal_k_neighbor_search<SearchTraits_t> CloudSearch_t;
typedef CloudSearch_t::Tree CloudSearchTree_t;
typedef CloudSearchTree_t::Splitter CloudSearchSplitter_t;
typedef CloudSearch_t::Distance CloudSearchDistance_t;
// Set up a search tree.
CloudSearchTree_t tree(
cloud.begin(), cloud.end(),
CloudSearchSplitter_t(),
SearchTraits_t( cloud.point_map() ) );
// Search.
CloudSearchDistance_t distance( cloud.point_map() );
CloudSearch_t search( tree, query, 1, 0, true, distance );
const auto& neighbor_point_index = search.begin()->first;
auto& cloud_neighbor_color = color_map[neighbor_point_index];
return cloud_neighbor_color;
}
int main(int argc, char** argv) {
std::cout << "Hello, test_point_set_nearest_neighbor! \n";
typedef std::array< unsigned char, 3 > Color_t;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel_t;
typedef Kernel_t::Point_3 Point_t;
typedef CGAL::Point_set_3<Point_t> PointSet_t;
PointSet_t cloud;
auto [ color_map, flag_added ] = cloud.add_property_map<Color_t>("color");
// Populate the point cloud with color.
// Omitted.
nearest_color( cloud, color_map, Point_t(0, 0, 0) );
return 0;
}
nearest_color( cloud, color_map, Point_t(0, 0, 0) );
return 0;
}
========== Code ends. ==========
========== Compile error begins. ==========
src/test_point_set_nearest_neighbor.cpp: In function ‘typename boost::property_traits<IndexMap>::value_type nearest_color(const CloudT&, const ColorMapT&, const typename CloudT::Point_3&)’:
/ws/src/shimizu_test_reconstruct_surface/src/test_point_set_nearest_neighbor.cpp:26:5: error: wrong number of template arguments (1, should be 3)
/ws/src/shimizu_test_reconstruct_surface/src/test_point_set_nearest_neighbor.cpp:26:5: error: wrong number of template arguments (1, should be 3)
(Later error messages are omitted.)
========== Compile error ends. ==========
Thank you!
Yaoyu
- [cgal-discuss] How to do the nearest neighbor search on a Point_set_3 with properties, Yaoyu Hu, 03/03/2022
- [cgal-discuss] Fwd: How to do the nearest neighbor search on a Point_set_3 with properties, Yaoyu Hu, 03/03/2022
- Re: [cgal-discuss] Fwd: How to do the nearest neighbor search on a Point_set_3 with properties, Sebastien Loriot, 03/04/2022
- Re: [cgal-discuss] Fwd: How to do the nearest neighbor search on a Point_set_3 with properties, Yaoyu Hu, 03/06/2022
- Re: [cgal-discuss] Fwd: How to do the nearest neighbor search on a Point_set_3 with properties, Sebastien Loriot, 03/11/2022
- Re: [cgal-discuss] Fwd: How to do the nearest neighbor search on a Point_set_3 with properties, Yaoyu Hu, 03/06/2022
- Re: [cgal-discuss] Fwd: How to do the nearest neighbor search on a Point_set_3 with properties, Sebastien Loriot, 03/04/2022
- [cgal-discuss] Fwd: How to do the nearest neighbor search on a Point_set_3 with properties, Yaoyu Hu, 03/03/2022
Archive powered by MHonArc 2.6.19+.