diff --git a/tests/geometry/surfaces/CMakeLists.txt b/tests/geometry/surfaces/CMakeLists.txt index 50d555053f..18c6d64027 100644 --- a/tests/geometry/surfaces/CMakeLists.txt +++ b/tests/geometry/surfaces/CMakeLists.txt @@ -40,6 +40,7 @@ endif() if ( DGTAL_WITH_POLYSCOPE_VIEWER ) set(POLYSCOPE_VIEWER_TESTS_SRC + testIntegralInvariantTraversal testLocalConvolutionNormalVectorEstimator testTensorVotingViewer) diff --git a/tests/geometry/surfaces/testIntegralInvariantTraversal.cpp b/tests/geometry/surfaces/testIntegralInvariantTraversal.cpp new file mode 100644 index 0000000000..67a6979eb5 --- /dev/null +++ b/tests/geometry/surfaces/testIntegralInvariantTraversal.cpp @@ -0,0 +1,136 @@ +/** + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + **/ + +/** + * @file + * @ingroup Tests + * @author David Coeurjolly (\c david.coeurjolly@liris.cnrs.fr ) + * Laboratoire d'InfoRmatique en Image et Systemes d'information - LIRIS (CNRS, UMR 5205), CNRS, France + * + * @date 2020/03/14 + * + * Functions for testing class IntegralInvariantShortcuts. + * + * This file is part of the DGtal library. + */ + +/////////////////////////////////////////////////////////////////////////////// +#include +#include +#include + +#include "DGtal/base/Common.h" +#include "ConfigTest.h" +#include "DGtalCatch.h" +#include "DGtal/helpers/StdDefs.h" +#include "DGtal/helpers/Shortcuts.h" +#include "DGtal/helpers/ShortcutsGeometry.h" +#include "DGtal/io/viewers/PolyscopeViewer.h" +#include "polyscope/curve_network.h" + +/////////////////////////////////////////////////////////////////////////////// +using namespace std; +using namespace DGtal; +typedef Shortcuts SH3; +typedef ShortcutsGeometry SHG3; + +/////////////////////////////////////////////////////////////////////////////// +// Functions for testing class IntegralInvariantShortcuts. +/////////////////////////////////////////////////////////////////////////////// + +int main() +{ + auto params = SH3::defaultParameters() | SHG3::defaultParameters() | SHG3::parametersGeometryEstimation(); + params( "polynomial", "goursat" )( "gridstep", 1. )( "surfaceTraversal", "BreadthFirst" ); + auto implicit_shape = SH3::makeImplicitShape3D ( params ); + auto digitized_shape = SH3::makeDigitizedImplicitShape3D( implicit_shape, params ); + auto binary_image = SH3::makeBinaryImage( digitized_shape, params ); + auto K = SH3::getKSpace( params ); + auto embedder = SH3::getSCellEmbedder(K); + + trace.info()<<"Binary image "<< *binary_image<< std::endl; + + auto surface = SH3::makeLightDigitalSurface( binary_image, K, params ); + auto surfels = SH3::getSurfelRange( surface, params ); + trace.info() << "Nb surfels= " << surfels.size() << std::endl; + + //Computing some differential quantities + params("r-radius", 3.0); + + trace.beginBlock("II SHG3 (BreadthFirst)"); + auto normals = SHG3::getIINormalVectors(binary_image,surfels,params); + trace.endBlock(); + + //Duplicating params and surfel range + auto paramsdepth= SH3::defaultParameters() | SHG3::defaultParameters(); + paramsdepth( "surfaceTraversal", "DepthFirst" )("r-radius",3.0); + auto surfelsdepth = SH3::getSurfelRange( surface, paramsdepth ); + + trace.beginBlock("II (DepthFirst)"); + auto normalsdepth = SHG3::getIINormalVectors(binary_image,surfelsdepth,paramsdepth); + trace.endBlock(); + + std::vector id(surfels.size()); + auto cpt=0; + for(auto &v: id) + v=cpt++; + + PolyscopeViewer viewer; + std::string objectName = "Surfels BF"; + viewer.draw(surfels, objectName); + viewer.addQuantity(objectName, "Normals (BF)", normals); + viewer.addQuantity(objectName, "Id (BF)", id); + + std::string objectName2 = "Surfels DF"; + viewer.draw(surfelsdepth, objectName2); + viewer.addQuantity(objectName2, "Normals (DF)", normalsdepth); + viewer.addQuantity(objectName2, "Id (BF)", id); + + //Nodes + std::vector bfnodes; + for(auto s: surfels) + bfnodes.push_back(embedder(s)); + std::vector dfnodes; + for(auto s: surfelsdepth) + dfnodes.push_back(embedder(s)); + + std::vector distbf, distdf; + for(auto i = 1 ; i < surfels.size(); ++i) + { + distbf.push_back( ( embedder(surfels[i]) - embedder(surfels[i-1])).norm()); + distdf.push_back( ( embedder(surfelsdepth[i]) - embedder(surfelsdepth[i-1])).norm()); + } + + auto ps= polyscope::registerCurveNetworkLine("BF", bfnodes); + ps->addNodeScalarQuantity("id", id); + ps->addEdgeScalarQuantity("dist", distbf); + auto ps2=polyscope::registerCurveNetworkLine("DF", dfnodes); + ps2->addNodeScalarQuantity("id", id); + ps2->addEdgeScalarQuantity("dist", distdf); + + trace.info()<<"Counting the number of consecutive pairs with distance <= 1.0"<< std::endl; + trace.info()<<"BF strategy = "<< std::count_if(distbf.begin(), distbf.end(), [](double a){ return a-0.000001 <= 1.0;})<< std::endl; + trace.info()<<"DF strategy = "<< std::count_if(distdf.begin(), distdf.end(), [](double a){ return a-0.000001 <= 1.0;})<< std::endl; + + trace.info()<<"Counting the number of consecutive pairs with distance <= sqrt{2}/2"<< std::endl; + trace.info()<<"BF strategy = "<< std::count_if(distbf.begin(), distbf.end(), [](double a){ return a-0.000001 <= sqrt(2.0)/2.0;})<< std::endl; + trace.info()<<"DF strategy = "<< std::count_if(distdf.begin(), distdf.end(), [](double a){ return a-0.000001 <= sqrt(2.0)/2.0;})<< std::endl; + + + viewer.show(); +} + +/** @ingroup Tests **/