<commit_before>#include "visualization.h"
#include <Eigen/Geometry> 


Visualization::Visualization(QString filename)
	:filename(filename)
{
	record = new Record();
	cloud.reset(new PointCloudT);
	cloud_out.reset(new PointCloudT);
	cloud_normals.reset(new PointCloudN);
	viewer.reset(new pcl::visualization::PCLVisualizer("preview", false));

	//kdtreeFlag = false;
	//centroidFlag = false;

	feature_id = 0;

	search_radius = 0.3;
	normal_level = 100;
	normal_scale = 0.0;
}


Visualization::~Visualization()
{
}

void
Visualization::preview(QString filename)
{
	viewer.reset(new pcl::visualization::PCLVisualizer("preview", true));

	std::string file_name = filename.toStdString();

	pcl_time.tic();
	record->statusUpdate("Loading model...");

	if (filename.endsWith(".pcd"))
	{
		if (!pcl::io::loadPCDFile(file_name, *cloud))
		{
			//QMessageBox msgBox;
			//msgBox.setText("Couldn't read file.");
			//int ret = msgBox.exec();
		}
			

	}		
			
	else if (filename.endsWith(".ply"))
	{
		if (!pcl::io::loadPLYFile(file_name, *cloud))
		{
			//QMessageBox msgBox;
			//msgBox.setText("Couldn't read file.");
			//int ret = msgBox.exec();
		}
	}
	//display number of points
	record->info = QString("data size: "
		+ QString::number(cloud->points.size())
		+ "; duration: "
		+ QString::number(pcl_time.toc())
		+ "ms;");
	record->infoRec(record->info);
	record->statusUpdate(record->info);

	viewer->setBackgroundColor(0, 0, 0);
	pcl::visualization::PointCloudColorHandlerCustom<PointT> rgb(cloud, 20, 180, 20);
	//pcl::visualization::PointCloudColorHandlerRGBField<PointC> rgb(cloud);
	viewer->addPointCloud(cloud, rgb, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
	viewer->addCoordinateSystem(10.0);
	viewer->initCameraParameters();

	

	while (!viewer->wasStopped())
	{
		switch (feature_id)
		{
		case 1:
			computeKdtree();
			break;
		case 2:
			computeCentroid();
			break;
		case 3:
			computeNormals();
			break;
		case 4:
			computeFPFH();
			break;
		case 5:
			filter_n_downsampling();
			break;
		case 6:
			computeEGI();
			break;
		default:
			break;
		}
		feature_id = 0;

		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}
}

void
Visualization::OnStarted()
{
	this->preview(filename);
	emit finished();
}

void
Visualization::feature_id_slot(int feature)
{
	feature_id = feature;
}

bool
Visualization::filter_n_downsampling()
{
	////VoxelGrid Filter Downsampling
	//record->statusUpdate("Downsampling...");
	//pcl::VoxelGrid<PointT> grid;
	//const float leaf = 0.005f;
	//grid.setLeafSize(leaf, leaf, leaf);
	//grid.setInputCloud(cloud);
	//grid.filter(*cloud);

	//StatisticalOutlierRemoval Filter
	record->statusUpdate("Remove Statistical Outlier...");
	pcl::StatisticalOutlierRemoval<PointT> sor;
	sor.setInputCloud(cloud);
	sor.setMeanK(normal_level);
	sor.setStddevMulThresh(search_radius);
	sor.filter(*cloud);
	record->statusUpdate("Done");

	////RadiusOutlierRemoval Filter
	//record->statusUpdate("Remove Radius Outlier...");
	//pcl::RadiusOutlierRemoval<PointT> ror;
	//ror.setInputCloud(cloud);
	//ror.setRadiusSearch(search_radius);
	//ror.setMinNeighborsInRadius(normal_level);
	//ror.filter(*cloud);
	//record->statusUpdate("Done");

	pcl::visualization::PointCloudColorHandlerCustom<PointT> rgb(cloud, 20, 180, 20);
	viewer->updatePointCloud(cloud, rgb, "sample cloud");

	return true;
}

bool
Visualization::computeKdtree()
{
	record->statusUpdate("compute Kdtree...");
	pcl_time.tic();
	//kd-tree tutorials
	srand(time(NULL));
	pcl::KdTreeFLANN<PointT> kdtree;
	kdtree.setInputCloud(cloud);
	int size = cloud->points.size();
	PointT searchPoint;
	std::vector<int> indices;
	std::vector<float> meanDistance;
	//searchPoint = cloud->points.at(cloud->points.size() * rand() / (RAND_MAX + 1));

	//viewer->addSphere(searchPoint, 1, 1, 0.2, 0.2, "search Point");

	int k = normal_level;
	std::vector<int> pointIdxNKNSearch(k);
	std::vector<float> pointNKNSquaredDistance(k);
	//std::stringstream ss;
	//ss  << "k nearest neighbor search at (" << searchPoint.x
	//	<< " " << searchPoint.y
	//	<< " " << searchPoint.z
	//	<< ") with K = " << k << std::endl;

	//record->infoRec(QString::fromStdString(ss.str()));

	//if (kdtree.nearestKSearch(searchPoint, k, pointIdxNKNSearch, pointNKNSquaredDistance) > 0)
	//{
	//	for (size_t i = 0; i < pointIdxNKNSearch.size(); ++i)
	//	{
	//		std::stringstream ss;

	//		ss  << " " << cloud->points[pointIdxNKNSearch[i]].x
	//			<< " " << cloud->points[pointIdxNKNSearch[i]].y
	//			<< " " << cloud->points[pointIdxNKNSearch[i]].z
	//			<< " (squared distance: " << pointNKNSquaredDistance[i] << ")" << std::endl;
	//		record->infoRec(QString::fromStdString(ss.str()));
	//	}
	//}
	record->progressBarUpdate(0);
	for (int i = 0; i < size; i++)
	{
		searchPoint = cloud->points.at(i);
		if (kdtree.nearestKSearch(searchPoint, k, pointIdxNKNSearch, pointNKNSquaredDistance) > 0)
		{
			float distance = 0.0;
			for (int j = 0; j < k; j++)
			{
				distance = distance + pointNKNSquaredDistance.at(j);
			}
			meanDistance.push_back(distance / k);
			indices.push_back(i);
			record->progressBarUpdate(int(100*i/size));
		}
	}
	QFile file("kdtree_data.txt");
	if (!file.open(QIODevice::Truncate | QFile::ReadWrite | QFile::Text))
		emit record->statusUpdate("can't open kdtree_data.txt");
	QTextStream in(&file);	
	for (int i = 0; i < indices.size(); i++)
	{
		in << indices.at(i) << " " << meanDistance.at(i) << endl;
	}
	file.close();
	record->progressBarUpdate(100);
	record->statusUpdate("completed in " + QString::number(pcl_time.toc()) + "ms;");

	return true;
}

bool
Visualization::computeCentroid()
{
	record->infoRec("compute Centroid...");
	pcl_time.tic();
	Eigen::Vector4f xyz_centroid;
	pcl::compute3DCentroid(*cloud, xyz_centroid);
	std::stringstream ss;
	for (size_t i = 0; i < 4; i++)
	{
		ss << " " << xyz_centroid(i);
	}
	ss << std::endl;
	record->infoRec(QString::fromStdString(ss.str()));

	PointT center;
	center.x = xyz_centroid(0);
	center.y = xyz_centroid(1);
	center.z = xyz_centroid(2);

	//viewer->addSphere(center, 1, 1, 0.2, 0.2, "centroid");
	record->statusUpdate("completed in " + QString::number(pcl_time.toc()) + "ms;");

	//transform point cloud
	Eigen::Transform<float, 3, Eigen::Affine> transformation_matrix;
	//Eigen::Matrix4d transformation_matrix = Eigen::Matrix4d::Identity();
	transformation_matrix(0, 0) = 1;
	transformation_matrix(1, 1) = 1;
	transformation_matrix(2, 2) = 1;
	transformation_matrix(0, 3) = - center.x;
	transformation_matrix(1, 3) = - center.y;
	transformation_matrix(2, 3) = - center.z;
	transformation_matrix(3, 3) = 1;
	pcl::transformPointCloud(*cloud, *cloud_out, transformation_matrix);

	pcl::visualization::PointCloudColorHandlerCustom<PointT> rgb(cloud, 20, 90, 90);
	//viewer->addPointCloud(cloud_out, rgb, "transformed cloud");
	*cloud = *cloud_out;
	viewer->updatePointCloud(cloud, rgb, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");

	return true;
}

bool
Visualization::computeNormals()
{<commit_msg>fix bugs in compute centroid and transformation<commit_after>#include "visualization.h"
#include <Eigen/Geometry> 


Visualization::Visualization(QString filename)
	:filename(filename)
{
	record = new Record();
	cloud.reset(new PointCloudT);
	cloud_out.reset(new PointCloudT);
	cloud_normals.reset(new PointCloudN);
	viewer.reset(new pcl::visualization::PCLVisualizer("preview", false));

	//kdtreeFlag = false;
	//centroidFlag = false;

	feature_id = 0;

	search_radius = 0.3;
	normal_level = 100;
	normal_scale = 0.0;
}


Visualization::~Visualization()
{
}

void
Visualization::preview(QString filename)
{
	viewer.reset(new pcl::visualization::PCLVisualizer("preview", true));

	std::string file_name = filename.toStdString();

	pcl_time.tic();
	record->statusUpdate("Loading model...");

	if (filename.endsWith(".pcd"))
	{
		if (!pcl::io::loadPCDFile(file_name, *cloud))
		{
			//QMessageBox msgBox;
			//msgBox.setText("Couldn't read file.");
			//int ret = msgBox.exec();
		}
			

	}		
			
	else if (filename.endsWith(".ply"))
	{
		if (!pcl::io::loadPLYFile(file_name, *cloud))
		{
			//QMessageBox msgBox;
			//msgBox.setText("Couldn't read file.");
			//int ret = msgBox.exec();
		}
	}
	//display number of points
	record->info = QString("data size: "
		+ QString::number(cloud->points.size())
		+ "; duration: "
		+ QString::number(pcl_time.toc())
		+ "ms;");
	record->infoRec(record->info);
	record->statusUpdate(record->info);

	viewer->setBackgroundColor(0, 0, 0);
	pcl::visualization::PointCloudColorHandlerCustom<PointT> rgb(cloud, 20, 180, 20);
	//pcl::visualization::PointCloudColorHandlerRGBField<PointC> rgb(cloud);
	viewer->addPointCloud(cloud, rgb, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
	viewer->addCoordinateSystem(10.0);
	viewer->initCameraParameters();

	

	while (!viewer->wasStopped())
	{
		switch (feature_id)
		{
		case 1:
			computeKdtree();
			break;
		case 2:
			computeCentroid();
			break;
		case 3:
			computeNormals();
			break;
		case 4:
			computeFPFH();
			break;
		case 5:
			filter_n_downsampling();
			break;
		case 6:
			computeEGI();
			break;
		default:
			break;
		}
		feature_id = 0;

		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}
}

void
Visualization::OnStarted()
{
	this->preview(filename);
	emit finished();
}

void
Visualization::feature_id_slot(int feature)
{
	feature_id = feature;
}

bool
Visualization::filter_n_downsampling()
{
	////VoxelGrid Filter Downsampling
	//record->statusUpdate("Downsampling...");
	//pcl::VoxelGrid<PointT> grid;
	//const float leaf = 0.005f;
	//grid.setLeafSize(leaf, leaf, leaf);
	//grid.setInputCloud(cloud);
	//grid.filter(*cloud);

	//StatisticalOutlierRemoval Filter
	record->statusUpdate("Remove Statistical Outlier...");
	pcl::StatisticalOutlierRemoval<PointT> sor;
	sor.setInputCloud(cloud);
	sor.setMeanK(normal_level);
	sor.setStddevMulThresh(search_radius);
	sor.filter(*cloud);
	record->statusUpdate("Done");

	////RadiusOutlierRemoval Filter
	//record->statusUpdate("Remove Radius Outlier...");
	//pcl::RadiusOutlierRemoval<PointT> ror;
	//ror.setInputCloud(cloud);
	//ror.setRadiusSearch(search_radius);
	//ror.setMinNeighborsInRadius(normal_level);
	//ror.filter(*cloud);
	//record->statusUpdate("Done");

	pcl::visualization::PointCloudColorHandlerCustom<PointT> rgb(cloud, 20, 180, 20);
	viewer->updatePointCloud(cloud, rgb, "sample cloud");

	return true;
}

bool
Visualization::computeKdtree()
{
	record->statusUpdate("compute Kdtree...");
	pcl_time.tic();
	//kd-tree tutorials
	srand(time(NULL));
	pcl::KdTreeFLANN<PointT> kdtree;
	kdtree.setInputCloud(cloud);
	int size = cloud->points.size();
	PointT searchPoint;
	std::vector<int> indices;
	std::vector<float> meanDistance;
	//searchPoint = cloud->points.at(cloud->points.size() * rand() / (RAND_MAX + 1));

	//viewer->addSphere(searchPoint, 1, 1, 0.2, 0.2, "search Point");

	int k = normal_level;
	std::vector<int> pointIdxNKNSearch(k);
	std::vector<float> pointNKNSquaredDistance(k);
	//std::stringstream ss;
	//ss  << "k nearest neighbor search at (" << searchPoint.x
	//	<< " " << searchPoint.y
	//	<< " " << searchPoint.z
	//	<< ") with K = " << k << std::endl;

	//record->infoRec(QString::fromStdString(ss.str()));

	//if (kdtree.nearestKSearch(searchPoint, k, pointIdxNKNSearch, pointNKNSquaredDistance) > 0)
	//{
	//	for (size_t i = 0; i < pointIdxNKNSearch.size(); ++i)
	//	{
	//		std::stringstream ss;

	//		ss  << " " << cloud->points[pointIdxNKNSearch[i]].x
	//			<< " " << cloud->points[pointIdxNKNSearch[i]].y
	//			<< " " << cloud->points[pointIdxNKNSearch[i]].z
	//			<< " (squared distance: " << pointNKNSquaredDistance[i] << ")" << std::endl;
	//		record->infoRec(QString::fromStdString(ss.str()));
	//	}
	//}
	record->progressBarUpdate(0);
	for (int i = 0; i < size; i++)
	{
		searchPoint = cloud->points.at(i);
		if (kdtree.nearestKSearch(searchPoint, k, pointIdxNKNSearch, pointNKNSquaredDistance) > 0)
		{
			float distance = 0.0;
			for (int j = 0; j < k; j++)
			{
				distance = distance + pointNKNSquaredDistance.at(j);
			}
			meanDistance.push_back(distance / k);
			indices.push_back(i);
			record->progressBarUpdate(int(100*i/size));
		}
	}
	QFile file("kdtree_data.txt");
	if (!file.open(QIODevice::Truncate | QFile::ReadWrite | QFile::Text))
		emit record->statusUpdate("can't open kdtree_data.txt");
	QTextStream in(&file);	
	for (int i = 0; i < indices.size(); i++)
	{
		in << indices.at(i) << " " << meanDistance.at(i) << endl;
	}
	file.close();
	record->progressBarUpdate(100);
	record->statusUpdate("completed in " + QString::number(pcl_time.toc()) + "ms;");

	return true;
}

bool
Visualization::computeCentroid()
{
	record->statusUpdate("compute Centroid...");
	pcl_time.tic();
	Eigen::Vector4f xyz_centroid;
	pcl::compute3DCentroid(*cloud, xyz_centroid);
	std::stringstream ss;
	for (size_t i = 0; i < 4; i++)
	{
		ss << " " << xyz_centroid(i);
	}
	ss << std::endl;
	record->infoRec(QString::fromStdString(ss.str()));

	PointT center;
	center.x = xyz_centroid(0);
	center.y = xyz_centroid(1);
	center.z = xyz_centroid(2);

	//viewer->addSphere(center, 1, 1, 0.2, 0.2, "centroid");
	record->statusUpdate("completed in " + QString::number(pcl_time.toc()) + "ms;");

	//transform point cloud
	//Eigen::Transform<float, 3, Eigen::Affine> transformation_matrix;
	Eigen::Matrix4f transformation_matrix = Eigen::Matrix4f::Identity();
	transformation_matrix(0, 0) = 1;
	transformation_matrix(1, 1) = 1;
	transformation_matrix(2, 2) = 1;
	transformation_matrix(0, 3) = - center.x;
	transformation_matrix(1, 3) = - center.y;
	transformation_matrix(2, 3) = - center.z;
	transformation_matrix(3, 3) = 1;
	pcl::transformPointCloud(*cloud, *cloud_out, transformation_matrix, true);

	pcl::visualization::PointCloudColorHandlerCustom<PointT> rgb(cloud, 20, 90, 90);
	//viewer->addPointCloud(cloud_out, rgb, "transformed cloud");
	*cloud = *cloud_out;
	viewer->updatePointCloud(cloud, rgb, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");

	return true;
}

bool
Visualization::computeNormals()
{
{'fraction_non_alphanumeric': 0.1784394393696395, 'fraction_numerical': 0.015619552332473328, 'mean_word_length': 4.902057613168724, 'pattern_counts': {'":': 0, '<': 145, '<?xml version=': 0, '>': 123, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3294682', 'n_tokens_mistral': 5818, 'n_tokens_neox': 5263, 'n_words': 889}