CADToPointCloud.cpp
Go to the documentation of this file.
1 
19 #include <CADToPointCloud.h>
20 #include <vtkTriangleFilter.h>
21 #include <vtkPolyDataMapper.h>
22 #include <vtkTriangle.h>
23 
24 CADToPointCloud::CADToPointCloud(const std::string& cad_file_path, int sample_points)
25 {
26  cad_file_path_ = cad_file_path;
27  ROS_INFO("Converting file: %s", cad_file_path_.c_str());
28 
29  extension_ = boost::filesystem::extension(cad_file_path);
30  ROS_INFO("File extension: %s", extension_.c_str());
31 
32  SAMPLE_POINTS_ = sample_points;
33 }
34 
35 void CADToPointCloud::convertCloud(PointCloudRGB::Ptr cloud)
36 {
37  vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
38 
39  if(extension_==".ply")
40  {
41  pcl::PolygonMesh mesh;
42  pcl::io::loadPolygonFilePLY(cad_file_path_, mesh);
43  pcl::io::mesh2vtk(mesh, polydata);
44  }
45  else if(extension_==".obj")
46  {
47  vtkSmartPointer<vtkOBJReader> readerQuery = vtkSmartPointer<vtkOBJReader>::New();
48  readerQuery->SetFileName(cad_file_path_.c_str());
49  readerQuery->Update();
50  polydata = readerQuery->GetOutput();
51  }
52 
53  PointCloudRGB::Ptr CAD_cloud(new PointCloudRGB);
54  uniformSampling(polydata, SAMPLE_POINTS_, *CAD_cloud);
55 
56  if(Utils::isValidCloud(CAD_cloud))
57  {
58  pcl::copyPointCloud(*CAD_cloud, *cloud);
59  }
60  else
61  ROS_ERROR("Error converting CAD mesh to pointcloud");
62 }
63 
64 // Following methods are extracted from Point Cloud Library (PCL)
65 // --> pcl/tools/mesh_sampling.cpp
66 //
67 // Software License Agreement (BSD License)
68 //
69 // Point Cloud Library (PCL) - www.pointclouds.org
70 // Copyright (c) 2010-2011, Willow Garage, Inc.
71 // All rights reserved.
72 //
73 // Redistribution and use in source and binary forms, with or without
74 // modification, are permitted provided that the following conditions
75 // are met:
76 //
77 // * Redistributions of source code must retain the above copyright
78 // notice, this list of conditions and the following disclaimer.
79 // * Redistributions in binary form must reproduce the above
80 // copyright notice, this list of conditions and the following
81 // disclaimer in the documentation and/or other materials provided
82 // with the distribution.
83 // * Neither the name of the copyright holder(s) nor the names of its
84 // contributors may be used to endorse or promote products derived
85 // from this software without specific prior written permission.
86 //
87 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
88 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
89 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
90 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
91 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
92 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
93 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
95 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
96 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
97 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
98 // POSSIBILITY OF SUCH DAMAGE.
99 //
100 
101 void CADToPointCloud::uniformSampling(vtkSmartPointer<vtkPolyData> polydata, size_t n_samples,
102  PointCloudRGB& cloud_out)
103 {
104  //make sure that the polygons are triangles
105  vtkSmartPointer<vtkTriangleFilter> triangleFilter = vtkSmartPointer<vtkTriangleFilter>::New();
106  triangleFilter->SetInputData(polydata);
107  triangleFilter->Update();
108 
109  vtkSmartPointer<vtkPolyDataMapper> triangleMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
110  triangleMapper->SetInputConnection(triangleFilter->GetOutputPort());
111  triangleMapper->Update();
112  polydata = triangleMapper->GetInput();
113 
114  polydata->BuildCells();
115  vtkSmartPointer<vtkCellArray> cells = polydata->GetPolys();
116 
117  double p1[3], p2[3], p3[3], totalArea = 0;
118  std::vector<double> cumulativeAreas(cells->GetNumberOfCells(), 0);
119  size_t i = 0;
120  vtkIdType npts = 0, *ptIds = NULL;
121  for (cells->InitTraversal(); cells->GetNextCell(npts, ptIds); i++)
122  {
123  polydata->GetPoint(ptIds[0], p1);
124  polydata->GetPoint(ptIds[1], p2);
125  polydata->GetPoint(ptIds[2], p3);
126  totalArea += vtkTriangle::TriangleArea(p1, p2, p3);
127  cumulativeAreas[i] = totalArea;
128  }
129 
130  cloud_out.points.resize(n_samples);
131  cloud_out.width = static_cast<pcl::uint32_t>(n_samples);
132  cloud_out.height = 1;
133 
134  for (i = 0; i < n_samples; i++)
135  {
136  Eigen::Vector4f p;
137  randPSurface(polydata, &cumulativeAreas, totalArea, p);
138  cloud_out.points[i].x = p[0];
139  cloud_out.points[i].y = p[1];
140  cloud_out.points[i].z = p[2];
141  }
142 }
143 
144 void CADToPointCloud::randPSurface(vtkPolyData* polydata, std::vector<double>* cumulativeAreas, double totalArea,
145  Eigen::Vector4f& p)
146 {
147  float r = static_cast<float>(uniformDeviate(rand()) * totalArea);
148 
149  std::vector<double>::iterator low = std::lower_bound(cumulativeAreas->begin(), cumulativeAreas->end(), r);
150  vtkIdType el = vtkIdType(low - cumulativeAreas->begin());
151 
152  double A[3], B[3], C[3];
153  vtkIdType npts = 0;
154  vtkIdType* ptIds = NULL;
155  polydata->GetCellPoints(el, npts, ptIds);
156  polydata->GetPoint(ptIds[0], A);
157  polydata->GetPoint(ptIds[1], B);
158  polydata->GetPoint(ptIds[2], C);
159  randomPointTriangle(float(A[0]), float(A[1]), float(A[2]), float(B[0]), float(B[1]), float(B[2]), float(C[0]),
160  float(C[1]), float(C[2]), p);
161 }
162 
164 {
165  double ran = seed * (1.0 / (RAND_MAX + 1.0));
166  return ran;
167 }
168 
169 void CADToPointCloud::randomPointTriangle(float a1, float a2, float a3, float b1, float b2, float b3, float c1,
170  float c2, float c3, Eigen::Vector4f& p)
171 {
172  float r1 = static_cast<float>(uniformDeviate(rand()));
173  float r2 = static_cast<float>(uniformDeviate(rand()));
174  float r1sqr = sqrtf(r1);
175  float OneMinR1Sqr = (1 - r1sqr);
176  float OneMinR2 = (1 - r2);
177  a1 *= OneMinR1Sqr;
178  a2 *= OneMinR1Sqr;
179  a3 *= OneMinR1Sqr;
180  b1 *= OneMinR2;
181  b2 *= OneMinR2;
182  b3 *= OneMinR2;
183  c1 = r1sqr * (r2 * c1 + b1) + a1;
184  c2 = r1sqr * (r2 * c2 + b2) + a2;
185  c3 = r1sqr * (r2 * c3 + b3) + a3;
186  p[0] = c1;
187  p[1] = c2;
188  p[2] = c3;
189  p[3] = 0;
190 }
int SAMPLE_POINTS_
number of points to sample CAD mesh.
static bool isValidCloud(PointCloudXYZ::Ptr cloud)
Check whether cloud contains data and is not empty.
Definition: Utils.cpp:46
std::string extension_
cad file path extension to check formats.
void randPSurface(vtkPolyData *polydata, std::vector< double > *cumulativeAreas, double totalArea, Eigen::Vector4f &p)
Extracted from Point Cloud Library (PCL) –> pcl/tools/mesh_sampling.cpp Copyright (c) 2010-2011...
#define ROS_INFO(...)
std::string cad_file_path_
path to CAD file to be converted.
void convertCloud(PointCloudRGB::Ptr cloud)
convert cloud defined by path in construstor into cloud
double uniformDeviate(int seed)
Extracted from Point Cloud Library (PCL) –> pcl/tools/mesh_sampling.cpp Copyright (c) 2010-2011...
CADToPointCloud(const std::string &cad_file_path, int sample_points)
Construct a new CADToPointCloud object.
#define ROS_ERROR(...)
void uniformSampling(vtkSmartPointer< vtkPolyData > polydata, size_t n_samples, PointCloudRGB &cloud_out)
Extracted from Point Cloud Library (PCL) –> pcl/tools/mesh_sampling.cpp Copyright (c) 2010-2011...
pcl::PointCloud< pcl::PointXYZRGB > PointCloudRGB
void randomPointTriangle(float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3, Eigen::Vector4f &p)
Extracted from Point Cloud Library (PCL) –> pcl/tools/mesh_sampling.cpp Copyright (c) 2010-2011...


leica_point_cloud_processing
Author(s): Ines Lara Sicilia
autogenerated on Fri Feb 5 2021 03:20:30