├── images
├── cut.png
├── new.png
├── copy.png
├── open.png
├── paste.png
├── save.png
├── undo.png
├── Capture1a.PNG
├── Capture1b.PNG
├── Capture1c.PNG
├── Capture1d.PNG
├── Capture1e.PNG
├── Capture2a.PNG
├── Capture2a2.PNG
├── Capture2b.PNG
├── Capture2b2.PNG
├── Capture2c.PNG
├── Capture2d.PNG
├── Capture2d2.PNG
├── Capture2e.PNG
├── Capture2e2.PNG
├── Capture2f.PNG
├── Capture2f2.PNG
├── Capture5a.PNG
├── Capture5b.PNG
├── Capture5c.PNG
├── Capture5d.PNG
├── Capture8a.PNG
├── Capture8b.PNG
├── Capture8c.PNG
└── Capture8d.PNG
├── release
├── bunny.pcd
├── OpenNI2.dll
├── PCReconstruct.exe
├── pcl_io_release.dll
├── pcl_common_release.dll
└── pcl_io_ply_release.dll
├── PCReconstruct.qrc
├── Cover-Tree
├── Makefile
├── CoverTreePoint.h
└── README
├── utils
├── pt_to_pt_distsq.h
├── cloud_normal.h
├── rotations.h
├── ensure_buffer_size.h
├── Plane.h
├── pt_to_pt_distsq.cpp
├── Plane.cpp
├── rotations.cpp
└── cloud_normal.cpp
├── dialogs
├── get_field.h
├── SparsifyDialog.h
├── RandomSurfDialog.h
├── NormalsDialog.h
├── DecimateDialog.h
├── OptionsDialog.h
├── BoundBoxDialog.h
├── get_field.cpp
├── RandomSurfDialog.cpp
├── SparsifyDialog.cpp
├── ReconstructDialog.h
├── NormalsDialog.cpp
├── DecimateDialog.cpp
├── OptionsDialog.cpp
├── BoundBoxDialog.cpp
└── ReconstructDialog.cpp
├── alignment.h
├── constants.h
├── dictionarylearning
├── cosine_transform.h
├── ksvd.h
├── MatchingPursuit.h
├── ksvd_dct2D.h
├── OrthogonalPursuit.h
├── MatchingPursuit.cpp
├── cosine_transform.cpp
├── OrthogonalPursuit.cpp
├── ksvd.cpp
└── ksvd_dct2D.cpp
├── MessageLogger.h
├── MessageLogger.cpp
├── CloudWorker.h
├── stable.h
├── CloudWorker.cpp
├── BoundBox.h
├── MainWindow.h
├── main.cpp
├── Window.h
├── Cloud.h
├── BoundBox.cpp
├── PCReconstruct.pro
├── README.md
├── Window.cpp
├── GLWidget.h
├── MainWindow.cpp
├── GLWidget.cpp
└── LICENSE
/images/cut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/cut.png
--------------------------------------------------------------------------------
/images/new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/new.png
--------------------------------------------------------------------------------
/images/copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/copy.png
--------------------------------------------------------------------------------
/images/open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/open.png
--------------------------------------------------------------------------------
/images/paste.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/paste.png
--------------------------------------------------------------------------------
/images/save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/save.png
--------------------------------------------------------------------------------
/images/undo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/undo.png
--------------------------------------------------------------------------------
/release/bunny.pcd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/release/bunny.pcd
--------------------------------------------------------------------------------
/release/OpenNI2.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/release/OpenNI2.dll
--------------------------------------------------------------------------------
/images/Capture1a.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture1a.PNG
--------------------------------------------------------------------------------
/images/Capture1b.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture1b.PNG
--------------------------------------------------------------------------------
/images/Capture1c.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture1c.PNG
--------------------------------------------------------------------------------
/images/Capture1d.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture1d.PNG
--------------------------------------------------------------------------------
/images/Capture1e.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture1e.PNG
--------------------------------------------------------------------------------
/images/Capture2a.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture2a.PNG
--------------------------------------------------------------------------------
/images/Capture2a2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture2a2.PNG
--------------------------------------------------------------------------------
/images/Capture2b.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture2b.PNG
--------------------------------------------------------------------------------
/images/Capture2b2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture2b2.PNG
--------------------------------------------------------------------------------
/images/Capture2c.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture2c.PNG
--------------------------------------------------------------------------------
/images/Capture2d.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture2d.PNG
--------------------------------------------------------------------------------
/images/Capture2d2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture2d2.PNG
--------------------------------------------------------------------------------
/images/Capture2e.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture2e.PNG
--------------------------------------------------------------------------------
/images/Capture2e2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture2e2.PNG
--------------------------------------------------------------------------------
/images/Capture2f.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture2f.PNG
--------------------------------------------------------------------------------
/images/Capture2f2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture2f2.PNG
--------------------------------------------------------------------------------
/images/Capture5a.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture5a.PNG
--------------------------------------------------------------------------------
/images/Capture5b.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture5b.PNG
--------------------------------------------------------------------------------
/images/Capture5c.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture5c.PNG
--------------------------------------------------------------------------------
/images/Capture5d.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture5d.PNG
--------------------------------------------------------------------------------
/images/Capture8a.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture8a.PNG
--------------------------------------------------------------------------------
/images/Capture8b.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture8b.PNG
--------------------------------------------------------------------------------
/images/Capture8c.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture8c.PNG
--------------------------------------------------------------------------------
/images/Capture8d.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/images/Capture8d.PNG
--------------------------------------------------------------------------------
/release/PCReconstruct.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/release/PCReconstruct.exe
--------------------------------------------------------------------------------
/release/pcl_io_release.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/release/pcl_io_release.dll
--------------------------------------------------------------------------------
/release/pcl_common_release.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/release/pcl_common_release.dll
--------------------------------------------------------------------------------
/release/pcl_io_ply_release.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codearxiv/PCReconstruct/HEAD/release/pcl_io_ply_release.dll
--------------------------------------------------------------------------------
/PCReconstruct.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | images/copy.png
4 | images/cut.png
5 | images/new.png
6 | images/open.png
7 | images/paste.png
8 | images/save.png
9 | images/undo.png
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Cover-Tree/Makefile:
--------------------------------------------------------------------------------
1 | CXX ?= g++
2 | CXXFLAGS ?= -Wall -O3 -ffast-math -funroll-loops
3 |
4 | all: test
5 |
6 | Cover_Tree_Point.o: Cover_Tree_Point.h Cover_Tree_Point.cc
7 | $(CXX) -c $(CXXFLAGS) Cover_Tree_Point.cc
8 |
9 | test: test.cc Cover_Tree.h Cover_Tree_Point.o Cover_Tree_Point.h Cover_Tree_Point.cc
10 | $(CXX) test.cc $(CXXFLAGS) -o test Cover_Tree_Point.o
11 |
12 | clean:
13 | rm *.o test
14 |
--------------------------------------------------------------------------------
/utils/pt_to_pt_distsq.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 |
6 | #ifndef PT_TO_PT_DISTSQ_H
7 | #define PT_TO_PT_DISTSQ_H
8 |
9 | #include
10 |
11 | double pt_to_pt_distsq(const Eigen::VectorXf& v, const Eigen::VectorXf& w);
12 |
13 | double pt_to_pt_distsq(const float v[3], const float w[3]);
14 |
15 |
16 | #endif // PT_TO_PT_DISTSQ_H
17 |
--------------------------------------------------------------------------------
/utils/cloud_normal.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 |
6 | #ifndef CLOUD_NORMAL_H
7 | #define CLOUD_NORMAL_H
8 |
9 | #include
10 | #include
11 |
12 |
13 | Eigen::Vector3f cloud_normal(
14 | const Eigen::Vector3f& p0, const std::vector& cloud,
15 | int niters, std::vector& vwork);
16 |
17 |
18 | #endif // CLOUD_NORMAL_H
19 |
--------------------------------------------------------------------------------
/dialogs/get_field.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #ifndef GET_FIELD_H
5 | #define GET_FIELD_H
6 |
7 | #include
8 |
9 | QT_BEGIN_NAMESPACE
10 | class QLineEdit;
11 | class QIntValidator;
12 | class QDoubleValidator;
13 | QT_END_NAMESPACE
14 |
15 | bool get_integer_field(
16 | QLineEdit *lineEdit, QIntValidator *validator, size_t& field);
17 |
18 | bool get_float_field(
19 | QLineEdit *lineEdit, QDoubleValidator *validator, float& field);
20 |
21 | #endif // GET_FIELD_H
22 |
--------------------------------------------------------------------------------
/alignment.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 | #ifndef ALIGNMENT_H
6 | #define ALIGNMENT_H
7 |
8 | #include
9 |
10 |
11 | #define ALIGNED_MEMORY
12 |
13 |
14 | #ifdef ALIGNED_MEMORY
15 | const size_t ALIGNEDX = Eigen::Aligned16;
16 | inline size_t align_padded(size_t n) {
17 | return ALIGNEDX > 0 ? ALIGNEDX*(1+((n-1)/ALIGNEDX)) : n;
18 | }
19 | #else
20 | const size_t ALIGNEDX = Eigen::Unaligned;
21 | inline size_t align_padded(size_t n) { return n; }
22 | #endif
23 |
24 | #endif // ALIGNMENT_H
25 |
--------------------------------------------------------------------------------
/constants.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 | #ifndef CONSTANTS_H
6 | #define CONSTANTS_H
7 |
8 | #include
9 |
10 | const float float_infinity = std::numeric_limits::infinity();
11 | const float float_tiny = std::numeric_limits::min();
12 | const double double_infinity = std::numeric_limits::infinity();
13 | const int int_infinity = std::numeric_limits::max();
14 |
15 | enum class SparseApprox { OrthogonalPursuit = 0, MatchingPursuit = 1 };
16 |
17 | #endif // CONSTANTS_H
18 |
--------------------------------------------------------------------------------
/dictionarylearning/cosine_transform.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 |
6 | #ifndef COSINETRANSFORM_H
7 | #define COSINETRANSFORM_H
8 |
9 | #include "alignment.h"
10 |
11 | #include
12 | #include
13 |
14 |
15 | void cosine_transform(
16 | const Eigen::VectorXf& U,
17 | const Eigen::VectorXf& V,
18 | Eigen::Index nfreq,
19 | std::vector>& dwork,
20 | Eigen::Ref T
21 | );
22 |
23 | #endif // COSINETRANSFORM_H
24 |
--------------------------------------------------------------------------------
/utils/rotations.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 | #ifndef ROTATIONS_H
6 | #define ROTATIONS_H
7 |
8 | #include
9 |
10 | void vector_to_vector_rotation_matrix(
11 | const Eigen::Vector3f& v, const Eigen::Vector3f& w,
12 | bool normalized, bool lineThruW, Eigen::Matrix3f& M);
13 |
14 | void angle_vector_rotation_matrix(
15 | float angle, const Eigen::Vector3f& u,
16 | Eigen::Matrix3f& M);
17 |
18 | void cos_sin_angle_vector_rotation_matrix(
19 | float cosa, float sina, const Eigen::Vector3f& u,
20 | Eigen::Matrix3f& M);
21 |
22 | #endif // ROTATIONS_H
23 |
--------------------------------------------------------------------------------
/dictionarylearning/ksvd.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 |
6 | #ifndef KSVD_H
7 | #define KSVD_H
8 |
9 | #include
10 | #include
11 |
12 |
13 |
14 | void ksvd(
15 | bool useOpenMP,
16 | const Eigen::MatrixXf& Y,
17 | Eigen::Index latm,
18 | int maxIters,
19 | float maxError,
20 | int svPowIters,
21 | const std::function sparseFunct,
27 | Eigen::MatrixXf& D,
28 | Eigen::MatrixXf& X
29 | );
30 |
31 | #endif // KSVD_H
32 |
--------------------------------------------------------------------------------
/dialogs/SparsifyDialog.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #ifndef SPARSIFYDIALOG_H
5 | #define SPARSIFYDIALOG_H
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | QT_BEGIN_NAMESPACE
12 | class QFormLayout;
13 | class QLineEdit;
14 | class QDialogButtonBox;
15 | class QDoubleValidator;
16 | QT_END_NAMESPACE
17 |
18 | class SparsifyDialog : public QDialog
19 | {
20 | Q_OBJECT
21 |
22 | public:
23 | SparsifyDialog(QWidget *parent = nullptr);
24 | bool getFields(float& percent) const;
25 |
26 | private:
27 | QFormLayout *form;
28 | QLineEdit *percentLineEdit;
29 | QDialogButtonBox *buttonBox;
30 | QDoubleValidator *validator;
31 |
32 | };
33 |
34 | #endif // SPARSIFYDIALOG_H
35 |
--------------------------------------------------------------------------------
/dialogs/RandomSurfDialog.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #ifndef SETRANDOMDIALOG_H
5 | #define SETRANDOMDIALOG_H
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | QT_BEGIN_NAMESPACE
12 | class QFormLayout;
13 | class QLineEdit;
14 | class QDialogButtonBox;
15 | class QIntValidator;
16 | QT_END_NAMESPACE
17 |
18 | class RandomSurfDialog : public QDialog
19 | {
20 | Q_OBJECT
21 |
22 | public:
23 | RandomSurfDialog(QWidget *parent = nullptr);
24 | bool getFields(size_t& nPoints) const;
25 |
26 | private:
27 | QFormLayout *form;
28 | QLineEdit *nPointsLineEdit;
29 | QDialogButtonBox *buttonBox;
30 | QIntValidator *validator;
31 |
32 | };
33 |
34 | #endif // SETRANDOMDIALOG_H
35 |
--------------------------------------------------------------------------------
/utils/ensure_buffer_size.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 |
6 | #ifndef ENSURE_BUFFER_SIZE_H
7 | #define ENSURE_BUFFER_SIZE_H
8 |
9 | #include
10 |
11 | //-----------------------------------------------------------
12 |
13 |
14 | template >
15 | void ensure_buffer_size(size_t sizeEnsure, std::vector& buffer)
16 | {
17 | if( buffer.capacity() < sizeEnsure ) buffer.reserve(2*sizeEnsure);
18 | if( buffer.size() < sizeEnsure ) buffer.resize(sizeEnsure);
19 |
20 | }
21 |
22 | //-----------------------------------------------------------
23 |
24 |
25 | #endif // ENSURE_BUFFER_SIZE_H
26 |
--------------------------------------------------------------------------------
/dialogs/NormalsDialog.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #ifndef NORMALSDIALOG_H
5 | #define NORMALSDIALOG_H
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | QT_BEGIN_NAMESPACE
12 | class QFormLayout;
13 | class QLineEdit;
14 | class QDialogButtonBox;
15 | class QIntValidator;
16 | QT_END_NAMESPACE
17 |
18 | class NormalsDialog : public QDialog
19 | {
20 | Q_OBJECT
21 |
22 | public:
23 | NormalsDialog(QWidget *parent = nullptr);
24 | bool getFields(int& nIters, size_t& kNN) const;
25 |
26 | private:
27 | QFormLayout *form;
28 | QLineEdit *nItersLineEdit;
29 | QLineEdit *kNNLineEdit;
30 | QDialogButtonBox *buttonBox;
31 | QIntValidator *validator;
32 |
33 | };
34 |
35 |
36 | #endif // NORMALSDIALOG_H
37 |
--------------------------------------------------------------------------------
/dialogs/DecimateDialog.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #ifndef DECIMATEDIALOG_H
5 | #define DECIMATEDIALOG_H
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | QT_BEGIN_NAMESPACE
12 | class QFormLayout;
13 | class QLineEdit;
14 | class QDialogButtonBox;
15 | class QIntValidator;
16 | QT_END_NAMESPACE
17 |
18 | class DecimateDialog : public QDialog
19 | {
20 | Q_OBJECT
21 |
22 | public:
23 | DecimateDialog(QWidget *parent = nullptr);
24 | bool getFields(size_t& nHoles, size_t& kNN) const;
25 |
26 | private:
27 | QFormLayout *form;
28 | QLineEdit *nHolesLineEdit;
29 | QLineEdit *nPointsLineEdit;
30 | QDialogButtonBox *buttonBox;
31 | QIntValidator *validator;
32 |
33 | };
34 |
35 |
36 | #endif // DECIMATEDIALOG_H
37 |
--------------------------------------------------------------------------------
/dialogs/OptionsDialog.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #ifndef OPTIONSDIALOG_H
5 | #define OPTIONSDIALOG_H
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | QT_BEGIN_NAMESPACE
12 | class QFormLayout;
13 | class QLineEdit;
14 | class QDialogButtonBox;
15 | class QDoubleValidator;
16 | QT_END_NAMESPACE
17 |
18 | class OptionsDialog : public QDialog
19 | {
20 | Q_OBJECT
21 |
22 | public:
23 | OptionsDialog(QWidget *parent = nullptr);
24 | bool getFields(float& pointSize, float& normScale) const;
25 |
26 | private:
27 | QFormLayout *form;
28 | QLineEdit *pointSizeLineEdit;
29 | QLineEdit *normScaleLineEdit;
30 | QDialogButtonBox *buttonBox;
31 | QDoubleValidator *validator;
32 |
33 | };
34 |
35 |
36 | #endif // OPTIONSDIALOG_H
37 |
--------------------------------------------------------------------------------
/utils/Plane.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 |
6 | #ifndef PLANE_H
7 | #define PLANE_H
8 |
9 | #include
10 |
11 | class Plane
12 | {
13 | using Index = Eigen::Index;
14 | using Matrix3f = Eigen::Matrix3f;
15 | using Vector3f = Eigen::Vector3f;
16 | using Vector2f = Eigen::Vector2f;
17 |
18 | public:
19 | Plane(const Vector3f p0, const Vector3f norm) { set(p0,norm); }
20 |
21 | void set(const Vector3f p0, const Vector3f norm);
22 | Vector2f project_uv(const Vector3f q);
23 | Vector3f project(const Vector3f q, Vector2f& puv);
24 | void getUVAxes(Vector3f& u, Vector3f& v) {u = m_u; v = m_v;}
25 |
26 | private:
27 | Vector3f m_p0;
28 | Vector3f m_norm;
29 | Vector3f m_u;
30 | Vector3f m_v;
31 |
32 | };
33 |
34 | #endif // PLANE_H
35 |
--------------------------------------------------------------------------------
/dialogs/BoundBoxDialog.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #ifndef BOUNDBOXDIALOG_H
5 | #define BOUNDBOXDIALOG_H
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | QT_BEGIN_NAMESPACE
12 | class QFormLayout;
13 | class QLineEdit;
14 | class QDialogButtonBox;
15 | class QDoubleValidator;
16 | QT_END_NAMESPACE
17 |
18 | class BoundBoxDialog : public QDialog
19 | {
20 | Q_OBJECT
21 |
22 | public:
23 | BoundBoxDialog(QWidget *parent = nullptr);
24 | bool getFields(float minBBox[], float maxBBox[]) const;
25 | void setFields(const float minBBox[3], const float maxBBox[3]);
26 |
27 | private:
28 | QFormLayout *form;
29 | QLineEdit* minLineEdit[3];
30 | QLineEdit* maxLineEdit[3];
31 | QDialogButtonBox *buttonBox;
32 | QDoubleValidator *validator;
33 |
34 | };
35 |
36 |
37 | #endif // BOUNDBOXDIALOG_H
38 |
--------------------------------------------------------------------------------
/utils/pt_to_pt_distsq.cpp:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 | #include "pt_to_pt_distsq.h"
6 |
7 | #include
8 | #include
9 |
10 | //-----------------------------------------------------------
11 |
12 | double pt_to_pt_distsq(const Eigen::VectorXf& v, const Eigen::VectorXf& w)
13 | {
14 | double distsq = 0.0;
15 | for(Eigen::Index i=0; i < v.size(); ++i) {
16 | distsq += (v[i]-w[i])*(v[i]-w[i]);
17 | }
18 | return distsq;
19 | }
20 | //-----------------------------------------------------------
21 |
22 | double pt_to_pt_distsq(const float v[3], const float w[3])
23 | {
24 | double distsq = 0.0;
25 | for(size_t i=0; i < 3; ++i) {
26 | distsq += (v[i]-w[i])*(v[i]-w[i]);
27 | }
28 | return distsq;
29 | }
30 | //-----------------------------------------------------------
31 |
--------------------------------------------------------------------------------
/MessageLogger.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 | #ifndef MESSAGELOGGER_H
6 | #define MESSAGELOGGER_H
7 |
8 | #include
9 | #include
10 |
11 | //QT_BEGIN_NAMESPACE
12 | //class QPlainTextEdit;
13 | //QT_END_NAMESPACE
14 |
15 | class MessageLogger : public QObject
16 | {
17 | Q_OBJECT
18 |
19 | public:
20 | explicit MessageLogger(QObject *parent = nullptr);
21 | ~MessageLogger();
22 |
23 | void logMessage(const QString& text, bool append = true);
24 |
25 | void logProgress(const QString& msgPrefix, size_t i, size_t n,
26 | int infreq, size_t& threshold, size_t& lastPos);
27 |
28 | signals:
29 | void undo();
30 | void logTextAppend(const QString& text);
31 | void logTextInsert(const QString& text);
32 |
33 | private:
34 | //QPlainTextEdit *m_logText;
35 | size_t m_lastPos = 0;
36 | QRecursiveMutex m_recMutex;
37 | };
38 |
39 | #endif // MESSAGELOGGER_H
40 |
--------------------------------------------------------------------------------
/MessageLogger.cpp:
--------------------------------------------------------------------------------
1 | #include "MessageLogger.h"
2 |
3 | #include
4 | #include
5 | #include
6 |
7 |
8 | MessageLogger::MessageLogger(QObject *parent) :
9 | QObject(parent)
10 | {
11 |
12 | }
13 |
14 |
15 | MessageLogger::~MessageLogger()
16 | {
17 |
18 | }
19 |
20 | void MessageLogger::logMessage(const QString& text, bool append) {
21 |
22 | QMutexLocker locker(&m_recMutex);
23 |
24 | if( append ){
25 | emit logTextAppend(text);
26 | ++m_lastPos;
27 | }
28 | else{
29 | emit logTextInsert(text);
30 | }
31 |
32 | }
33 |
34 | void MessageLogger::logProgress(
35 | const QString& msgPrefix, size_t i, size_t n, int infreq,
36 | size_t& threshold, size_t& lastPos) {
37 | float percent = (100.0f*i)/n;
38 | if(percent >= threshold) {
39 | QMutexLocker locker(&m_recMutex);
40 | bool append = threshold > 0 ? (lastPos < m_lastPos) : true;
41 | logMessage(msgPrefix + ": " + QString::number(int(percent)) + "%...",
42 | append);
43 | threshold += infreq;
44 | lastPos = m_lastPos;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/CloudWorker.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 | #ifndef RECONSTRUCTTHREAD_H
6 | #define RECONSTRUCTTHREAD_H
7 |
8 | #include "constants.h"
9 |
10 | #include
11 | #include
12 |
13 | class Cloud;
14 | class BoundBox;
15 |
16 |
17 | class CloudWorker : public QObject
18 | {
19 | Q_OBJECT
20 |
21 | public:
22 | explicit CloudWorker(
23 | Cloud& cloud, QObject *parent = nullptr);
24 | ~CloudWorker();
25 |
26 | public slots:
27 | void approxCloudNorms(int nIters, size_t kNN);
28 | void decimateCloud(size_t nHoles, size_t kNN);
29 | void sparsifyCloud(float percent);
30 | void reconstructCloud(
31 | int kSVDIters, size_t kNN, size_t nfreq, float densify,
32 | size_t natm, size_t latm, size_t maxNewPoints, bool looseBBox,
33 | SparseApprox method);
34 |
35 |
36 | signals:
37 | void finished(bool updateBBox);
38 |
39 | private:
40 | Cloud *m_cloud;
41 | QMutex m_mutex;
42 | };
43 |
44 |
45 | #endif // RECONSTRUCTTHREAD_H
46 |
--------------------------------------------------------------------------------
/dictionarylearning/MatchingPursuit.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 |
6 | #ifndef MATCHINGPURSUIT_H
7 | #define MATCHINGPURSUIT_H
8 |
9 | #include "alignment.h"
10 |
11 | #include
12 |
13 |
14 | class MatchingPursuit
15 | {
16 | using Index = Eigen::Index;
17 | using MatrixXf = Eigen::MatrixXf;
18 | using VectorXf = Eigen::VectorXf;
19 |
20 | public:
21 | MatchingPursuit() :
22 | ndim(0), natm(0), lmax(0) {}
23 |
24 | MatchingPursuit(const MatchingPursuit &mp) : MatchingPursuit() {}
25 | //{ ensure(sa.ndim, sa.natm, sa.lmax); }
26 |
27 | ~MatchingPursuit(){}
28 |
29 | void ensure(Index nd, Index na, Index lm);
30 |
31 | void operator() (
32 | const VectorXf& Y, const MatrixXf& D, Index l,
33 | VectorXf& X, VectorXf& R);
34 |
35 | private:
36 | Index ndim; // Size of signal vector.
37 | Index natm; // No. of 'atoms' in dictionary.
38 | Index lmax; // maximum sparsity constraint <= natm.
39 |
40 | };
41 |
42 | #endif // MATCHINGPURSUIT_H
43 |
--------------------------------------------------------------------------------
/dialogs/get_field.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #include "get_field.h"
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | bool get_integer_field(
11 | QLineEdit *lineEdit, QIntValidator *validator, size_t& field)
12 | {
13 | QString fieldStr = lineEdit->text();
14 | int pos = 0;
15 | if(validator->validate(fieldStr, pos) != QValidator::Acceptable){
16 | lineEdit->clear();
17 | return false;
18 | }
19 | else{
20 | bool ok;
21 | field = fieldStr.toULongLong(&ok);
22 | if(!ok) {
23 | lineEdit->clear();
24 | return false;
25 | }
26 | }
27 |
28 | return true;
29 | }
30 |
31 | bool get_float_field(
32 | QLineEdit *lineEdit, QDoubleValidator *validator, float& field)
33 | {
34 | QString fieldStr = lineEdit->text();
35 | int pos = 0;
36 | if(validator->validate(fieldStr, pos) != QValidator::Acceptable){
37 | lineEdit->clear();
38 | return false;
39 | }
40 | else{
41 | bool ok;
42 | field = fieldStr.toFloat(&ok);
43 | if(!ok) {
44 | lineEdit->clear();
45 | return false;
46 | }
47 | }
48 |
49 | return true;
50 | }
51 |
--------------------------------------------------------------------------------
/dialogs/RandomSurfDialog.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #include "RandomSurfDialog.h"
5 | #include "get_field.h"
6 | #include "constants.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 |
17 | RandomSurfDialog::RandomSurfDialog(QWidget *parent) : QDialog(parent)
18 | {
19 | validator = new QIntValidator(1, int_infinity, this);
20 |
21 | form = new QFormLayout(this);
22 | form->addRow(new QLabel(
23 | "Create a new point cloud sampled randomly from a random surface"));
24 | nPointsLineEdit = new QLineEdit(this);
25 | nPointsLineEdit->setValidator(validator);
26 | nPointsLineEdit->setText("15000");
27 | form->addRow(QString("Number of points sampled:"), nPointsLineEdit);
28 |
29 | buttonBox = new QDialogButtonBox(
30 | QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
31 | Qt::Horizontal, this);
32 |
33 | form->addRow(buttonBox);
34 | connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
35 | connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
36 |
37 | }
38 |
39 |
40 | bool RandomSurfDialog::getFields(size_t& nPoints) const
41 | {
42 |
43 | bool ok = get_integer_field(nPointsLineEdit, validator, nPoints);
44 | return ok;
45 | }
46 |
47 |
48 |
--------------------------------------------------------------------------------
/dialogs/SparsifyDialog.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #include "SparsifyDialog.h"
5 | #include "get_field.h"
6 | #include "constants.h"
7 |
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 |
19 | SparsifyDialog::SparsifyDialog(QWidget *parent) : QDialog(parent)
20 | {
21 | validator = new QDoubleValidator(0.0, 100.0, 5, this);
22 |
23 | form = new QFormLayout(this);
24 | form->addRow(new QLabel(
25 | "Take a random subset of point cloud within bounding box"));
26 | percentLineEdit = new QLineEdit(this);
27 | percentLineEdit->setValidator(validator);
28 | percentLineEdit->setText("7.0");
29 | form->addRow(QString("Percentage of points to keep:"), percentLineEdit);
30 |
31 | buttonBox = new QDialogButtonBox(
32 | QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
33 | Qt::Horizontal, this);
34 |
35 | form->addRow(buttonBox);
36 | connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
37 | connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
38 |
39 | }
40 |
41 |
42 | bool SparsifyDialog::getFields(float& percent) const
43 | {
44 | bool ok = get_float_field(percentLineEdit, validator, percent);
45 | return ok;
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/utils/Plane.cpp:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 | #include "Plane.h"
6 |
7 | #include
8 |
9 | using Eigen::Index;
10 | using Eigen::Matrix3f;
11 | using Eigen::Vector3f;
12 | using Eigen::Vector2f;
13 |
14 | //-----------------------------------------------------------
15 |
16 | void Plane::set(const Vector3f p0, const Vector3f norm)
17 | {
18 |
19 | const float RRT2 = 1.0f/sqrt(2.0f);
20 | m_p0 = p0;
21 | m_norm = norm;
22 |
23 | if( abs(norm(0)) < RRT2 ) {
24 | m_u(0) = 0.0f;
25 | m_u(1) = norm(2);
26 | m_u(2) = -norm(1);
27 | }
28 | else{
29 | m_u(0) = -norm(2);
30 | m_u(1) = 0.0f;
31 | m_u(2) = norm(0);
32 | }
33 | m_v = m_u.cross(norm);
34 |
35 | m_u.normalize();
36 | m_v.normalize();
37 |
38 | }
39 | //-----------------------------------------------------------
40 |
41 | Eigen::Vector2f Plane::project_uv(const Vector3f q)
42 | {
43 | Vector3f w = q - m_p0;
44 | Vector2f puv;
45 | puv(0) = w.dot(m_u);
46 | puv(1) = w.dot(m_v);
47 | return puv;
48 | }
49 |
50 | //-----------------------------------------------------------
51 |
52 |
53 | Eigen::Vector3f Plane::project(const Vector3f q, Vector2f& puv)
54 | {
55 | puv = project_uv(q);
56 | Vector3f p = puv(0)*m_u + puv(1)*m_v;
57 | return p;
58 | }
59 |
60 | //-----------------------------------------------------------
61 |
62 |
63 |
--------------------------------------------------------------------------------
/dictionarylearning/ksvd_dct2D.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 |
6 | #ifndef KSVD_DCT2D_H
7 | #define KSVD_DCT2D_H
8 |
9 | #include "alignment.h"
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | class MessageLogger;
16 |
17 | void ksvd_dct2D(
18 | bool useOpenMP,
19 | const std::vector& Y,
20 | const std::vector& U,
21 | const std::vector& V,
22 | Eigen::Index nfreq,
23 | Eigen::Index latm,
24 | int maxIters,
25 | float maxError,
26 | const std::function sparseFunct,
33 | Eigen::MatrixXf& D,
34 | Eigen::MatrixXf& X,
35 | MessageLogger* msgLogger = nullptr
36 | );
37 |
38 |
39 | void print_error_dct2D(
40 | bool useOpenMP,
41 | const std::vector& Y,
42 | const std::vector& U,
43 | const std::vector& V,
44 | const Eigen::MatrixXf& D,
45 | const Eigen::MatrixXf& X,
46 | Eigen::Index nfreq,
47 | Eigen::Index iter,
48 | MessageLogger* msgLogger
49 | );
50 |
51 |
52 | void column_normalize(Eigen::Ref M,
53 | Eigen::Ref NrmInv);
54 |
55 | #endif // KSVD_DCT2D_H
56 |
--------------------------------------------------------------------------------
/dialogs/ReconstructDialog.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #ifndef RECONSTRUCTDIALOG_H
5 | #define RECONSTRUCTDIALOG_H
6 |
7 | #include "constants.h"
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | QT_BEGIN_NAMESPACE
14 | class QFormLayout;
15 | class QLineEdit;
16 | class QDialogButtonBox;
17 | class QIntValidator;
18 | class QDoubleValidator;
19 | class QComboBox;
20 | QT_END_NAMESPACE
21 |
22 | class ReconstructDialog : public QDialog
23 | {
24 | Q_OBJECT
25 |
26 | public:
27 | ReconstructDialog(QWidget *parent = nullptr);
28 | int getFields(
29 | int& kSVDIters, size_t& kNN, size_t& nfreq, float& densify,
30 | size_t& natm, size_t& latm, size_t& maxNewPoints, bool& looseBBox,
31 | SparseApprox& method) const;
32 |
33 | public slots:
34 | void bBoxComboChanged(int idx) { m_bBoxComboIdx = idx; }
35 | void methodComboChanged(int idx) { m_methodComboIdx = idx; }
36 |
37 | private:
38 | QFormLayout *form;
39 | QLineEdit *nItersLineEdit;
40 | QLineEdit *kNNLineEdit;
41 | QLineEdit *nFreqLineEdit;
42 | QLineEdit *densifyLineEdit;
43 | QLineEdit *nAtmLineEdit;
44 | QLineEdit *lAtmLineEdit;
45 | QLineEdit *maxNewLineEdit;
46 | QComboBox *bBoxComboBox;
47 | int m_bBoxComboIdx = 0;
48 | QComboBox *methodComboBox;
49 | int m_methodComboIdx = 0;
50 |
51 | QDialogButtonBox *buttonBox;
52 | QIntValidator *intValidator;
53 | QDoubleValidator *doubleValidator;
54 |
55 | };
56 |
57 | #endif // RECONSTRUCTDIALOG_H
58 |
--------------------------------------------------------------------------------
/dialogs/NormalsDialog.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #include "NormalsDialog.h"
5 | #include "get_field.h"
6 | #include "constants.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 |
18 | NormalsDialog::NormalsDialog(QWidget *parent) : QDialog(parent)
19 | {
20 | validator = new QIntValidator(1, int_infinity, this);
21 |
22 | form = new QFormLayout(this);
23 | form->addRow(new QLabel("Approximate cloud normals"));
24 | nItersLineEdit = new QLineEdit(this);
25 | nItersLineEdit->setValidator(validator);
26 | nItersLineEdit->setText("25");
27 | form->addRow(QString("Number of iterations:"), nItersLineEdit);
28 | kNNLineEdit = new QLineEdit(this);
29 | kNNLineEdit->setValidator(validator);
30 | kNNLineEdit->setText("25");
31 | form->addRow(QString("Number of neighbouring points used:"), kNNLineEdit);
32 |
33 | buttonBox = new QDialogButtonBox(
34 | QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
35 | Qt::Horizontal, this);
36 |
37 | form->addRow(buttonBox);
38 | connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
39 | connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
40 |
41 | }
42 |
43 |
44 |
45 | bool NormalsDialog::getFields(int& nIters, size_t& kNN) const
46 | {
47 | bool ok;
48 | size_t temp;
49 |
50 | ok = get_integer_field(nItersLineEdit, validator, temp);
51 | if(!ok) return false;
52 | nIters = int(temp);
53 |
54 | ok = get_integer_field(kNNLineEdit, validator, kNN);
55 | if(!ok) return false;
56 |
57 | return true;
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/dialogs/DecimateDialog.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #include "DecimateDialog.h"
5 | #include "get_field.h"
6 | #include "constants.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 |
18 | DecimateDialog::DecimateDialog(QWidget *parent) : QDialog(parent)
19 | {
20 | validator = new QIntValidator(1, int_infinity, this);
21 |
22 | form = new QFormLayout(this);
23 | form->addRow(new QLabel("Create random holes within bounding box"));
24 | nHolesLineEdit = new QLineEdit(this);
25 | nHolesLineEdit->setValidator(validator);
26 | nHolesLineEdit->setText("50");
27 | form->addRow(QString("Number of holes:"), nHolesLineEdit);
28 | nPointsLineEdit = new QLineEdit(this);
29 | nPointsLineEdit->setValidator(validator);
30 | nPointsLineEdit->setText("100");
31 | form->addRow(QString("Number of points per hole:"), nPointsLineEdit);
32 |
33 | buttonBox = new QDialogButtonBox(
34 | QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
35 | Qt::Horizontal, this);
36 |
37 | form->addRow(buttonBox);
38 | connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
39 | connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
40 |
41 | }
42 |
43 |
44 |
45 | bool DecimateDialog::getFields(size_t& nHoles, size_t& kNN) const
46 | {
47 | bool ok;
48 |
49 | ok = get_integer_field(nHolesLineEdit, validator, nHoles);
50 | if(!ok) return false;
51 |
52 | ok = get_integer_field(nPointsLineEdit, validator, kNN);
53 | if(!ok) return false;
54 |
55 | return true;
56 | }
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/dialogs/OptionsDialog.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 | #include "OptionsDialog.h"
5 | #include "get_field.h"
6 | #include "constants.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | OptionsDialog::OptionsDialog(QWidget *parent) : QDialog(parent)
18 | {
19 | validator = new QDoubleValidator(0.0, double_infinity, 5, this);
20 |
21 | form = new QFormLayout(this);
22 | form->addRow(new QLabel("Change app settings"));
23 |
24 | pointSizeLineEdit = new QLineEdit(this);
25 | pointSizeLineEdit->setValidator(validator);
26 | pointSizeLineEdit->setText("5.0");
27 | form->addRow(QString("Display point size:"), pointSizeLineEdit);
28 |
29 | normScaleLineEdit = new QLineEdit(this);
30 | normScaleLineEdit->setValidator(validator);
31 | normScaleLineEdit->setText("0.01");
32 | form->addRow(QString("Display normals size:"), normScaleLineEdit);
33 |
34 | buttonBox = new QDialogButtonBox(
35 | QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
36 | Qt::Horizontal, this);
37 |
38 | form->addRow(buttonBox);
39 | connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
40 | connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
41 |
42 | }
43 |
44 |
45 | bool OptionsDialog::getFields(float& pointSize, float& normScale) const
46 | {
47 |
48 | bool ok;
49 |
50 | ok = get_float_field(pointSizeLineEdit, validator, pointSize);
51 | if(!ok) return false;
52 |
53 | ok = get_float_field(normScaleLineEdit, validator, normScale);
54 | if(!ok) return false;
55 |
56 | return true;
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/Cover-Tree/CoverTreePoint.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 |
6 |
7 | // Brief description
8 | // Point on a cover tree stored as a vector in Eigen.
9 |
10 | #ifndef _COVERTREEPOINT_H
11 | #define _COVERTREEPOINT_H
12 |
13 | #include "pt_to_pt_distsq.h"
14 | #include
15 |
16 |
17 | template
18 | class CoverTreePoint {
19 | private:
20 | T _vec;
21 | size_t _id;
22 | public:
23 | CoverTreePoint(T v, size_t id) : _vec(v), _id(id) {}
24 | CoverTreePoint(){}
25 | ~CoverTreePoint(){}
26 | double distance(const CoverTreePoint& p) const;
27 | const T& getVec() const;
28 | size_t getId() const;
29 | void set(const T& v, size_t id);
30 | void print() const;
31 | bool operator==(const CoverTreePoint&) const;
32 | };
33 |
34 | template
35 | double CoverTreePoint::distance(const CoverTreePoint& p) const {
36 | const T& vec2 = p.getVec();
37 | assert(vec2.size() == _vec.size());
38 | double distsq = 0.0;
39 | size_t n = size_t(_vec.size());
40 | for(size_t i=0; i < n; ++i) {
41 | distsq += (_vec[i]-vec2[i])*(_vec[i]-vec2[i]);
42 | }
43 | return distsq;
44 | }
45 |
46 | template
47 | const T& CoverTreePoint::getVec() const {
48 | return _vec;
49 | }
50 |
51 | template
52 | size_t CoverTreePoint::getId() const {
53 | return _id;
54 | }
55 |
56 | template
57 | void CoverTreePoint::set(const T& v, size_t id) {
58 | _vec = v;
59 | _id = id;
60 | }
61 |
62 | template
63 | void CoverTreePoint::print() const {
64 | std::cout << "point " << _id << ": " << _vec << "\n";
65 | }
66 |
67 | template
68 | bool CoverTreePoint::operator==(const CoverTreePoint& p) const {
69 | return (_id==p.getId());
70 | }
71 |
72 |
73 | #endif // _COVERTREEPOINT_H
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/dictionarylearning/OrthogonalPursuit.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 |
6 | #ifndef ORTHOGONALPURSUIT_H
7 | #define ORTHOGONALPURSUIT_H
8 |
9 |
10 | #include "alignment.h"
11 |
12 | #include
13 | #include
14 |
15 |
16 | class OrthogonalPursuit
17 | {
18 | using Index = Eigen::Index;
19 | using MatrixXf = Eigen::MatrixXf;
20 | using VectorXf = Eigen::VectorXf;
21 | using MapVectf = Eigen::Map;
22 | using MapMtrxf = Eigen::Map;
23 | template using Map = Eigen::Map;
24 | template using vector = std::vector>;
25 |
26 | public:
27 | OrthogonalPursuit() :
28 | ndim(0), natm(0), lmax(0), dworkOffset(0),
29 | U(nullptr,0), V(nullptr,0), W(nullptr,0),
30 | XI(nullptr,0), I(nullptr,0),
31 | E(nullptr,0,0), F(nullptr,0,0),
32 | ETblk(nullptr,0,0), Fblk(nullptr,0,0),
33 | ldlt(nullptr), ldltSize(0) {}
34 |
35 | OrthogonalPursuit(const OrthogonalPursuit &op) : OrthogonalPursuit(){}
36 | //{ ensure(sa.ndim, sa.natm, sa.lmax); }
37 |
38 | ~OrthogonalPursuit(){
39 | delete ldlt;
40 | }
41 |
42 | void ensure(Index nd, Index na, Index lm);
43 |
44 | void operator() (
45 | const VectorXf& Y, const MatrixXf& D, Index l,
46 | VectorXf& X, VectorXf& R);
47 |
48 | private:
49 | void ensureWorkspace();
50 |
51 | Index ndim; // Size of signal vector.
52 | Index natm; // No. of 'atoms' in dictionary.
53 | Index lmax; // maximum sparsity constraint <= natm.
54 |
55 | vector dwork;
56 | size_t dworkOffset;
57 | vector iwork;
58 | // Work-space mapped onto work buffer.
59 | MapVectf U, V, W, XI;
60 | Map< Eigen::Matrix > I;
61 | MapMtrxf E, F, ETblk, Fblk;
62 |
63 | Eigen::LDLT *ldlt;
64 | Index ldltSize;
65 |
66 |
67 | };
68 |
69 | #endif // ORTHOGONALPURSUIT_H
70 |
71 |
--------------------------------------------------------------------------------
/stable.h:
--------------------------------------------------------------------------------
1 | /* Add C includes here */
2 |
3 | //#if defined __cplusplus
4 | /* Add C++ includes here */
5 | //#include
6 | //#include
7 | //#include
8 | //#include
9 | //#include
10 | //#include
11 | //#include
12 | //#include
13 | //#include
14 | //#include
15 | //#include
16 | //#include
17 | //#include
18 | //#include
19 | //#include
20 | //#include
21 | //#include
22 | //#include
23 | //#include
24 | //#include
25 | //#include
26 | //#include
27 | //#include
28 | //#include
29 | //#include
30 | ////#include
31 | //#include
32 | //#include
33 | //#include
34 | //#include
35 | //#include
36 | //#include
37 | //#include
38 | //#include
39 | //#include
40 | //#include
41 | //#include
42 | //#include
43 | //#include
44 | //#include
45 | //#include
46 | //#include
47 | //#include
48 | //#include
49 | //#include
50 | //#include
51 | //#include
52 | //#include
53 | //#include
54 | //#include
55 | //#include
56 | //#include
57 | //#include
58 | //#include
59 | //#include
60 | //#include
61 | //#include
62 | //#include
63 | //#include
64 | //#include
65 | //#include
66 | //#include
67 | //#include
68 | //#include
69 | //#endif
70 |
--------------------------------------------------------------------------------
/CloudWorker.cpp:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 | #include "CloudWorker.h"
6 | #include "Cloud.h"
7 | #include "constants.h"
8 |
9 | //-------------------------------------------------------------------------
10 | CloudWorker::CloudWorker(Cloud& cloud, QObject *parent) :
11 | QObject(parent)
12 | {
13 | m_cloud = &cloud;
14 | }
15 |
16 | //-------------------------------------------------------------------------
17 | CloudWorker::~CloudWorker()
18 | {
19 | }
20 |
21 | //-------------------------------------------------------------------------
22 |
23 | void CloudWorker::approxCloudNorms(int nIters, size_t kNN)
24 | {
25 | if(m_cloud->pointCount() == 0) return;
26 | m_cloud->approxCloudNorms(nIters, kNN);
27 | emit finished(false);
28 |
29 | }
30 |
31 | //-------------------------------------------------------------------------
32 | void CloudWorker::decimateCloud(size_t nHoles, size_t kNN)
33 | {
34 | if(m_cloud->pointCount() == 0) return;
35 | m_cloud->backup();
36 | m_cloud->decimate(nHoles, kNN);
37 |
38 | emit finished(false);
39 | }
40 |
41 | //-------------------------------------------------------------------------
42 | void CloudWorker::sparsifyCloud(float percent)
43 | {
44 | if(m_cloud->pointCount() == 0) return;
45 | m_cloud->backup();
46 | m_cloud->sparsify(percent);
47 |
48 | emit finished(false);
49 | }
50 |
51 | //-------------------------------------------------------------------------
52 |
53 | void CloudWorker::reconstructCloud(
54 | int kSVDIters, size_t kNN, size_t nfreq, float densify,
55 | size_t natm, size_t latm, size_t maxNewPoints, bool looseBBox,
56 | SparseApprox method)
57 | {
58 | if(m_cloud->pointCount() == 0) return;
59 | m_cloud->backup();
60 | m_cloud->reconstruct(
61 | kSVDIters, kNN, nfreq, densify, natm, latm,
62 | maxNewPoints, looseBBox, method);
63 |
64 | emit finished(false);
65 |
66 | }
67 |
68 |
69 | //-------------------------------------------------------------------------
70 |
--------------------------------------------------------------------------------
/Cover-Tree/README:
--------------------------------------------------------------------------------
1 | This is a C++ implementation of the cover tree datastructure. Implements the
2 | cover tree algorithms for insert, removal, and k-nearest-neighbor search.
3 |
4 | To build simply type make in the terminal from the project directory. Do
5 | ./test to run the tests. Look in test.cc for example code of how to use the
6 | cover tree.
7 |
8 | Relevant links:
9 | https://secure.wikimedia.org/wikipedia/en/wiki/Cover_tree - Wikipedia's page
10 | on cover trees.
11 | http://hunch.net/~jl/projects/cover_tree/cover_tree.html - John Langford's (one
12 | of the inventors of cover trees) page on cover trees with links to papers.
13 |
14 | To use the Cover Tree, you must implement your own Point class. CoverTreePoint
15 | is provided for testing and as an example. Your Point class must implement the
16 | following functions:
17 |
18 | double YourPoint::distance(const YourPoint& p);
19 | bool YourPoint::operator==(const YourPoint& p);
20 | and optionally (for debugging/printing only):
21 | void YourPoint::print();
22 |
23 | The distance function must be a Metric, meaning (from Wikipedia):
24 | 1: d(x, y) = 0 if and only if x = y
25 | 2: d(x, y) = d(y, x) (symmetry)
26 | 3: d(x, z) =< d(x, y) + d(y, z) (subadditivity / triangle inequality).
27 |
28 | See https://secure.wikimedia.org/wikipedia/en/wiki/Metric_%28mathematics%29
29 | for details.
30 |
31 | Actually, 1 does not exactly need to hold for this implementation; you can
32 | provide, for example, names for your points which are unrelated to distance
33 | but important for equality. You can insert multiple points with distance 0 to
34 | each other and the tree will keep track of them, but you cannot insert multiple
35 | points that are equal to each other; attempting to insert a point that
36 | already exists in the tree will not alter the tree at all.
37 |
38 | If you do not want to allow multiple nodes with distance 0, then just make
39 | your equality operator always return true when distance is 0.
40 |
41 | TODO:
42 | -The papers describe batch insert and batch-nearest-neighbors algorithms which
43 | may be worth implementing.
44 | -Try using a third "upper bound" argument for distance functions, beyond which
45 | the distance does not need to be calculated, to improve efficiency in practice.
46 |
--------------------------------------------------------------------------------
/utils/rotations.cpp:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 | #include "rotations.h"
6 | #include "constants.h"
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | using Eigen::Vector3f;
13 | using Eigen::Matrix3f;
14 |
15 |
16 | //-----------------------------------------------------------
17 | // Returns the rotation matrix M that rotates vector v to a
18 | // vector w (or to a line through w if lineThruW is true).
19 |
20 | void vector_to_vector_rotation_matrix(
21 | const Vector3f& v, const Vector3f& w,
22 | bool normalized, bool lineThruW, Matrix3f& M)
23 | {
24 |
25 | Vector3f vxw = v.cross(w);
26 | float vxwLen = vxw.norm();
27 | float cosa = v.dot(w);
28 | float sina = vxwLen;
29 |
30 | if( lineThruW ){
31 | if( cosa < 0.0f ){
32 | cosa = -cosa;
33 | vxw = -vxw;
34 | }
35 | }
36 |
37 | if( !normalized ){
38 | float vvww = sqrt(v.dot(v)*w.dot(w));
39 |
40 | if( vvww > float_tiny ){
41 | cosa = cosa/vvww;
42 | sina = sina/vvww;
43 | }
44 | else{
45 | cosa = 1.0f;
46 | sina = 0.0f;
47 | }
48 | }
49 |
50 | if( vxwLen > float_tiny ){
51 | Vector3f u = vxw/vxwLen;
52 | cos_sin_angle_vector_rotation_matrix(cosa, sina, u, M);
53 | }
54 | else{
55 | M.setIdentity();
56 | if( cosa < 0.0f ) M = -M;
57 | }
58 |
59 | }
60 |
61 | //-----------------------------------------------------------
62 | /*
63 | Returns the counter-clockwise rotation matrix M around
64 | a unit vector U by an angle. U must have unit length.
65 | */
66 | void angle_vector_rotation_matrix(
67 | float angle, const Vector3f& u, Matrix3f& M)
68 | {
69 | cos_sin_angle_vector_rotation_matrix(cos(angle), sin(angle), u, M);
70 | }
71 |
72 | //-----------------------------------------------------------
73 |
74 | void cos_sin_angle_vector_rotation_matrix(
75 | float cosa, float sina, const Vector3f& u,
76 | Matrix3f& M)
77 | {
78 |
79 | Vector3f tu = (1.0f-cosa)*u;
80 | Vector3f su = sina*u;
81 |
82 | M(0,0) = tu(0)*u(0) + cosa;
83 | M(1,0) = tu(0)*u(1) + su(2);
84 | M(2,0) = tu(0)*u(2) - su(1);
85 |
86 | M(0,1) = tu(1)*u(0) - su(2);
87 | M(1,1) = tu(1)*u(1) + cosa;
88 | M(2,1) = tu(1)*u(2) + su(0);
89 |
90 | M(0,2) = tu(2)*u(0) + su(1);
91 | M(1,2) = tu(2)*u(1) - su(0);
92 | M(2,2) = tu(2)*u(2) + cosa;
93 | }
94 | //-----------------------------------------------------------
95 |
--------------------------------------------------------------------------------
/BoundBox.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 | #ifndef BOUNDBOX_H
6 | #define BOUNDBOX_H
7 |
8 | #include "pt_to_pt_distsq.h"
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | class MessageLogger;
15 | class Cloud;
16 |
17 | class BoundBox
18 | {
19 | using Index = Eigen::Index;
20 | using Vector3f = Eigen::Vector3f;
21 |
22 | public:
23 | BoundBox(MessageLogger* msgLogger = nullptr): m_msgLogger(msgLogger){}
24 | BoundBox(
25 | const float minBBox[3], const float maxBBox[3],
26 | MessageLogger* msgLogger = nullptr);
27 | BoundBox(const Cloud& cloud, MessageLogger* msgLogger = nullptr);
28 |
29 | void set(const float minBBox[3], const float maxBBox[3]);
30 | void set(const Cloud& cloud);
31 | void pad(float padX, float padY, float padZ);
32 | void rescale(float frac);
33 | void setParentCloud(Cloud *cloud);
34 |
35 | int vertCount() const { return m_vertCount; }
36 | void getExtents(float minBBox[], float maxBBox[]) const {
37 | for(int i=0; i < 3; ++i){
38 | minBBox[i] = m_minBBox[i];
39 | maxBBox[i] = m_maxBBox[i];
40 | }
41 | }
42 | float diagonalSize() const {
43 | return sqrt(pt_to_pt_distsq(m_minBBox, m_maxBBox));
44 | }
45 |
46 | const GLfloat *vertGLData();
47 | const GLuint *elemGLData() const
48 | { return static_cast(m_elemGL.data()); }
49 |
50 | bool pointInBBox(const Vector3f& p) const {
51 | return p(0) >= m_minBBox[0] && p(0) <= m_maxBBox[0] &&
52 | p(1) >= m_minBBox[1] && p(1) <= m_maxBBox[1] &&
53 | p(2) >= m_minBBox[2] && p(2) <= m_maxBBox[2];
54 | }
55 |
56 | float ballInBBox(const Vector3f& p, float radius) const {
57 | return p(0) - m_minBBox[0] >= radius &&
58 | p(1) - m_minBBox[1] >= radius &&
59 | p(2) - m_minBBox[2] >= radius &&
60 | m_maxBBox[0] - p(0) >= radius &&
61 | m_maxBBox[1] - p(1) >= radius &&
62 | m_maxBBox[2] - p(2) >= radius;
63 | }
64 |
65 | void logMessageBBox() const;
66 |
67 |
68 | private:
69 | float m_minBBox[3] = {0.0f,0.0f,0.0f};
70 | float m_maxBBox[3] = {0.0f,0.0f,0.0f};
71 | int m_vertCount = 0;
72 | std::array m_vertGL;
73 | Cloud* m_cloud = nullptr;
74 |
75 | static constexpr std::array m_elemGL = {
76 | 0, 1,
77 | 0, 2,
78 | 0, 4,
79 | 1, 3,
80 | 1, 5,
81 | 2, 3,
82 | 2, 6,
83 | 3, 7,
84 | 4, 5,
85 | 4, 6,
86 | 5, 7,
87 | 6, 7
88 | };
89 |
90 | MessageLogger* m_msgLogger;
91 |
92 |
93 | };
94 |
95 | #endif // BOUNDBOX_H
96 |
--------------------------------------------------------------------------------
/dictionarylearning/MatchingPursuit.cpp:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------
2 | // Copyright (C) 2019 Piotr (Peter) Beben
3 | // See LICENSE included with this distribution.
4 |
5 |
6 | #include "MatchingPursuit.h"
7 | #include "ensure_buffer_size.h"
8 | #include "constants.h"
9 |
10 | #include
11 |
12 | using Index = Eigen::Index;
13 | using MatrixXf = Eigen::MatrixXf;
14 | using VectorXf = Eigen::VectorXf;
15 |
16 | //-------------------------------------------------------------------------
17 | void MatchingPursuit::ensure(
18 | Index nd, Index na, Index lm)
19 | {
20 | if(nd != ndim || na != natm || lm != lmax){
21 | ndim = nd;
22 | natm = na;
23 | lmax = (na < lm) ? na : lm;
24 | }
25 | }
26 |
27 |
28 | //-------------------------------------------------------------------------
29 | /**
30 | Given a size n signal vector Y, an n x m dictionary matrix D of
31 | m atoms (unit column vectors of size n), and an integer L,
32 | our task is to find a sparse size m code vector X that encodes Y
33 | as closely as possible using no more than L atoms in D. In detail,
34 | we try to solve to minimization problem
35 |
36 | min_X ||Y - DX||_F
37 | subject to
38 | ||X||_0 <= L
39 |
40 | where ||.||_F is the matrix Frobenius norm, and ||.||_0 is the
41 | vector L_0 norm (the number of non-zero entries in a vector).
42 |
43 | This is a greedy approach using the matching pursuit algorithm.
44 |
45 | @param[in] Y: size n vector.
46 | @param[in] D: n x m dictionary matrix.
47 | @param[in] latm: Sparsity constraint L.
48 | @param[out] X: size m code vector.
49 | @param[out] R: size n residual vector.
50 |
51 | */
52 |
53 |
54 |
55 | void MatchingPursuit::operator()(
56 | const VectorXf& Y, const MatrixXf& D, Index latm, VectorXf& X, VectorXf& R)
57 | {
58 | assert(D.rows() == Y.rows());
59 | assert(D.cols() == X.rows());
60 | ensure(D.rows(), D.cols(), latm);
61 |
62 | X.setZero();
63 | R = Y;
64 |
65 | for(Index j = 1; j <= latm; ++j){
66 | float absprojmax = -float_infinity;
67 | float projmax = 0;
68 | Index imax = 0;
69 | for(Index i = 0; i < natm; ++i){
70 | if( X(i) != 0.0f ) continue;
71 | float proj = R.dot(D.col(i));
72 | float absproj = abs(proj);
73 | if( absproj > absprojmax ){
74 | projmax = proj;
75 | absprojmax = absproj;
76 | imax = i;
77 | }
78 | }
79 | X(imax) = projmax;
80 | R = R - projmax*D.col(imax);
81 | }
82 | }
83 | //-------------------------------------------------------------------------
84 |
--------------------------------------------------------------------------------
/dialogs/BoundBoxDialog.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2019 Piotr (Peter) Beben
2 | // See LICENSE included with this distribution.
3 |
4 |
5 | #include "BoundBoxDialog.h"
6 | #include "get_field.h"
7 | #include "constants.h"
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include