00001 #include <srs_env_model_percp/but_plane_detector/plane.h>
00002
00003 namespace srs_env_model_percp {
00004
00005 PlaneExt::PlaneExt(but_plane_detector::Plane<float> plane) : but_plane_detector::Plane<float> (0.0, 0.0, 0.0, 0.0), planeCoefficients(new pcl::ModelCoefficients())
00006 {
00007 a = plane.a;
00008 b = plane.b;
00009 c = plane.c;
00010 d = plane.d;
00011 norm = plane.norm;
00012
00013
00014 Eigen::Vector3f current(a, b, c);
00015 Eigen::Vector3f target(0.0, 0.0, 1.0);
00016 Eigen::Quaternion<float> q;
00017 q.setFromTwoVectors(current, target);
00018 planeTransXY = q.toRotationMatrix();
00019
00020 planeShift = -d;
00021
00022 color.r = abs(a) / 2.0 + 0.2;
00023 color.g = abs(b) / 2.0 + 0.2;
00024 color.b = abs(d) / 5.0;
00025 color.a = 1.0;
00026
00027
00028 planeCoefficients->values.push_back(a);
00029 planeCoefficients->values.push_back(b);
00030 planeCoefficients->values.push_back(c);
00031 planeCoefficients->values.push_back(d);
00032
00033 }
00034
00035 PlaneExt::tVertices PlaneExt::ComputeConcaveHull(pcl::PointCloud<pcl::PointXYZ>::Ptr &plane_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr &plane_hull)
00036 {
00037 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected (new pcl::PointCloud<pcl::PointXYZ> ());
00038
00039
00040 pcl::ProjectInliers<pcl::PointXYZ> proj;
00041 proj.setModelType (pcl::SACMODEL_PLANE);
00042 proj.setInputCloud (plane_cloud);
00043 proj.setModelCoefficients (planeCoefficients);
00044 proj.filter(*cloud_projected);
00045
00046
00047 pcl::ConcaveHull<pcl::PointXYZ > chull;
00048 chull.setInputCloud (cloud_projected);
00049 chull.setAlpha(0.15);
00050
00051 tVertices polys;
00052 chull.reconstruct(*plane_hull, polys);
00053
00054 if (polys.size() > MAX_POLYS)
00055 return tVertices();
00056
00057 return polys;
00058 }
00059
00060 ClipperLib::ExPolygons PlaneExt::PolygonizeConcaveHull(pcl::PointCloud<pcl::PointXYZ>::Ptr &plane_hull, tVertices &polygon_indices)
00061 {
00062 ClipperLib::ExPolygons polygon;
00063
00064
00065 pcl::PointCloud<pcl::PointXYZ>::Ptr plane_hull_proj (new pcl::PointCloud<pcl::PointXYZ> ());
00066 pcl::transformPointCloud(*plane_hull, *plane_hull_proj, Eigen::Vector3f(-a*planeShift, -b*planeShift, -c*planeShift), Eigen::Quaternion<float>(0,0,0,0));
00067 pcl::transformPointCloud(*plane_hull_proj, *plane_hull_proj, planeTransXY);
00068
00069
00070 if (plane_hull_proj->points.size() > 0)
00071 {
00072 for (unsigned int i = 0; i < polygon_indices.size(); ++i)
00073 {
00074 ClipperLib::ExPolygon clipperPoly;
00075 clipperPoly.outer.resize(polygon_indices[i].vertices.size());
00076
00077 for (unsigned int j = 0; j < polygon_indices[i].vertices.size(); ++j)
00078 {
00079 clipperPoly.outer[j].X = CONVERT_TO_LONG(plane_hull_proj->points[polygon_indices[i].vertices[j]].x);
00080 clipperPoly.outer[j].Y = CONVERT_TO_LONG(plane_hull_proj->points[polygon_indices[i].vertices[j]].y);
00081 }
00082
00083
00084 if (!ClipperLib::Orientation(clipperPoly.outer))
00085 {
00086 ClipperLib::ReversePolygon(clipperPoly.outer);
00087 }
00088 polygon.push_back(clipperPoly);
00089 }
00090 }
00091 return polygon;
00092 }
00093
00094 void PlaneExt::ConcaveHullRewrite(pcl::PointCloud<pcl::PointXYZ>::Ptr &plane_hull, tVertices &polygon_indices)
00095 {
00096
00097 planePolygonsClipper = PolygonizeConcaveHull(plane_hull, polygon_indices);
00098 }
00099
00100 bool PlaneExt::ConcaveHullJoinCurrent(pcl::PointCloud<pcl::PointXYZ>::Ptr &plane_hull, tVertices &polygon_indices, int max_poly_size)
00101 {
00102
00103 ClipperLib::ExPolygons newPoly = PolygonizeConcaveHull(plane_hull, polygon_indices);
00104
00105 std::cerr << "polygonized" << std::endl;
00106
00107 if (newPoly.size() > max_poly_size) {
00108
00109 std::cerr << "too big (new) polygon" << std::endl;
00110 return false;
00111
00112 }
00113
00114 if (planePolygonsClipper.size() > max_poly_size) {
00115
00116 std::cerr << "too big (exist) polygon" << std::endl;
00117 return false;
00118
00119 }
00120
00121 ClipperLib::Clipper clipper;
00122
00123 std::cerr << "add existing pol " << planePolygonsClipper.size() << std::endl;
00124 for (unsigned int i = 0; i < planePolygonsClipper.size(); ++i) {
00125 try {
00126
00127 clipper.AddPolygon(planePolygonsClipper[i].outer, ClipperLib::ptSubject);
00128
00129 } catch (const char* Message) {
00130
00131 std::cerr << "excp" << std::endl;
00132
00133 }
00134
00135 }
00136
00137
00138 std::cerr << "add new pol " << newPoly.size() << std::endl;
00139 for (unsigned int i = 0; i < newPoly.size(); ++i) {
00140
00141 try {
00142
00143 clipper.AddPolygon(newPoly[i].outer, ClipperLib::ptClip);
00144
00145 } catch (const char* Message) {
00146
00147 std::cerr << "excp" << std::endl;
00148
00149 }
00150
00151 }
00152
00153
00154 std::cerr << "executing join... polygons: " << planePolygonsClipper.size() + newPoly.size() << std::endl;
00155 clipper.Execute(ClipperLib::ctUnion, planePolygonsClipper);
00156 std::cerr << "executed join!" << std::endl;
00157
00158 return true;
00159 }
00160
00161 void PlaneExt::TriangulatePlanePolygon()
00162 {
00163
00164 planeTriangles.points.clear();
00165 planeTrianglesSRS.clear();
00166
00167
00168 for (unsigned int polygon_i = 0; polygon_i < planePolygonsClipper.size(); ++polygon_i)
00169 {
00170 planeTrianglesSRS.push_back(cob_3d_mapping_msgs::Shape());
00171 planeTrianglesSRS.back().type = cob_3d_mapping_msgs::Shape::POLYGON;
00172 planeTrianglesSRS.back().params.push_back(a);
00173 planeTrianglesSRS.back().params.push_back(b);
00174 planeTrianglesSRS.back().params.push_back(c);
00175 planeTrianglesSRS.back().params.push_back(d);
00176 planeTrianglesSRS.back().holes.push_back(false);
00177
00178
00179 TPPLPoly triPolygon;
00180 triPolygon.Init(planePolygonsClipper[polygon_i].outer.size());
00181 pcl::PointCloud<pcl::PointXYZ> current_point_cloud;
00182
00183 for (unsigned int i = 0; i < planePolygonsClipper[polygon_i].outer.size(); ++i)
00184 {
00185 triPolygon[i].x = CONVERT_FROM_LONG(planePolygonsClipper[polygon_i].outer[i].X);
00186 triPolygon[i].y = CONVERT_FROM_LONG(planePolygonsClipper[polygon_i].outer[i].Y);
00187
00188
00189 pcl::PointXYZ point;
00190 point.x = triPolygon[i].x;
00191 point.y = triPolygon[i].y;
00192 point.z = 0;
00193 current_point_cloud.push_back(point);
00194 }
00195
00196
00197 TPPLPartition triangulation;
00198 std::list<TPPLPoly> triangles;
00199 triangulation.Triangulate_EC(&triPolygon, &triangles);
00200
00201
00202
00203 for (std::list<TPPLPoly>::iterator it = triangles.begin(); it != triangles.end(); ++it)
00204 {
00205 for (unsigned int j = 0; j < it->GetNumPoints(); ++j)
00206 {
00207 Eigen::Vector3f vec;
00208 vec(0) = it->GetPoint(j).x;
00209 vec(1) = it->GetPoint(j).y;
00210 vec(2) = 0;
00211 vec = planeTransXY.inverse() * vec;
00212 geometry_msgs::Point p;
00213 p.x = vec(0) + planeShift*a;
00214 p.y = vec(1) + planeShift*b;
00215 p.z = vec(2) + planeShift*c;
00216
00217 planeTriangles.points.push_back(p);
00218 }
00219 }
00220
00221
00222 pcl::transformPointCloud(current_point_cloud, current_point_cloud, planeTransXY.inverse());
00223 pcl::transformPointCloud(current_point_cloud, current_point_cloud, Eigen::Vector3f(a*planeShift, b*planeShift, c*planeShift), Eigen::Quaternion<float>(0,0,0,0));
00224
00225 sensor_msgs::PointCloud2 cloud;
00226 pcl::toROSMsg(current_point_cloud, cloud);
00227 planeTrianglesSRS.back().points.push_back(cloud);
00228 planeTrianglesSRS.back().centroid.x = planeShift*a;
00229 planeTrianglesSRS.back().centroid.y = planeShift*b;
00230 planeTrianglesSRS.back().centroid.z = planeShift*c;
00231 planeTrianglesSRS.back().color = color;
00232 planeTriangles.color = color;
00233 }
00234
00235
00236 }
00237
00238 visualization_msgs::Marker PlaneExt::NewPlanePoints(pcl::PointCloud<pcl::PointXYZ>::Ptr plane_cloud)
00239 {
00240
00241 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_hull (new pcl::PointCloud<pcl::PointXYZ>());
00242 tVertices polygons = ComputeConcaveHull(plane_cloud, cloud_hull);
00243
00244
00245 ConcaveHullRewrite(cloud_hull, polygons);
00246
00247
00248 TriangulatePlanePolygon();
00249
00250 return planeTriangles;
00251 }
00252
00253 visualization_msgs::Marker PlaneExt::AddPlanePoints(pcl::PointCloud<pcl::PointXYZ>::Ptr plane_cloud, int max_poly_size)
00254 {
00255
00256 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_hull (new pcl::PointCloud<pcl::PointXYZ>());
00257 std::cerr << "computing concave hull" << std::endl;
00258 tVertices polygons = ComputeConcaveHull(plane_cloud, cloud_hull);
00259
00260
00261 std::cerr << "concave hull join" << std::endl;
00262 ConcaveHullJoinCurrent(cloud_hull, polygons, max_poly_size);
00263
00264
00265 std::cerr << "triangulating polygon" << std::endl;
00266 TriangulatePlanePolygon();
00267
00268 return planeTriangles;
00269 }
00270
00271 visualization_msgs::Marker &PlaneExt::getMeshMarker()
00272 {
00273 return planeTriangles;
00274 }
00275
00276 PlaneExt::tShapeMarker &PlaneExt::getShapeMarker()
00277 {
00278 return planeTrianglesSRS;
00279 }
00280
00281 void PlaneExt::setColor(std_msgs::ColorRGBA &new_color)
00282 {
00283 planeTriangles.color = new_color;
00284 for (unsigned int i = 0; i < planeTrianglesSRS.size(); ++i)
00285 planeTrianglesSRS[i].color = new_color;
00286
00287 color = new_color;
00288 }
00289
00290 ClipperLib::ExPolygons &PlaneExt::getPolygons()
00291 {
00292 return planePolygonsClipper;
00293 }
00294
00295 void PlaneExt::setPolygons(ClipperLib::ExPolygons &polys)
00296 {
00297 planePolygonsClipper = polys;
00298 }
00299
00300 }