#pragma once

#include <QAction>
#include <QCloseEvent>
#include <QColor>
#include <QComboBox>
#include <QDateTime>
#include <QDebug>
#include <QDesktopWidget>
#include <QFileDialog>
#include <QFontComboBox>
#include <QImage>
#include <QLabel>
#include <QMainWindow>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QProgressDialog>
#include <QRect>
#include <QSettings>
#include <QSpinBox>
#include <QString>
#include <QStringList>
#include <QTextCharFormat>
#include <QTime>
#include <QToolBar>
#include <QToolButton>
#include <QListWidgetItem>

#include <QApplication>
#include <QDateTime> //添加QDateTime头文件
#include <QMovie>
#include <QPixmap>
#include <QSplashScreen>
#include <QTextCodec>

// Point Cloud Library
#include <QColorDialog>
#include <iostream>
#include <pcl/common/common.h>
#include <pcl/console/time.h> // TicToc
#include <pcl/console/time.h>
#include <pcl/filters/convolution_3d.h>
#include <pcl/filters/filter.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>

#include <boost/random.hpp> //随机数
#include <boost/thread/thread.hpp>
#include <iostream>
#include <pcl/console/time.h> // TicToc
#include <pcl/features/normal_3d.h>
#include <pcl/filters/bilateral.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/fast_bilateral.h>
#include <pcl/filters/fast_bilateral_omp.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/registration/ia_fpcs.h>  // 4PCS算法
#include <pcl/registration/ia_kfpcs.h> //K4PCS算法头文件
#include <pcl/registration/icp.h>
#include <pcl/registration/registration.h>
#include <pcl/search/flann_search.h>
#include <pcl/surface/concave_hull.h>
#include <pcl/surface/gp3.h> //贪婪投影三角化算法类定义的头文件
#include <pcl/surface/marching_cubes_hoppe.h> //移动立方体
#include <pcl/surface/marching_cubes_rbf.h>
#include <pcl/surface/mls.h>     //MLS
#include <pcl/surface/poisson.h> //泊松重建
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <string>
#include <vector>
#include <vtkOutputWindow.h>

#include <pcl/console/time.h>                   // TicToc
#include <pcl/filters/approximate_voxel_grid.h> // 体素滤波
#include <pcl/filters/voxel_grid.h>             // 体素滤波
#include <vtkOutputWindow.h>

#include <boost/thread/thread.hpp>
#include <pcl/ModelCoefficients.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h> //随机参数估计方法
#include <pcl/sample_consensus/model_types.h>  //模型定义
#include <pcl/segmentation/sac_segmentation.h> //RANSAC分割
#include <pcl/visualization/pcl_visualizer.h>
#include <sstream>
#include <stdlib.h> //rand()头文件
#include <vtkMassProperties.h>
#include <vtkPLYReader.h>
#include <vtkSmartPointer.h>
#include <vtkTriangleFilter.h>

#include <Eigen/Core>
#include <iostream>
#include <pcl/common/common.h>
#include <pcl/common/transforms.h>
#include <pcl/features/moment_of_inertia_estimation.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <string>
#include <string>
#include <vector>
#include <vtkAutoInit.h>
//可视化相关头文件
#include <vtkActor.h>
#include <vtkAutoInit.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
// Boost
#include <boost/math/special_functions/round.hpp>

// Visualization Toolkit (VTK)
#include <vtkRenderWindow.h>
 
#include "BasePCL.h"


///////////////////////////////////////////////////////////
//// 构建 点法向量
//////////////////////////////////////////////////////////

// 构建点云法向量
void NormalEstimation(pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud, pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals);

////////////////////////////////////////////////////////////////////
// 离群点 + 滤波
//////////////////////////////////////////////////////////////////
/*
                                下采样
*/
void downSampling(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered,
    double leafSize = 0.01f);

 
/*
                                高斯滤波
*/
void gaussian_filter(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered,
    double radius);

/*
                                双边滤波1
*/
void bilateralFilter(pcl::PointCloud<pcl::PointXYZRGBA>::Ptr input,
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr output,
    float sigma_s,
    float sigma_r);

/*
                                半径滤波器:
                                基于密度的杂散点移除
*/
void radius_filter(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered,
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_out,
    double RadiusSearch=0.015,
    int minNearSearch=35);
/*
                                统计滤波器:
                                基于统计的杂散点移除
*/
void statistical_filter(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered,
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_out,
    int meanK= 50,
    double StddevThresh=1.0);




/************************************************************************/
/* 表面重建 */
/************************************************************************/

/*
      下采样点云精简

*/
 

void MLS(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in,
    pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals);

void Pos(pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals,
    pcl::PolygonMesh& mesh,
    int Degree = 2,
    int Depth = 8,
    int IsoDivide = 8,
    float SamplesPerNode=3.0,
    int SolverDivide=8
    );

// 贪婪三角网
void GP(pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals,
    pcl::PolygonMesh& mesh,
    double SearchRadius=1,
    double Mu=2.5,
    int MaximumNearestNeighbors=100,
    double MaximumSurfaceAngle=M_PI/4.0,
    double MinimumAngle=M_PI/18,
    double MaximumAngle=M_PI/3
    );

//移动立方体
void MC(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PolygonMesh& mesh);





/************************************************************************/
/* 点云配准算法 */
/************************************************************************/

//// 接下来使用的点云指针
//PointCloudT::Ptr cloud_in; // Original point cloud
//PointCloudT::Ptr cloud_tr; // Transformed point cloud
//PointCloudT::Ptr cloud_RE; // ICP output point cloud
//
////使用配准基类Registration来实现多态
//pcl::Registration<PointT, PointT>::Ptr ALIGN;
//pcl::IterativeClosestPoint<PointT, PointT>::Ptr icp;
//
////迭代次数
//int iterations = 1; // Default number of ICP iterations
//// bool next_iteration = false;

/*
                打印4*4的矩阵
*/
void print4x4Matrix(const Eigen::Matrix4d& matrix);

// TODO
/*
              4*4的矩阵
*/
QString get4x4MatrixStr(const Eigen::Matrix4d& matrix);

 