00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef PCL_SURFACE_ORGANIZED_FAST_MESH_H_
00042 #define PCL_SURFACE_ORGANIZED_FAST_MESH_H_
00043
00044 #include <pcl/common/angles.h>
00045 #include <pcl/surface/reconstruction.h>
00046
00047 namespace pcl
00048 {
00049
00064 template <typename PointInT>
00065 class OrganizedFastMesh : public MeshConstruction<PointInT>
00066 {
00067 public:
00068 typedef boost::shared_ptr<OrganizedFastMesh<PointInT> > Ptr;
00069 typedef boost::shared_ptr<const OrganizedFastMesh<PointInT> > ConstPtr;
00070
00071 using MeshConstruction<PointInT>::input_;
00072 using MeshConstruction<PointInT>::check_tree_;
00073
00074 typedef typename pcl::PointCloud<PointInT>::Ptr PointCloudPtr;
00075
00076 typedef std::vector<pcl::Vertices> Polygons;
00077
00078 enum TriangulationType
00079 {
00080 TRIANGLE_RIGHT_CUT,
00081 TRIANGLE_LEFT_CUT,
00082 TRIANGLE_ADAPTIVE_CUT,
00083 QUAD_MESH
00084 };
00085
00087 OrganizedFastMesh ()
00088 : max_edge_length_squared_ (0.025f)
00089 , triangle_pixel_size_ (1)
00090 , triangulation_type_ (QUAD_MESH)
00091 , store_shadowed_faces_ (false)
00092 , cos_angle_tolerance_ (fabsf (cosf (pcl::deg2rad (12.5f))))
00093 {
00094 check_tree_ = false;
00095 };
00096
00098 virtual ~OrganizedFastMesh () {};
00099
00103 inline void
00104 setMaxEdgeLength (float max_edge_length)
00105 {
00106 max_edge_length_squared_ = max_edge_length * max_edge_length;
00107 };
00108
00113 inline void
00114 setTrianglePixelSize (int triangle_size)
00115 {
00116 triangle_pixel_size_ = std::max (1, (triangle_size - 1));
00117 }
00118
00123 inline void
00124 setTriangulationType (TriangulationType type)
00125 {
00126 triangulation_type_ = type;
00127 }
00128
00132 inline void
00133 storeShadowedFaces (bool enable)
00134 {
00135 store_shadowed_faces_ = enable;
00136 }
00137
00138 protected:
00140 float max_edge_length_squared_;
00141
00143 int triangle_pixel_size_;
00144
00146 TriangulationType triangulation_type_;
00147
00149 bool store_shadowed_faces_;
00150
00151 float cos_angle_tolerance_;
00152
00156 void
00157 reconstructPolygons (std::vector<pcl::Vertices>& polygons);
00158
00162 virtual void
00163 performReconstruction (std::vector<pcl::Vertices> &polygons);
00164
00172 void
00173 performReconstruction (pcl::PolygonMesh &output);
00174
00182 inline void
00183 addTriangle (int a, int b, int c, int idx, std::vector<pcl::Vertices>& polygons)
00184 {
00185 assert (idx < static_cast<int> (polygons.size ()));
00186 polygons[idx].vertices.resize (3);
00187 polygons[idx].vertices[0] = a;
00188 polygons[idx].vertices[1] = b;
00189 polygons[idx].vertices[2] = c;
00190 }
00191
00200 inline void
00201 addQuad (int a, int b, int c, int d, int idx, std::vector<pcl::Vertices>& polygons)
00202 {
00203 assert (idx < static_cast<int> (polygons.size ()));
00204 polygons[idx].vertices.resize (4);
00205 polygons[idx].vertices[0] = a;
00206 polygons[idx].vertices[1] = b;
00207 polygons[idx].vertices[2] = c;
00208 polygons[idx].vertices[3] = d;
00209 }
00210
00219 inline void
00220 resetPointData (const int &point_index, pcl::PolygonMesh &mesh, const float &value = 0.0f,
00221 int field_x_idx = 0, int field_y_idx = 1, int field_z_idx = 2)
00222 {
00223 float new_value = value;
00224 memcpy (&mesh.cloud.data[point_index * mesh.cloud.point_step + mesh.cloud.fields[field_x_idx].offset], &new_value, sizeof (float));
00225 memcpy (&mesh.cloud.data[point_index * mesh.cloud.point_step + mesh.cloud.fields[field_y_idx].offset], &new_value, sizeof (float));
00226 memcpy (&mesh.cloud.data[point_index * mesh.cloud.point_step + mesh.cloud.fields[field_z_idx].offset], &new_value, sizeof (float));
00227 }
00228
00233 inline bool
00234 isShadowed (const PointInT& point_a, const PointInT& point_b)
00235 {
00236 Eigen::Vector3f viewpoint = Eigen::Vector3f::Zero ();
00237 Eigen::Vector3f dir_a = viewpoint - point_a.getVector3fMap ();
00238 Eigen::Vector3f dir_b = point_b.getVector3fMap () - point_a.getVector3fMap ();
00239 float distance_to_points = dir_a.norm ();
00240 float distance_between_points = dir_b.norm ();
00241 float cos_angle = dir_a.dot (dir_b) / (distance_to_points*distance_between_points);
00242 if (cos_angle != cos_angle)
00243 cos_angle = 1.0f;
00244 return (fabs (cos_angle) >= cos_angle_tolerance_);
00245
00246 }
00247
00253 inline bool
00254 isValidTriangle (const int& a, const int& b, const int& c)
00255 {
00256 if (!pcl::isFinite (input_->points[a])) return (false);
00257 if (!pcl::isFinite (input_->points[b])) return (false);
00258 if (!pcl::isFinite (input_->points[c])) return (false);
00259 return (true);
00260 }
00261
00267 inline bool
00268 isShadowedTriangle (const int& a, const int& b, const int& c)
00269 {
00270 if (isShadowed (input_->points[a], input_->points[b])) return (true);
00271 if (isShadowed (input_->points[b], input_->points[c])) return (true);
00272 if (isShadowed (input_->points[c], input_->points[a])) return (true);
00273 return (false);
00274 }
00275
00282 inline bool
00283 isValidQuad (const int& a, const int& b, const int& c, const int& d)
00284 {
00285 if (!pcl::isFinite (input_->points[a])) return (false);
00286 if (!pcl::isFinite (input_->points[b])) return (false);
00287 if (!pcl::isFinite (input_->points[c])) return (false);
00288 if (!pcl::isFinite (input_->points[d])) return (false);
00289 return (true);
00290 }
00291
00298 inline bool
00299 isShadowedQuad (const int& a, const int& b, const int& c, const int& d)
00300 {
00301 if (isShadowed (input_->points[a], input_->points[b])) return (true);
00302 if (isShadowed (input_->points[b], input_->points[c])) return (true);
00303 if (isShadowed (input_->points[c], input_->points[d])) return (true);
00304 if (isShadowed (input_->points[d], input_->points[a])) return (true);
00305 return (false);
00306 }
00307
00311 void
00312 makeQuadMesh (std::vector<pcl::Vertices>& polygons);
00313
00317 void
00318 makeRightCutMesh (std::vector<pcl::Vertices>& polygons);
00319
00323 void
00324 makeLeftCutMesh (std::vector<pcl::Vertices>& polygons);
00325
00329 void
00330 makeAdaptiveCutMesh (std::vector<pcl::Vertices>& polygons);
00331 };
00332 }
00333
00334 #ifdef PCL_NO_PRECOMPILE
00335 #include <pcl/surface/impl/organized_fast_mesh.hpp>
00336 #endif
00337
00338 #endif // PCL_SURFACE_ORGANIZED_FAST_MESH_H_