pcl
pcl copied to clipboard
Support for correspondence estimation with different point types
Fixes #329. Credits for @aichim, @jpapon and @taketwo . Added unit test for XYZ point types.
Still have some doubts:
pcl::registration::CorrespondenceEstimationseems to support with all point types. Is it supposed to work with more weird cases of source and target point types, e.g. between XYZ points types <-> Normal point types? Not sure if this is possible.- Should I also add a test for Normal point types? RGB? Is KDTree flexible enough for this?
LGTM. Can't comment on the point type use cases, never used this class in my projects. I think testing with XYZ points is enough, this verifies that the algorithm is correct.
Seems to work with pcl::Normal to pcl::Normal, but if one of the point types has XYZ data and the other doesn't, e.g. pcl::Normal to pcl::PointNormal, it starts failing. It's probably giving priority to XYZ data.
Gentle reminder. This is good for review and merge.
My colleague (Thomas, actually) has recently enquired about the status of this PR. Has anything changed from your side in the last... two years? Maybe rebase, check CI results, and merge?
I'll have a new look at it later today with fresh eyes.
This is all I managed to do before the weekend. I circumvented the unnecessary copy discussed in #329 with the use of a helper specialized struct. I verified that it performs no copy when the point type is the same and it invokes copyPoint (through nearestKSearchT) in the opposite case.
That helper struct might require some reorganization though. I can't enclose it inside the CorrespondenceEstimation, because I lose the ability to specialize it.
Nevertheless, the proof of concept is here. Now we need to decide how to tidy up things.
I wonder why don't we apply this same specialization trick directly to KdTree::nearestKSearchT() function?
No doubt that it would make more sense. On C++14 migration it will require a cleanup.
Anything else you see out of place?
No doubt that it would make more sense. On C++14 migration it will require a cleanup.
Don't understand. Do you mean we can not implement it now?
Anything else you see out of place?
No, everything else looks good.
Yes I can. Only mid next week though. I'm restricted to a tablet for the duration of the weekend.
I noticed I need to improve the doxygen documentation and perhaps try some obscure cases under which only the normals are the common fields.
Ah, OK!
Just had a quick look at things and applying this change will require to modify search/search.h for nearestKSearch(T) and radiusSearch(T), but also replicate the same approach on kdtree/kdtree.h. This will take more time than anticipated.
I don't know how comfortable you are with template stuff, so here is a quick snippet:
template <typename PointTDiff, typename boost::enable_if<boost::is_same<PointT, PointTDiff>, int>::type = 0> inline int
This is the template line for the version where point types are the same. For the opposite case just replace "enable" with "disable".
Included your comment regarding the enable_if, disable_if.
I also realized why the tests failed (one year ago) for anything other than point XYZ types. The KdTree's derived from Search are all for "simple" XYZ queries. For ND queries, one needs to use the KdTree from the kdtree module. Correspondence estimation uses the former.
Edit: Here's a dump with some extra verbose from the added unit test
$ test/registration/test_correspondence_estimation
[==========] Running 19 tests from 18 test cases.
[----------] Global test environment set-up.
[----------] 2 tests from CorrespondenceEstimation
[ RUN ] CorrespondenceEstimation.CorrespondenceEstimationNormalShooting
[ OK ] CorrespondenceEstimation.CorrespondenceEstimationNormalShooting (3 ms)
[ RUN ] CorrespondenceEstimation.CorrespondenceEstimationSetSearchMethod
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
[ OK ] CorrespondenceEstimation.CorrespondenceEstimationSetSearchMethod (0 ms)
[----------] 2 tests from CorrespondenceEstimation (3 ms total)
[----------] 1 test from CorrespondenceEstimationTest/0, where TypeParam = pcl::PointXYZ
[ RUN ] CorrespondenceEstimationTest/0.DifferentPointTypes
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
no copy
[ OK ] CorrespondenceEstimationTest/0.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/0 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/1, where TypeParam = pcl::PointXYZI
[ RUN ] CorrespondenceEstimationTest/1.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/1.DifferentPointTypes (1 ms)
[----------] 1 test from CorrespondenceEstimationTest/1 (1 ms total)
[----------] 1 test from CorrespondenceEstimationTest/2, where TypeParam = pcl::PointXYZL
[ RUN ] CorrespondenceEstimationTest/2.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/2.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/2 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/3, where TypeParam = pcl::PointXYZRGBA
[ RUN ] CorrespondenceEstimationTest/3.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/3.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/3 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/4, where TypeParam = pcl::PointXYZRGB
[ RUN ] CorrespondenceEstimationTest/4.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/4.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/4 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/5, where TypeParam = pcl::PointXYZRGBL
[ RUN ] CorrespondenceEstimationTest/5.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/5.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/5 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/6, where TypeParam = pcl::PointXYZHSV
[ RUN ] CorrespondenceEstimationTest/6.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/6.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/6 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/7, where TypeParam = pcl::InterestPoint
[ RUN ] CorrespondenceEstimationTest/7.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/7.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/7 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/8, where TypeParam = pcl::PointNormal
[ RUN ] CorrespondenceEstimationTest/8.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/8.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/8 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/9, where TypeParam = pcl::PointXYZRGBNormal
[ RUN ] CorrespondenceEstimationTest/9.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/9.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/9 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/10, where TypeParam = pcl::PointXYZINormal
[ RUN ] CorrespondenceEstimationTest/10.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/10.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/10 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/11, where TypeParam = pcl::PointXYZLNormal
[ RUN ] CorrespondenceEstimationTest/11.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/11.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/11 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/12, where TypeParam = pcl::PointWithRange
[ RUN ] CorrespondenceEstimationTest/12.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/12.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/12 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/13, where TypeParam = pcl::PointWithViewpoint
[ RUN ] CorrespondenceEstimationTest/13.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/13.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/13 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/14, where TypeParam = pcl::PointWithScale
[ RUN ] CorrespondenceEstimationTest/14.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/14.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/14 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/15, where TypeParam = pcl::PointSurfel
[ RUN ] CorrespondenceEstimationTest/15.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/15.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/15 (0 ms total)
[----------] 1 test from CorrespondenceEstimationTest/16, where TypeParam = pcl::PointDEM
[ RUN ] CorrespondenceEstimationTest/16.DifferentPointTypes
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
Copy happening
[ OK ] CorrespondenceEstimationTest/16.DifferentPointTypes (0 ms)
[----------] 1 test from CorrespondenceEstimationTest/16 (0 ms total)
[----------] Global test environment tear-down
[==========] 19 tests from 18 test cases ran. (4 ms total)
[ PASSED ] 19 tests.
Sorry, I should have been more explicit. There is no need for helper classes. All we need is to replace
template <typename PointTDiff> inline int
nearestKSearchT (const PointTDiff &point, int k,
std::vector<int> &k_indices, std::vector<float> &k_sqr_distances) const
{
PointT p;
copyPoint (point, p);
return (nearestKSearch (p, k, k_indices, k_sqr_distances));
}
with
template <typename PointTDiff, typename boost::enable_if<boost::is_same<PointT, PointTDiff>, int>::type = 0> inline int
nearestKSearchT (const PointTDiff &point, int k,
std::vector<int> &k_indices, std::vector<float> &k_sqr_distances) const
{
return (nearestKSearch (point, k, k_indices, k_sqr_distances));
}
template <typename PointTDiff, typename boost::disable_if<boost::is_same<PointT, PointTDiff>, int>::type = 0> inline int
nearestKSearchT (const PointTDiff &point, int k,
std::vector<int> &k_indices, std::vector<float> &k_sqr_distances) const
{
PointT p;
copyPoint (point, p);
return (nearestKSearch (p, k, k_indices, k_sqr_distances));
}
You can't specialize class methods without specializing the entire class.
This rule does not apply here, because we are specializing not on the class template parameter, but on a method's own parameter. In other words, you can not specialize nearestKSearchT for different PointT classes, however it's absolutely alright to specialize on PointTDiff or auxiliary parameter (like in this case). Just give it a try ;)
I'm trying to verify the what you said in cpp.sh as first step. Here's my snippet so far http://cpp.sh/2x7s4 did I miss the point behind what you described? My class is not templated on anything, just the methods.
Another thing which stands out in what you wrote is this
typename boost::enable_if<boost::is_same<PointT, PointTDiff>, int>::type = 0
How is this valid? You're saying a type is 0.
Ok... there are some additional nuances to what boost::enable_if does. I'll just go and try what you proposed.
Hm, perhaps I'm wrong with my last statement. However, the thing still works, because we are actually not specializing anything! This part which you are wondering about typename boost::enable_if<boost::is_same<PointT, PointTDiff>, int>::type = 0, when the point types are the same, it expands to int = 0. So it becomes an integral template argument. When the types are different, it's a substitution failure and this version of the method is just not considered.
So for the compiler only single unspecialized version of
template<PointDiffT, int = 0> inline int nearestKSearchT()
is visible, so everything is fine.
Your approach is being killed by C++03 :/
error: default template arguments may not be used in function templates without -std=c++11 or -std=gnu++11
If I remove that default setting to = 0 then we get an ambiguous call.
In file included from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/correspondence_estimation.h:480:0,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/registration.h:52,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:47,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/impl/correspondence_estimation.hpp: In instantiation of ‘void pcl::registration::CorrespondenceEstimation<PointSource, PointTarget, Scalar>::determineCorrespondences(pcl::Correspondences&, double) [with PointSource = pcl::PointXYZRGBA; PointTarget = pcl::PointXYZRGBA; Scalar = float; pcl::Correspondences = std::vector<pcl::Correspondence, Eigen::aligned_allocator<pcl::Correspondence> >]’:
/home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:328:1: required from here
/home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/impl/correspondence_estimation.hpp:130:5: error: no matching function for call to ‘pcl::search::KdTree<pcl::PointXYZRGBA, pcl::KdTreeFLANN<pcl::PointXYZRGBA, flann::L2_Simple<float> > >::nearestKSearchT(const pcl::PointXYZRGBA&, int, std::vector<int>&, std::vector<float>&)’
tree_->nearestKSearchT ((*input_)[*idx], 1, index, distance);
^
In file included from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac_model.h:54:0,
from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac.h:45,
from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/ransac.h:44,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:45,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:167:9: note: candidate: template<class PointTDiff, typename boost::disable_if<boost::is_same<pcl::PointXYZRGBA, T2>, int>::type <anonymous> > int pcl::search::Search<PointT>::nearestKSearchT(const PointTDiff&, int, std::vector<int>&, std::vector<float>&) const [with PointTDiff = PointTDiff; typename boost::disable_if<boost::is_same<T1, T2>, int>::type <anonymous> = <enumerator>; PointT = pcl::PointXYZRGBA]
nearestKSearchT (const PointTDiff &point, int k,
^
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:167:9: note: template argument deduction/substitution failed:
In file included from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/correspondence_estimation.h:480:0,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/registration.h:52,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:47,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/impl/correspondence_estimation.hpp:130:5: note: couldn't deduce template parameter ‘<anonymous>’
tree_->nearestKSearchT ((*input_)[*idx], 1, index, distance);
^
In file included from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac_model.h:54:0,
from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac.h:45,
from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/ransac.h:44,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:45,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:177:9: note: candidate: template<class PointTDiff, typename boost::enable_if<boost::is_same<pcl::PointXYZRGBA, T2>, int>::type <anonymous> > int pcl::search::Search<PointT>::nearestKSearchT(const PointTDiff&, int, std::vector<int>&, std::vector<float>&) const [with PointTDiff = PointTDiff; typename boost::enable_if<boost::is_same<T1, T2>, int>::type <anonymous> = <enumerator>; PointT = pcl::PointXYZRGBA]
nearestKSearchT (const PointTDiff &point, int k,
^
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:177:9: note: template argument deduction/substitution failed:
In file included from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/correspondence_estimation.h:480:0,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/registration.h:52,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:47,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/impl/correspondence_estimation.hpp:130:5: note: couldn't deduce template parameter ‘<anonymous>’
tree_->nearestKSearchT ((*input_)[*idx], 1, index, distance);
^
In file included from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac_model.h:54:0,
from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/sac.h:45,
from /home/sergio/Development/3rdparty/pcl/sample_consensus/include/pcl/sample_consensus/ransac.h:44,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:45,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:249:9: note: candidate: template<class PointTDiff> void pcl::search::Search<PointT>::nearestKSearchT(const pcl::PointCloud<PointTDiff>&, const std::vector<int>&, int, std::vector<std::vector<int> >&, std::vector<std::vector<float> >&) const [with PointTDiff = PointTDiff; PointT = pcl::PointXYZRGBA]
nearestKSearchT (const pcl::PointCloud<PointTDiff> &cloud, const std::vector<int>& indices, int k, std::vector< std::vector<int> > &k_indices,
^
/home/sergio/Development/3rdparty/pcl/search/include/pcl/search/search.h:249:9: note: template argument deduction/substitution failed:
In file included from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/correspondence_estimation.h:480:0,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/registration.h:52,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/icp.h:47,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp.h:44,
from /home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/gicp6d.h:46,
from /home/sergio/Development/3rdparty/pcl/registration/src/gicp6d.cpp:39:
/home/sergio/Development/3rdparty/pcl/registration/include/pcl/registration/impl/correspondence_estimation.hpp:130:5: note: ‘const pcl::PointXYZRGBA’ is not derived from ‘const pcl::PointCloud<PointT>’
tree_->nearestKSearchT ((*input_)[*idx], 1, index, distance);
^
Still, this was definitely one of my meta lessons for this year. :+1:
Unless you want to start invoking explicitly nearestKSearchT<PointTDiff, 0> ? Not exactly sexy but it should work in theory.
Damn, true, this requires C++11 :disappointed: OK, then we will use return type SFINAE (prepare for the next meta lesson). Give me a sec to prototype.
Just replace the template line with:
template <typename T> inline typename boost::enable_if<boost::is_same<PointT, T>, int>::type
and disable_if respectively. Should work regardless of C++ standard. It's basically the same, but it makes it harder to read the return type of the function, that's why I normally prefer the first approach.
Quick question, just in case you know it
typename boost::enable_if<boost::is_same<PointT, T>, int>::type
expands to int in case the condition is true, and what happens in the opposite case? Is it something collision free?
Some of the methods are of void type. Should I modify to
typename boost::enable_if<boost::is_same<PointT, T>, void>::type
?
and what happens in the opposite case?
Nothing. It's called "substitution failure" and the function is just silently discarded by the compiler. That's why the technique is called SFINAE (substitution failure is not an error).
Some of the methods are of void type.
Yes, just put void instead of int.
:+1: works. I'll clean it up.
I'll squash my personal commits after review and CI validation.
This pull request has been automatically marked as stale because it hasn't had any activity in the past 60 days. Commenting or adding a new commit to the pull request will revert this.
Come back whenever you have time. We look forward to your contribution.