#include "quad_patch_tesselator.h"


MyMesh tesselate_quad_patch(QuadPatch q, MyMesh mesh, VertexHandle vh) {
	const size_t patch_divs = 8;
	MyMesh patch;
	Eigen::Vector3d point
		(mesh.point(vh)[0], mesh.point(vh)[1], mesh.point(vh)[2]);
	point = q.transform() * point;
	double xmin = point[0], xmax = point[0];
	double ymin = point[1], ymax = point[1];
	for (VertexHandle vi : mesh.vv_range(vh)) {
		Eigen::Vector3d point
			(mesh.point(vi)[0], mesh.point(vi)[1], mesh.point(vi)[2]);
		point = q.transform() * point;
		xmin = std::min(xmin, point[0]);
		xmax = std::max(xmax, point[0]);
		ymin = std::min(ymin, point[1]);
		ymax = std::max(ymax, point[1]);
	}
	double xstep = (xmax-xmin)/static_cast<double>(patch_divs);
	double ystep = (ymax-ymin)/static_cast<double>(patch_divs);
	for (size_t y = 0; y < patch_divs; y++) {
		for (size_t x = 0; x < patch_divs; x++) {
			double dx = xmin + x * xstep;
			double dy = ymin + y * ystep;
			Eigen::Vector3d point(dx, dy, -q(dx, dy));
			point = q.inverse_transform() * point;
			patch.new_vertex(Point(point[0], point[1], point[2]));
		}
	}
	for (VertexHandle vhi : patch.vertices()) {
		patch.set_color(vhi, MyMesh::Color(0, 1, .2));
		size_t i = vhi.idx();
		size_t x = i % patch_divs;
		size_t y = i / patch_divs;
		if (x == patch_divs - 1 || y == patch_divs - 1) continue;
		patch.add_face(vhi, patch.vertex_handle(i + patch_divs),
					   patch.vertex_handle(i + 1));
		patch.add_face(patch.vertex_handle(i + 1),
					   patch.vertex_handle(i + patch_divs),
					   patch.vertex_handle(i + patch_divs + 1));
	}
	return patch;
}
