Skip to content

Commit

Permalink
allows to query the vertex indices of each primitive (now planes and …
Browse files Browse the repository at this point in the history
…cylinders are supported)
  • Loading branch information
LiangliangNan committed Oct 31, 2023
1 parent 0edf659 commit d67de97
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 27 deletions.
60 changes: 36 additions & 24 deletions easy3d/algo/point_cloud_ransac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@
********************************************************************/

#include <easy3d/algo/point_cloud_ransac.h>

#include <set>
#include <list>

#include <easy3d/core/point_cloud.h>

#include <3rd_party/ransac/RansacShapeDetector.h>
Expand All @@ -37,9 +33,9 @@
#include <3rd_party/ransac/SpherePrimitiveShapeConstructor.h>
#include <3rd_party/ransac/ConePrimitiveShapeConstructor.h>
#include <3rd_party/ransac/TorusPrimitiveShapeConstructor.h>
//#include <3rd_party/ransac/PlanePrimitiveShape.h>
#include <3rd_party/ransac/PlanePrimitiveShape.h>
#include <3rd_party/ransac/CylinderPrimitiveShape.h>
//#include <3rd_party/ransac/SpherePrimitiveShape.h>
//#include <3rd_party/ransac/CylinderPrimitiveShape.h>
//#include <3rd_party/ransac/ConePrimitiveShape.h>
//#include <3rd_party/ransac/TorusPrimitiveShape.h>

Expand All @@ -56,6 +52,8 @@ namespace easy3d {
PointCloud *cloud,
PointCloud_Ransac &pc,
const std::set<PrimitivesRansac::PrimType> &types,
std::vector<PrimitivesRansac::PlanePrim>& plane_primitives,
std::vector<PrimitivesRansac::CylinderPrim>& cylinder_primitives_,
unsigned int min_support,
float dist_thresh,
float bitmap_reso,
Expand Down Expand Up @@ -130,11 +128,10 @@ namespace easy3d {
const PrimitiveShape *primitive = shape_itr->first;
std::size_t num = shape_itr->second;

std::list<int> vts;
std::vector<int> vts(num);
PointCloud_Ransac::reverse_iterator point_itr = start;
for (std::size_t count = 0; count < num; ++count) {
int v = int(point_itr->index);
vts.push_back(v);
for (std::size_t idx = 0; idx < num; ++idx) {
vts[idx] = static_cast<int>(point_itr->index);
++point_itr;
}
start = point_itr;
Expand All @@ -148,31 +145,37 @@ namespace easy3d {
// extract parameters for this primitive
switch (primitive->Identifier()) {
case PrimitivesRansac::PLANE: {
// parameters are discarded
// const Plane& pl = dynamic_cast<const PlanePrimitiveShape*>(primitive)->Internal();
// const Vec3f& p = pl.getPosition();
// const Vec3f& n = pl.getNormal();
// const Plane3 plane(vec3(p.getValue()), vec3(n.getValue()));
PrimitivesRansac::PlanePrim prim;
const Plane& pl = dynamic_cast<const PlanePrimitiveShape*>(primitive)->Internal();
prim.primitive_index = index;
prim.position = vec3(pl.getPosition().getValue());
prim.normal = vec3(pl.getNormal().getValue()).normalize();
prim.plane = Plane3(prim.position, prim.normal);
for (auto id : vts) {
const PointCloud::Vertex v(id);
primitive_types[v] = PrimitivesRansac::PLANE;
primitive_indices[v] = index;
prim.vertices.push_back(id);
}
plane_primitives.push_back(prim);
break;
}
case PrimitivesRansac::CYLINDER: {
// parameters are discarded
// const Cylinder& cylinder = dynamic_cast<const CylinderPrimitiveShape*>(primitive)->Internal();
// double radius = cylinder.Radius();
// const Vec3f& pos = cylinder.AxisPosition();
// const Vec3f& nor = cylinder.AxisDirection();
// const vec3 position(pos[0], pos[1], pos[2]);
// vec3 dir(nor[0], nor[1], nor[2]); dir = normalize(dir);
PrimitivesRansac::CylinderPrim prim;
const Cylinder& cylinder = dynamic_cast<const CylinderPrimitiveShape*>(primitive)->Internal();
const Vec3f& pos = cylinder.AxisPosition();
const Vec3f& nor = cylinder.AxisDirection();
prim.radius = cylinder.Radius();
prim.position = vec3(pos[0], pos[1], pos[2]);
prim.direction = vec3(nor[0], nor[1], nor[2]).normalize();
prim.primitive_index = index;
for (auto id : vts) {
const PointCloud::Vertex v(id);
primitive_types[v] = PrimitivesRansac::CYLINDER;
primitive_indices[v] = index;
prim.vertices.push_back(id);
}
cylinder_primitives_.push_back(prim);
break;
}
case PrimitivesRansac::SPHERE: {
Expand Down Expand Up @@ -231,6 +234,11 @@ namespace easy3d {
}


void PrimitivesRansac::remove_primitive_type(PrimType t) {
types_.erase(t);
}


int PrimitivesRansac::detect(
PointCloud *cloud,
unsigned int min_support /* = 1000 */,
Expand Down Expand Up @@ -259,6 +267,10 @@ namespace easy3d {
return 0;
}

// clear the existing results (if any)
plane_primitives_.clear();
cylinder_primitives_.clear();

// prepare the data
PointCloud_Ransac pc;
pc.resize(cloud->n_vertices());
Expand All @@ -276,7 +288,7 @@ namespace easy3d {
pc[i].index = i;
}

return internal::do_detect(cloud, pc, types_, min_support, dist_thresh, bitmap_reso, normal_thresh, overlook_prob);
return internal::do_detect(cloud, pc, types_, plane_primitives_, cylinder_primitives_, min_support, dist_thresh, bitmap_reso, normal_thresh, overlook_prob);
}


Expand Down Expand Up @@ -327,7 +339,7 @@ namespace easy3d {
pc[index].index = idx;
}

return internal::do_detect(cloud, pc, types_, min_support, dist_thresh, bitmap_reso, normal_thresh, overlook_prob);
return internal::do_detect(cloud, pc, types_, plane_primitives_, cylinder_primitives_, min_support, dist_thresh, bitmap_reso, normal_thresh, overlook_prob);
}

}
35 changes: 32 additions & 3 deletions easy3d/algo/point_cloud_ransac.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
#define EASY3D_ALGO_POINT_CLOUD_RANSAC_H


#include <set>
#include <vector>
#include <easy3d/core/types.h>


namespace easy3d {
Expand Down Expand Up @@ -63,6 +62,11 @@ namespace easy3d {
* \details This is done by adding the interested primitive types one by one.
*/
void add_primitive_type(PrimType t);
/**
* \brief Exclude a primitive types to be extracted.
* \details This is done by removing the primitive type from the existing list.
*/
void remove_primitive_type(PrimType t);

/**
* \brief Extract primitives from a point cloud.
Expand Down Expand Up @@ -113,8 +117,33 @@ namespace easy3d {
float overlook_probability = 0.001f
);

//Todo: implement storing parameters for spheres, toruses, and cones.

// In addition to the primitive information (primitive type and index stored as per-vertex properties,
// the parameters of the detected primititives can be queried using the perspective functions.
struct PlanePrim {
int primitive_index; // the index of this plane (w.r.t. the entire list of detected primitives)
std::vector<int> vertices; // the vertex indices (w.r.t. the point cloud) of this plane
Plane3 plane; // the plane equation
vec3 position;
vec3 normal;
};
const std::vector<PlanePrim>& get_planes() const { return plane_primitives_; }

struct CylinderPrim {
int primitive_index; // the index of this cylinder w.r.t. the entire list of detected primitives
std::vector<int> vertices; // the vertex indices (w.r.t. the point cloud) of this cylinder
float radius;
vec3 position;
vec3 direction;
};
const std::vector<CylinderPrim>& get_cylinders() const { return cylinder_primitives_; }

private:
std::set<PrimType> types_;
std::set<PrimType> types_;

std::vector<PlanePrim> plane_primitives_;
std::vector<CylinderPrim> cylinder_primitives_;
};

}
Expand Down

0 comments on commit d67de97

Please sign in to comment.