8#include <boost/graph/adjacency_list.hpp>
9#include <boost/graph/graph_traits.hpp>
10#include <boost/iterator/filter_iterator.hpp>
12#include <spdlog/spdlog.h>
14#include <fmt/format.h>
20#include <Eigen/StdVector>
22#include <pcl/pcl_base.h>
23#include <pcl/point_cloud.h>
24#include <pcl/point_types.h>
26#include <range/v3/range/concepts.hpp>
27#include <range/v3/view/zip.hpp>
53 std::variant<VertexData, FaceData, CellData>
data;
60template <
typename Scalar,
int Rows>
62 std::vector<Eigen::Matrix<Scalar, Rows, 1>,
63 Eigen::aligned_allocator<Eigen::Matrix<Scalar, Rows, 1>>>;
68 :
public boost::adjacency_list<boost::vecS,
78 using Graph = boost::adjacency_list<boost::vecS, boost::vecS,
82 using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
83 using GraphIter = boost::graph_traits<CellComplex>::vertex_iterator;
84 using AdjacencyIter = boost::graph_traits<CellComplex>::adjacency_iterator;
91 bool operator()(CellComplex::vertex_descriptor vd)
const {
92 auto const &prop = (*g)[vd];
93 return prop.type == T;
104 auto const &prop = (*g)[vd];
106 auto [begin, end] = boost::adjacent_vertices(vd, *
g);
107 for (
auto it = begin; it != end; ++it)
117 boost::filter_iterator<IsFaceBetweenCells, GraphIter>;
124 int vertex_count = 0;
134 std::vector<Eigen::Vector4d, Eigen::aligned_allocator<Eigen::Vector4d>>
136 std::vector<size_t> &verticals, std::vector<size_t> &horizontals,
137 std::vector<std::pair<size_t, size_t>> &pairs,
138 std::array<double, 2> min_xy, std::array<double, 2> max_xy,
140 std::function<
void(
size_t, std::vector<std::array<double, 3>>
const &,
141 std::vector<int>
const &)>>
142 viz_func = std::nullopt);
152 template <
typename Po
intT = pcl::Po
intXYZ>
155 std::vector<pcl::IndicesPtr> &inliers,
156 const double grid_size = 0.2) -> void;
158 template <
typename PointT = pcl::PointXYZ,
typename PointN = pcl::Normal,
159 typename PointL = pcl::Label>
161 pcl::PointCloud<PointN>::ConstPtr normals,
162 pcl::PointCloud<PointL>::ConstPtr labels,
163 const double grid_size = 0.2) -> void;
166 auto v = boost::add_vertex(*
this);
168 (*this)[v].id = vertex_count++;
169 (*this)[v].pos = pos;
174 template <
typename T>
177 auto f = boost::add_vertex(*
this);
179 (*this)[f].id = face_count++;
180 (*this)[f].pos = pos;
181 (*this)[f].data =
FaceData{plane_id};
182 for (
auto it = begin; it != end; ++it)
183 boost::add_edge(*it, f, *
this);
186 template <
typename Range>
189 return add_face(pos, std::begin(vertices), std::end(vertices), plane_id);
192 template <
typename T>
194 auto c = boost::add_vertex(*
this);
196 (*this)[c].id = cell_count++;
197 (*this)[c].pos = pos;
199 for (
auto it = begin; it != end; ++it)
200 boost::add_edge(*it, c, *
this);
203 template <
typename Range>
205 return add_cell(pos, std::begin(faces), std::end(faces));
250 template <
typename ParseContext>
constexpr auto parse(ParseContext &ctx) {
255 template <
typename FormatContext>
257 FormatContext &ctx)
const {
258 return fmt::format_to(ctx.out(),
"[{}c {}f {}v {}r {}w]", obj.
num_cells(),
std::vector< Eigen::Matrix< Scalar, Rows, 1 >, Eigen::aligned_allocator< Eigen::Matrix< Scalar, Rows, 1 > > > EigenVectorContainer
boost::graph_traits< CellComplex >::adjacency_iterator AdjacencyIter
auto compute_room_probabilities(pcl::PointCloud< PointT >::ConstPtr cloud, pcl::PointCloud< PointN >::ConstPtr normals, pcl::PointCloud< PointL >::ConstPtr labels, const double grid_size=0.2) -> void
auto cells_end() const -> CellIterator
Is_Type< NodeType::Face > IsFace
boost::filter_iterator< IsVertex, GraphIter > VertexIterator
size_t num_vertices() const
Is_Type< NodeType::Vertex > IsVertex
auto faces_end() const -> FaceIterator
auto cells_begin() const -> CellIterator
Vertex add_vertex(Eigen::Vector3d pos)
Vertex add_face(Eigen::Vector3d pos, T begin, T end, int plane_id=-1)
boost::filter_iterator< IsFaceBetweenCells, GraphIter > FaceBetweenCellIterator
auto faces_between_cells_end() const -> FaceBetweenCellIterator
auto vertices_begin() const -> VertexIterator
Vertex add_cell(Eigen::Vector3d pos, T begin, T end)
auto faces_between_cells_begin() const -> FaceBetweenCellIterator
std::ostream & operator<<(std::ostream &os) const
boost::filter_iterator< IsCell, GraphIter > CellIterator
boost::filter_iterator< IsVertex, AdjacencyIter > VertexOnFaceIterator
boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, VertexData, EdgeData > Graph
boost::graph_traits< CellComplex >::vertex_iterator GraphIter
Is_Type< NodeType::Cell > IsCell
Vertex add_face(Eigen::Vector3d pos, Range vertices, int plane_id=-1)
CellComplex(std::vector< Eigen::Vector4d, Eigen::aligned_allocator< Eigen::Vector4d > > &planes, std::vector< size_t > &verticals, std::vector< size_t > &horizontals, std::vector< std::pair< size_t, size_t > > &pairs, std::array< double, 2 > min_xy, std::array< double, 2 > max_xy, std::optional< std::function< void(size_t, std::vector< std::array< double, 3 > > const &, std::vector< int > const &)> > viz_func=std::nullopt)
boost::graph_traits< Graph >::vertex_descriptor Vertex
auto faces_begin() const -> FaceIterator
auto compute_face_coverage(pcl::PointCloud< PointT >::ConstPtr cloud, EigenVectorContainer< double, 4 > &planes, std::vector< pcl::IndicesPtr > &inliers, const double grid_size=0.2) -> void
auto get_a(Vertex f) const -> Vertex
Vertex add_cell(Eigen::Vector3d pos, Range faces)
boost::filter_iterator< IsFace, AdjacencyIter > FaceOnCellIterator
auto vertices_end() const -> VertexIterator
boost::filter_iterator< IsFace, GraphIter > FaceIterator
auto get_b(Vertex f) const -> Vertex
boost::filter_iterator< IsCell, AdjacencyIter > CellOnFaceIterator
std::vector< Eigen::Matrix< Scalar, Rows, 1 >, Eigen::aligned_allocator< Eigen::Matrix< Scalar, Rows, 1 > > > EigenVectorContainer
IsFaceBetweenCells(const CellComplex *g)
bool operator()(CellComplex::vertex_descriptor vd) const
IsFaceBetweenCells()=delete
Is_Type(const CellComplex *g)
bool operator()(CellComplex::vertex_descriptor vd) const
std::variant< VertexData, FaceData, CellData > data