Skip to content

Commit fcc3e9b

Browse files
author
Lars Glud
committed
Add test for nurbs fitting surface pdm and triangulation.
1 parent 6e9460c commit fcc3e9b

2 files changed

Lines changed: 131 additions & 0 deletions

File tree

test/surface/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ PCL_ADD_TEST(surface_poisson test_poisson
3939
LINK_WITH pcl_gtest pcl_io pcl_kdtree pcl_surface pcl_features
4040
ARGUMENTS "${PCL_SOURCE_DIR}/test/bun0.pcd")
4141

42+
if(BUILD_surface_on_nurbs)
43+
PCL_ADD_TEST(surface_on_nurbs test_on_nurbs
44+
FILES test_on_nurbs.cpp
45+
LINK_WITH pcl_gtest pcl_io pcl_kdtree pcl_surface pcl_features pcl_search
46+
ARGUMENTS "${PCL_SOURCE_DIR}/test/bun0.pcd")
47+
endif()
48+
4249
if(QHULL_FOUND)
4350
PCL_ADD_TEST(surface_convex_hull test_convex_hull
4451
FILES test_convex_hull.cpp

test/surface/test_on_nurbs.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* SPDX-License-Identifier: BSD-3-Clause
3+
*
4+
* Point Cloud Library (PCL) - www.pointclouds.org
5+
* Copyright (c) 2025-, Open Perception Inc.
6+
*
7+
* All rights reserved
8+
*/
9+
10+
#include <pcl/test/gtest.h>
11+
12+
#include <pcl/common/common.h>
13+
#include <pcl/io/pcd_io.h>
14+
#include <pcl/point_cloud.h>
15+
#include <pcl/point_types.h>
16+
#include <pcl/surface/on_nurbs/nurbs_data.h>
17+
#include <pcl/surface/on_nurbs/fitting_surface_pdm.h>
18+
#include <pcl/surface/on_nurbs/triangulation.h>
19+
20+
#include <cmath>
21+
22+
using namespace pcl;
23+
using namespace pcl::io;
24+
25+
using Point = pcl::PointXYZ;
26+
27+
PointCloud<Point>::Ptr cloud (new PointCloud<Point>);
28+
29+
void
30+
PointCloud2Vector3d (pcl::PointCloud<Point>::Ptr cloud, pcl::on_nurbs::vector_vec3d &data)
31+
{
32+
for (const auto &p : *cloud)
33+
{
34+
if (!std::isnan (p.x) && !std::isnan (p.y) && !std::isnan (p.z))
35+
data.emplace_back (p.x, p.y, p.z);
36+
}
37+
}
38+
39+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
40+
TEST (PCL, on_nurbs_fitting_surface_pdm)
41+
{
42+
// ############################################################################
43+
// fit B-spline surface
44+
pcl::on_nurbs::NurbsDataSurface data;
45+
PointCloud2Vector3d (cloud, data.interior);
46+
// parameters
47+
unsigned order (3);
48+
unsigned refinement (5);
49+
unsigned iterations (10);
50+
unsigned mesh_resolution (256);
51+
52+
pcl::on_nurbs::FittingSurface::Parameter params;
53+
params.interior_smoothness = 0.2;
54+
params.interior_weight = 1.0;
55+
params.boundary_smoothness = 0.2;
56+
params.boundary_weight = 0.0;
57+
58+
// initialize
59+
printf (" surface fitting ...\n");
60+
ON_NurbsSurface nurbs = pcl::on_nurbs::FittingSurface::initNurbsPCABoundingBox (order, &data);
61+
pcl::on_nurbs::FittingSurface fit (&data, nurbs);
62+
// fit.setQuiet (false); // enable/disable debug output
63+
64+
// mesh for visualization
65+
pcl::PolygonMesh mesh;
66+
pcl::PointCloud<pcl::PointXYZ>::Ptr mesh_cloud (new pcl::PointCloud<pcl::PointXYZ>);
67+
std::vector<pcl::Vertices> mesh_vertices;
68+
std::string mesh_id = "mesh_nurbs";
69+
pcl::on_nurbs::Triangulation::convertSurface2PolygonMesh (fit.m_nurbs, mesh, mesh_resolution);
70+
71+
// surface refinement
72+
for (unsigned i = 0; i < refinement; i++)
73+
{
74+
fit.refine (0);
75+
fit.refine (1);
76+
fit.assemble (params);
77+
fit.solve ();
78+
pcl::on_nurbs::Triangulation::convertSurface2Vertices (fit.m_nurbs, mesh_cloud, mesh_vertices, mesh_resolution);
79+
}
80+
81+
// surface fitting with final refinement level
82+
for (unsigned i = 0; i < iterations; i++)
83+
{
84+
fit.assemble (params);
85+
fit.solve ();
86+
pcl::on_nurbs::Triangulation::convertSurface2Vertices (fit.m_nurbs, mesh_cloud, mesh_vertices, mesh_resolution);
87+
}
88+
89+
ASSERT_EQ (mesh.polygons.size (), 131072);
90+
// All polygons should be triangles
91+
for (const auto & polygon : mesh.polygons)
92+
EXPECT_EQ (polygon.vertices.size (), 3);
93+
94+
EXPECT_EQ (mesh.polygons[10].vertices[0], 5);
95+
EXPECT_EQ (mesh.polygons[10].vertices[1], 6);
96+
EXPECT_EQ (mesh.polygons[10].vertices[2], 263);
97+
98+
EXPECT_EQ (mesh.polygons[200].vertices[0], 100);
99+
EXPECT_EQ (mesh.polygons[200].vertices[1], 101);
100+
EXPECT_EQ (mesh.polygons[200].vertices[2], 358);
101+
102+
EXPECT_EQ (mesh.polygons[1000].vertices[0], 501);
103+
EXPECT_EQ (mesh.polygons[1000].vertices[1], 502);
104+
EXPECT_EQ (mesh.polygons[1000].vertices[2], 759);
105+
}
106+
107+
/* ---[ */
108+
int
109+
main (int argc, char** argv)
110+
{
111+
if (argc < 2)
112+
{
113+
std::cerr << "No test file given. Please download `bun0.pcd` and pass its path to the test." << std::endl;
114+
return (-1);
115+
}
116+
117+
// Load file
118+
loadPCDFile (argv[1], *cloud);
119+
120+
// Testing
121+
testing::InitGoogleTest (&argc, argv);
122+
return (RUN_ALL_TESTS ());
123+
}
124+
/* ]--- */

0 commit comments

Comments
 (0)