#include "util.h"

#include <stack>
#include <OpenMesh/Core/Utils/PropertyManager.hh>


QDebug operator<<(QDebug dbg, const Point &p) {
	return dbg << p[0] << p[1] << p[2];
}


qreal cotan(const qreal x) {
	return 1. / qTan(x);
}


static void traverse_connected(MyMesh &mesh, std::vector<VertexHandle> &out,
							   VertexHandle start) {
	auto prop =
		OpenMesh::makeTemporaryProperty<MyMesh::VertexHandle, bool>(mesh);
	for (VertexHandle vh : mesh.vertices()) {
		prop[vh] = false;
	}
	std::stack<VertexHandle> stack;
	stack.push(start);
	prop[start] = true;
	while (!stack.empty()) {
		VertexHandle v = stack.top();
		stack.pop();
		out.emplace_back(v);
		for (VertexHandle v2 : mesh.vv_range(v)) {
			if (!prop[v2]) {
				stack.push(v2);
				prop[v2] = true;
			}
		}
	}
}


std::vector<std::vector<VertexHandle>> find_connected_components(
	MyMesh &mesh) {
	auto prop =
		OpenMesh::makeTemporaryProperty<MyMesh::VertexHandle, bool>(mesh);
	for (VertexHandle vh : mesh.vertices()) {
		prop[vh] = false;
	}
	std::vector<std::vector<VertexHandle>> connected_components;
	for (VertexHandle vh : mesh.vertices()) {
		if (prop[vh]) continue;
		connected_components.push_back({});
		traverse_connected(mesh, connected_components.back(), vh);
	}
	return connected_components;
}
