RSMesh 1.0.0
一个曲面重构的系统,输入为点云,输出为obj,stl等主流格式的网格文件,使用的方法为径向基函数插值,采取了并行优化、Intel-MKL等优化措施,支持百万级别的点云
载入中...
搜索中...
未找到
eigen_utility.h
1//
2// Created by RainSure on 2023/10/30.
3//
4
5#ifndef RSMESH_EIGEN_UTILITY_H
6#define RSMESH_EIGEN_UTILITY_H
7
8#include <functional>
9#include <iterator>
10#include <memory>
11#include <stdexcept>
12#include <utility>
13#include <vector>
14
15#include "boost/operators.hpp"
16#include "Eigen/Core"
17
18#include "fold.h"
19#include "iterator_range.h"
20#include "macros.h"
21
22
23namespace rsmesh {
28 namespace common {
29 namespace detail {
30 template<class Derived>
31 class col_iterator : public boost::random_access_iterator_helper<col_iterator<Derived>,
32 typename Eigen::MatrixBase<Derived>::ColXpr, Eigen::Index, void, typename Eigen::MatrixBase<Derived>::ColXpr> {
33 using self_type = col_iterator;
34 public:
35 using iterator_category = std::input_iterator_tag;
36
37 col_iterator(Eigen::MatrixBase<Derived> &m, Eigen::Index index) : m_(std::addressof(m)),
38 index_(index) {}
39
40 bool operator==(const self_type &rhs) const {
41 RSMESH_ASSERT(m_ == rhs.m_);
42 return index_ == rhs.m_;
43 }
44
45 self_type &operator++() {
46 RSMESH_ASSERT(index_ < m_->cols());
47 index_++;
48 return *this;
49 }
50
51 self_type &operator--() {
52 RSMESH_ASSERT(index_ > 0);
53 index_--;
54 return *this;
55 }
56
57 typename self_type::reference operator*() const {
58 RSMESH_ASSERT(index_ < m_->cols() and index_ >= 0);
59 return m_->col(index_);
60 }
61
62 typename self_type::pointer operator->() const = delete;
63
64 bool operator<(const self_type &rhs) const {
65 RSMESH_ASSERT(m_ == rhs.m_);
66 return index_ < rhs.index_;
67 }
68
69 self_type &operator+=(typename self_type::difference_type n) {
70 RSMESH_ASSERT(index_ + n < m_->cols());
71 index_ += n;
72 return *this;
73 }
74
75 self_type &operator-=(typename self_type::difference_type n) {
76 RSMESH_ASSERT(index_ - n >= 0);
77 index_ -= n;
78 return *this;
79 }
80
81 friend typename self_type::difference_type
82 operator-(const self_type &lhs, const self_type &rhs) {
83 RSMESH_ASSERT(lhs.m_ == rhs.m_);
84 return lhs.index_ - rhs.index_;
85 }
86
87 private:
88 Eigen::MatrixBase<Derived> *m_;
89 Eigen::Index index_;
90 };
91
92 template<class Derived>
93 class const_col_iterator : public boost::random_access_iterator_helper<const_col_iterator<Derived>,
94 typename Eigen::MatrixBase<Derived>::ConstColXpr, Eigen::Index, void, typename Eigen::MatrixBase<Derived>::ConstColXpr> {
96 public:
97 using iterator_category = std::input_iterator_tag;
98
99 const_col_iterator(const Eigen::MatrixBase<Derived>& m, Eigen::Index index) : m_(std::addressof(m)), index_(index) {}
100
101 bool operator==(const self_type& rhs) const {
102 RSMESH_ASSERT(m_ == rhs.m_);
103 return index_ == rhs.index_;
104 }
105
106 self_type& operator++() {
107 RSMESH_ASSERT(index_ < m_->cols());
108 index_ ++;
109 return *this;
110 }
111
112 self_type operator--() {
113 RSMESH_ASSERT(index_ > 0);
114 index_ --;
115 return *this;
116 }
117
118 typename self_type::reference operator*() const {
119 RSMESH_ASSERT(index_ < m_->cols() and index_ >= 0);
120 return m_->col(index_);
121 }
122
123 typename self_type::pointer operator->() const = delete;
124
125 bool operator<(const self_type& rhs) const {
126 RSMESH_ASSERT(m_ == rhs.m_);
127 return index_ < rhs.index_;
128 }
129
130 self_type& operator+=(typename self_type::difference_type n) {
131 RSMESH_ASSERT(index_ + n < m_->cols());
132 index_ += n;
133 return *this;
134 }
135
136 self_type& operator-=(typename self_type::difference_type n) {
137 RSMESH_ASSERT(index_ - n >= 0);
138 index_ -= n;
139 return *this;
140 }
141
142 friend typename self_type::difference_type operator-(const self_type& lhs, const self_type &rhs) {
143 RSMESH_ASSERT(lhs.m_ == rhs.m_);
144 return lhs.index_ - rhs.index_;
145 }
146 private:
147 const Eigen::MatrixBase<Derived> *m_;
148 Eigen::Index index_;
149 };
150
151 template <class Derived>
152 class row_iterator : public boost::random_access_iterator_helper<row_iterator<Derived>,
153 typename Eigen::MatrixBase<Derived>::RowXpr, Eigen::Index, void, typename Eigen::MatrixBase<Derived>::RowXpr> {
154 using self_type = row_iterator;
155
156 public:
157 using iterator_category = std::input_iterator_tag;
158
159 row_iterator(Eigen::MatrixBase<Derived>& m, Eigen::Index index) : m_(std::addressof(m)), index_(index) {}
160
161 bool operator==(const self_type& rhs) const {
162 RSMESH_ASSERT(m_ == rhs.m_);
163 return index_ == rhs.index_;
164 }
165
166 self_type& operator++() {
167 RSMESH_ASSERT(index_ < m_->rows());
168 index_ ++;
169 return *this;
170 }
171
172 self_type operator--() {
173 RSMESH_ASSERT(index_ > 0);
174 index_ --;
175 return *this;
176 }
177
178 typename self_type::reference operator*() const {
179 RSMESH_ASSERT(index_ < m_->cols() and index_ >= 0);
180 return m_->row(index_);
181 }
182
183 typename self_type::pointer operator->() const = delete;
184
185 bool operator<(const self_type& rhs) const {
186 RSMESH_ASSERT(m_ == rhs.m_);
187 return index_ < rhs.index_;
188 }
189
190 self_type& operator+=(typename self_type::difference_type n) {
191 RSMESH_ASSERT(index_ + n < m_->rows());
192 index_ += n;
193 return *this;
194 }
195
196 self_type& operator-=(typename self_type::difference_type n) {
197 RSMESH_ASSERT(index_ - n >= 0);
198 index_ -= n;
199 return *this;
200 }
201
202 friend typename self_type::difference_type operator-(const self_type& lhs, const self_type &rhs) {
203 RSMESH_ASSERT(lhs.m_ == rhs.m_);
204 return lhs.index_ - rhs.index_;
205 }
206
207 private:
208 Eigen::MatrixBase<Derived> *m_;
209 Eigen::Index index_;
210 };
211
212 template<class Derived>
213 class const_row_iterator : public boost::random_access_iterator_helper<const_row_iterator<Derived>,
214 typename Eigen::MatrixBase<Derived>::ConstRowXpr, Eigen::Index, void, typename Eigen::MatrixBase<Derived>::ConstRowXpr> {
216
217 public:
218 using iterator_category = std::input_iterator_tag;
219
220 const_row_iterator(const Eigen::MatrixBase<Derived>& m, Eigen::Index index) : m_(std::addressof(m)), index_(index) {}
221
222 bool operator==(const self_type& rhs) const {
223 RSMESH_ASSERT(m_ == rhs.m_);
224 return index_ == rhs.index_;
225 }
226
227 self_type& operator++() {
228 RSMESH_ASSERT(index_ < m_->rows());
229 index_ ++;
230 return *this;
231 }
232
233 self_type operator--() {
234 RSMESH_ASSERT(index_ > 0);
235 index_ --;
236 return *this;
237 }
238
239 typename self_type::reference operator*() const {
240 RSMESH_ASSERT(index_ < m_->cols() and index_ >= 0);
241 return m_->row(index_);
242 }
243
244 typename self_type::pointer operator->() const = delete;
245
246 bool operator<(const self_type& rhs) const {
247 RSMESH_ASSERT(m_ == rhs.m_);
248 return index_ < rhs.index_;
249 }
250
251 self_type& operator+=(typename self_type::difference_type n) {
252 RSMESH_ASSERT(index_ + n < m_->rows());
253 index_ += n;
254 return *this;
255 }
256
257 self_type& operator-=(typename self_type::difference_type n) {
258 RSMESH_ASSERT(index_ - n >= 0);
259 index_ -= n;
260 return *this;
261 }
262
263 friend typename self_type::difference_type operator-(const self_type& lhs, const self_type &rhs) {
264 RSMESH_ASSERT(lhs.m_ == rhs.m_);
265 return lhs.index_ - rhs.index_;
266 }
267
268 private:
269 const Eigen::MatrixBase<Derived> *m_;
270 Eigen::Index index_;
271 };
272
273 } // detail
274
275 template<class Derived>
276 auto col_begin(Eigen::MatrixBase<Derived>& m) {
278 }
279
280 template<class Derived>
281 auto col_end(Eigen::MatrixBase<Derived>& m) {
282 return detail::col_iterator<Derived>(m, m.cols());
283 }
284
285 template<class Derived>
286 auto col_begin(const Eigen::MatrixBase<Derived>& m) {
287 return detail::const_col_iterator<Derived>(m, 0);
288 }
289
290 template<class Derived>
291 auto col_end(const Eigen::MatrixBase<Derived>& m) {
292 return detail::const_col_iterator<Derived>(m, m.cols());
293 }
294
295 template<class Derived>
296 auto row_begin(Eigen::MatrixBase<Derived>& m) {
297 return detail::row_iterator<Derived>(m, 0);
298 }
299
300 template<class Derived>
301 auto row_end(Eigen::MatrixBase<Derived>& m) {
302 return detail::row_iterator<Derived>(m, m.rows());
303 }
304
305 template<class Derived>
306 auto row_begin(const Eigen::MatrixBase<Derived>& m) {
307 return detail::const_row_iterator<Derived>(m, 0);
308 }
309
310 template<class Derived>
311 auto row_end(const Eigen::MatrixBase<Derived>& m) {
312 return detail::const_row_iterator<Derived>(m, m.rows());
313 }
314
315 namespace detail {
316 template <class Derived>
318 public:
319 explicit col_range_wrapper(Eigen::MatrixBase<Derived>& m) : m_(m) {}
320
321 auto begin() {return col_begin(m_);}
322
323 auto end() {return col_end(m_);}
324
325 private:
326 Eigen::MatrixBase<Derived>& m_;
327 };
328
329 template <class Derived>
331 public:
332 explicit const_col_range_wrapper(const Eigen::MatrixBase<Derived>& m) : m_(m) {}
333
334 auto begin() { return col_begin(m_);}
335
336 auto end() {return col_end(m_);}
337
338 private:
339 const Eigen::MatrixBase<Derived>& m_;
340 };
341
342 template <class Derived>
344 public:
345 explicit row_range_wrapper(Eigen::MatrixBase<Derived>& m) : m_(m) {}
346
347 auto begin() {return row_begin(m_);}
348
349 auto end() {return row_end(m_);}
350
351 private:
352 Eigen::MatrixBase<Derived>& m_;
353 };
354
355 template <class Derived>
357 public:
358 explicit const_row_range_wrapper(Eigen::MatrixBase<Derived>& m) : m_(m) {}
359
360 auto begin() {return row_begin(m_);}
361
362 auto end() {return row_end(m_);}
363 private:
364 Eigen::MatrixBase<Derived> *m_;
365 };
366 } // detail
367
368 template <class Derived>
369 auto col_range(Eigen::MatrixBase<Derived>& m) {
371 }
372
373 template <class Derived>
374 auto col_range(const Eigen::MatrixBase<Derived>& m) {
375 return detail::const_col_range_wrapper<Derived>(m);
376 }
377
378 template <class Derived>
379 auto row_range(Eigen::MatrixBase<Derived>& m) {
380 return detail::row_range_wrapper<Derived>(m);
381 }
382
383 template <class Derived>
384 auto row_range(const Eigen::MatrixBase<Derived>& m) {
385 return detail::const_row_range_wrapper<Derived>(m);
386 }
387
388 namespace detail {
389 // 特化版本用于终止递归
390 template <class Derived>
391 Eigen::Index common_cols(const Eigen::MatrixBase<Derived>& m) {
392 return m.cols();
393 }
394
395 template <class Derived, class ...Args>
396 Eigen::Index common_cols(const Eigen::MatrixBase<Derived>& m, const Args&&... args) {
397 if(m.cols() != common_cols(std::forward<Args>(args)...)) {
398 throw std::invalid_argument("All inputs must have the same number of columns.");
399 }
400
401 return m.cols();
402 }
403
404 // 特化版本用于终止递归
405 template<class Derived, class ...Args>
406 Eigen::Index common_rows(const Eigen::MatrixBase<Derived>& m) {
407 return m.rows();
408 }
409
410 template <class Derived, class ...Args>
411 Eigen::Index common_rows(const Eigen::MatrixBase<Derived>& m, Args&&... args) {
412 if(m.rows() != common_rows(std::forward<Args>(args)...)) {
413 throw std::invalid_argument("All inputs must have the same number of rows");
414 }
415 return m.rows();
416 }
417
418 template <class ResultDerived, class Derived>
419 void concatenate_cols_impl(Eigen::MatrixBase<ResultDerived>& result, const Eigen::MatrixBase<Derived>& m) {
420 result = m;
421 }
422
423 template <class ResultDerived, class Derived, class... Args>
424 void concatenate_cols_impl(Eigen::MatrixBase<ResultDerived>& result, const Eigen::MatrixBase<Derived>&m, Args&&... args) {
425 result.leftCols(m.cols()) = m;
426 auto result_tail = result.rightCols(result.cols() - m.cols());
427 concatenate_cols_impl(result_tail, std::forward<Args>(args)...);
428 }
429
430 template <class ResultDerived, class Derived>
431 void concatenate_rows_impl(Eigen::MatrixBase<ResultDerived>& result, const Eigen::MatrixBase<Derived>& m) {
432 result = m;
433 }
434
435 template <class ResultDerived, class Derived, class ...Args>
436 void concatenate_rows_impl(Eigen::MatrixBase<ResultDerived>& result, const Eigen::MatrixBase<Derived>& m, Args&&... args) {
437 result.topRows(m.rows()) = m;
438
439 auto result_tail = result.bottomRows(result.rows() - m.rows());
440 concatenate_rows_impl(result_tail, std::forward<Args>(args)...);
441 }
442
443 template <class ResultDerived, class Derived>
444 void take_cols_impl(Eigen::MatrixBase<ResultDerived>& result, const Eigen::MatrixBase<Derived>& m, Eigen::Index index) {
445 result.col(0) = m.col(index);
446 }
447
448 template <class ResultDerived, class Derived, class... Ts>
449 void take_cols_impl(Eigen::MatrixBase<ResultDerived>& result, const Eigen::MatrixBase<Derived>& m, Eigen::Index index, Ts... indices) {
450 result.col(0) = m.col(index);
451 auto result_tail = result.rightCols(result.cols() - 1);
452 take_cols_impl(result, m, indices...);
453 }
454
455 template <class ResultDerived, class Derived>
456 void take_rows_impl(Eigen::MatrixBase<ResultDerived>& result, const Eigen::MatrixBase<Derived>& m, Eigen::Index index) {
457 result.row(0) = m.row(index);
458 }
459
460 template <class ResultDerived, class Derived, class... Ts>
461 void take_rows_impl(Eigen::MatrixBase<ResultDerived>& result, const Eigen::MatrixBase<Derived>& m, Eigen::Index index, Ts... indices) {
462 result.row(0) = m.row(index);
463 auto result_tail = result.bottomRows(result.rows() - 1);
464 take_rows_impl(result, m, indices...);
465 }
466
467 } // detail
468
469 template <class ...Args>
470 auto concatenate_cols(Args&&... args) {
471 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> result (
472 detail::common_rows(std::forward<Args>(args)...),
473 (args.cols() + ...)
474 );
475
476 detail::concatenate_cols_impl(result, std::forward<Args>(args)...);
477 return result;
478 }
479
480 template <class ...Args>
481 auto concatenate_rows(Args&&... args) {
482 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> result (
483 common::fold_left(std::plus<>(), args.rows()...),
484 detail::common_cols(std::forward<Args>(args)...)
485 );
486
487 detail::concatenate_rows_impl(result, std::forward<Args>(args)...);
488 return result;
489 }
490
491 template <class Derived, class... Ts>
492 auto take_cols(const Eigen::MatrixBase<Derived>& m, Ts... indices) {
493 Eigen::Matrix<
494 typename Eigen::MatrixBase<Derived>::Scalar,
495 Eigen::MatrixBase<Derived>::RowsAtCompileTime,
496 sizeof...(indices),
497 Eigen::MatrixBase<Derived>::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor
498 > result(m.rows(), sizeof...(indices));
499
500 detail::take_cols_impl(result, m, indices...);
501
502 return result;
503 }
504
505 template <class Derived, class ForwardRange>
506 auto take_cols(const Eigen::MatrixBase<Derived>& m, ForwardRange indices) {
507 Eigen::Index n_cols = std::distance(indices.begin(), indices.end());
508
509 Eigen::Matrix<
510 typename Eigen::MatrixBase<Derived>::Scalar,
511 Eigen::MatrixBase<Derived>::RowsAtCompileTime,
512 Eigen::Dynamic, // 编译期无法确定indices的大小,不可以显式指定为n_cols,因为C++模板元编程时,模板参数必须是编译时已知的值
513 Eigen::MatrixBase<Derived>::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor
514 > result(m.rows(), n_cols);
515
516 auto it = indices.begin();
517 for (Eigen::Index i = 0; i < n_cols; i ++) {
518 result.col(i) = m.col(*it ++);
519 }
520 return result;
521 }
522
523 template <class Derived>
524 auto take_cols(const Eigen::MatrixBase<Derived>& m, const std::vector<Eigen::Index> &indices) {
525 return take_cols(m, make_range(indices.begin(), indices.end()));
526 }
527
528 template <class Derived, class... Ts>
529 auto take_rows(const Eigen::MatrixBase<Derived>& m, Ts... indices) {
530 Eigen::Matrix <
531 typename Eigen::MatrixBase<Derived>::Scalar,
532 sizeof...(indices),
533 Eigen::MatrixBase<Derived>::ColsAtCompileTime,
534 Eigen::MatrixBase<Derived>::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor
535 > result(sizeof...(indices), m.cols());
536
537 detail::take_rows_impl(result, m, indices...);
538
539 return result;
540 }
541
542 template <class Derived, class ForwardRange>
543 auto take_rows(const Eigen::MatrixBase<Derived>& m, ForwardRange indices) {
544 Eigen::Index n_rows = std::distance(indices.begin(), indices.end());
545
546 Eigen::Matrix <
547 typename Eigen::MatrixBase<Derived>::Scalar,
548 Eigen::Dynamic,
549 Eigen::MatrixBase<Derived>::ColsAtCompileTime,
550 Eigen::MatrixBase<Derived>::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor
551 > result(n_rows, m.cols());
552
553 auto it = indices.begin();
554 for(Eigen::Index i = 0; i < n_rows; i ++) {
555 result.row(i) = m.row(i);
556 }
557 return result;
558 }
559
560 template <class Derived>
561 auto take_rows(const Eigen::MatrixBase<Derived>& m, const std::vector<Eigen::Index>& indices) {
562 return take_rows(m, make_range(indices.begin(), indices.end()));
563 }
564
565 } // common
566} // rsmesh
567
568#endif //RSMESH_EIGEN_UTILITY_H
本系统的主命名空间,包含了common, examples, fmm, geometry, numeric, point_cloud等子命名空间