Clean up
This commit is contained in:
parent
a812f74ca3
commit
7a3b220f0a
@ -196,94 +196,14 @@ std::optional<std::wstring> Emboss::get_font_path(const std::wstring &font_face_
|
|||||||
return wsFontFile;
|
return wsFontFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <commdlg.h>
|
|
||||||
void choose_font_dlg() {
|
|
||||||
HWND hwnd = (HWND)GetFocus(); // owner window
|
|
||||||
HDC hdc = GetDC(NULL); // display device context of owner window
|
|
||||||
|
|
||||||
CHOOSEFONT cf; // common dialog box structure
|
|
||||||
static LOGFONT lf; // logical font structure
|
|
||||||
static DWORD rgbCurrent; // current text color
|
|
||||||
HFONT hfont, hfontPrev;
|
|
||||||
DWORD rgbPrev;
|
|
||||||
|
|
||||||
// Initialize CHOOSEFONT
|
|
||||||
ZeroMemory(&cf, sizeof(cf));
|
|
||||||
cf.lStructSize = sizeof(cf);
|
|
||||||
cf.hwndOwner = hwnd;
|
|
||||||
cf.lpLogFont = &lf;
|
|
||||||
cf.rgbColors = rgbCurrent;
|
|
||||||
cf.Flags = CF_SCREENFONTS | CF_EFFECTS;
|
|
||||||
|
|
||||||
if (ChooseFont(&cf) == TRUE) {
|
|
||||||
std::wcout << "selected font is "
|
|
||||||
<< (std::wstring) cf.lpLogFont->lfFaceName
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
//hfont = CreateFontIndirect(cf.lpLogFont);
|
|
||||||
//hfontPrev = SelectObject(hdc, hfont);
|
|
||||||
//rgbCurrent = cf.rgbColors;
|
|
||||||
//rgbPrev = SetTextColor(hdc, rgbCurrent);
|
|
||||||
//...
|
|
||||||
} else {
|
|
||||||
std::cout << "Font was not selected";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_OS_font()
|
|
||||||
{
|
|
||||||
LOGFONT lf;
|
|
||||||
HGDIOBJ g_hfFont = GetStockObject(DEFAULT_GUI_FONT);
|
|
||||||
GetObject(g_hfFont, sizeof(LOGFONT), &lf);
|
|
||||||
std::wcout << "DEFAULT_GUI_FONT is " << (std::wstring) lf.lfFaceName << std::endl;
|
|
||||||
|
|
||||||
g_hfFont = GetStockObject(OEM_FIXED_FONT);
|
|
||||||
GetObject(g_hfFont, sizeof(LOGFONT), &lf);
|
|
||||||
std::wcout << "OEM_FIXED_FONT is " << (std::wstring) lf.lfFaceName << std::endl;
|
|
||||||
|
|
||||||
g_hfFont = GetStockObject(ANSI_FIXED_FONT);
|
|
||||||
GetObject(g_hfFont, sizeof(LOGFONT), &lf);
|
|
||||||
std::wcout << "ANSI_FIXED_FONT is " << (std::wstring) lf.lfFaceName << std::endl;
|
|
||||||
|
|
||||||
g_hfFont = GetStockObject(ANSI_VAR_FONT);
|
|
||||||
GetObject(g_hfFont, sizeof(LOGFONT), &lf);
|
|
||||||
std::wcout << "ANSI_VAR_FONT is " << (std::wstring) lf.lfFaceName << std::endl;
|
|
||||||
|
|
||||||
g_hfFont = GetStockObject(SYSTEM_FONT);
|
|
||||||
GetObject(g_hfFont, sizeof(LOGFONT), &lf);
|
|
||||||
std::wcout << "SYSTEM_FONT is " << (std::wstring) lf.lfFaceName << std::endl;
|
|
||||||
|
|
||||||
g_hfFont = GetStockObject(DEVICE_DEFAULT_FONT);
|
|
||||||
GetObject(g_hfFont, sizeof(LOGFONT), &lf);
|
|
||||||
std::wcout << "DEVICE_DEFAULT_FONT is " << (std::wstring) lf.lfFaceName << std::endl;
|
|
||||||
|
|
||||||
g_hfFont = GetStockObject(SYSTEM_FIXED_FONT);
|
|
||||||
GetObject(g_hfFont, sizeof(LOGFONT), &lf);
|
|
||||||
std::wcout << "SYSTEM_FIXED_FONT is " << (std::wstring) lf.lfFaceName << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FontList Emboss::get_font_list()
|
FontList Emboss::get_font_list()
|
||||||
{
|
{
|
||||||
//auto a = get_font_path(L"none");
|
|
||||||
//get_OS_font();
|
|
||||||
//choose_font_dlg();
|
|
||||||
//FontList list1 = get_font_list_by_enumeration();
|
//FontList list1 = get_font_list_by_enumeration();
|
||||||
//FontList list2 = get_font_list_by_register();
|
//FontList list2 = get_font_list_by_register();
|
||||||
//FontList list3 = get_font_list_by_folder();
|
//FontList list3 = get_font_list_by_folder();
|
||||||
return get_font_list_by_register();
|
return get_font_list_by_register();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exists_file(const std::wstring &name)
|
|
||||||
{
|
|
||||||
if (FILE *file = _wfopen(name.c_str(), L"r")) {
|
|
||||||
fclose(file);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FontList Emboss::get_font_list_by_register() {
|
FontList Emboss::get_font_list_by_register() {
|
||||||
static const LPWSTR fontRegistryPath = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
|
static const LPWSTR fontRegistryPath = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
|
@ -414,7 +414,7 @@ void GLGizmoEmboss::draw_font_list()
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::BeginCombo("##font_collection_selector",
|
if (ImGui::BeginCombo("##font_collection_selector",
|
||||||
std::to_string(m_font->index).c_str())) {
|
std::to_string(m_font->index).c_str())) {
|
||||||
for (size_t i = 0; i < m_font->count; ++i) {
|
for (unsigned int i = 0; i < m_font->count; ++i) {
|
||||||
ImGui::PushID(1 << 10 + i);
|
ImGui::PushID(1 << 10 + i);
|
||||||
if (ImGui::Selectable(std::to_string(i).c_str(),
|
if (ImGui::Selectable(std::to_string(i).c_str(),
|
||||||
i == m_font->index)) {
|
i == m_font->index)) {
|
||||||
|
@ -54,7 +54,7 @@ TEST_CASE("Add TriangleMeshes", "[MeshBoolean]")
|
|||||||
ExPolygons ttf2polygons(const char * font_name, char letter, float flatness = 1.f) {
|
ExPolygons ttf2polygons(const char * font_name, char letter, float flatness = 1.f) {
|
||||||
auto font = Emboss::load_font(font_name);
|
auto font = Emboss::load_font(font_name);
|
||||||
if (!font.has_value()) return ExPolygons();
|
if (!font.has_value()) return ExPolygons();
|
||||||
return Emboss::letter2glyph(*font, letter, flatness)->polygons;
|
return Emboss::letter2glyph(*font, letter, flatness)->shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "libslic3r/SVG.hpp"
|
#include "libslic3r/SVG.hpp"
|
||||||
@ -97,23 +97,6 @@ struct EmbossConfig
|
|||||||
float height = 1.; // [in milimeters]
|
float height = 1.; // [in milimeters]
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FontConfig
|
|
||||||
{
|
|
||||||
const char *font_path = "C:/windows/fonts/arialbd.ttf";
|
|
||||||
float flatness = 2.; // precision of lettter outline curve in conversion to lines
|
|
||||||
float scale = 1.0; // size of text
|
|
||||||
float letter_space = 1.; // unscaled space between letters
|
|
||||||
float line_space = 1.; // unscaled space between lines
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Seam
|
|
||||||
{
|
|
||||||
std::vector<size_t> seam_points; // indexes of vertices which made seam
|
|
||||||
std::vector<size_t> inner_faces; // indexes of triangle (its.indices) which are inside of polygon
|
|
||||||
std::vector<size_t> outline_faces; // indexes of triangle (its.indices) contains seam points
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <libslic3r/AABBTreeIndirect.hpp>
|
#include <libslic3r/AABBTreeIndirect.hpp>
|
||||||
Vec3d calc_hit_point(const igl::Hit & h,
|
Vec3d calc_hit_point(const igl::Hit & h,
|
||||||
@ -170,8 +153,6 @@ struct TrianglePath
|
|||||||
};
|
};
|
||||||
using TrianglePaths = std::vector<TrianglePath>;
|
using TrianglePaths = std::vector<TrianglePath>;
|
||||||
|
|
||||||
std::vector<Vec3i> triangulate(const Vec3i &triangle, const Vec3d &triangle_normal, const std::vector<Vec3f> &vertices, const TrianglePaths& paths);
|
|
||||||
|
|
||||||
// create transformation matrix to convert direction vectors
|
// create transformation matrix to convert direction vectors
|
||||||
// do not care about up vector
|
// do not care about up vector
|
||||||
// Directions are normalized
|
// Directions are normalized
|
||||||
@ -304,114 +285,11 @@ TEST_CASE("triangle intersection", "[]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include <libslic3r/Geometry.hpp>
|
#include <libslic3r/Geometry.hpp>
|
||||||
|
#include <libslic3r/Triangulation.hpp>
|
||||||
std::optional<Seam> create_seam(const Polygon &shape, const OrientedPlane& plane, indexed_triangle_set &its) {
|
|
||||||
// IMPROVE: create area of interests (mask for neighbors)
|
|
||||||
auto neighbors = its_face_edge_ids(its);
|
|
||||||
auto tree = AABBTreeIndirect::build_aabb_tree_over_indexed_triangle_set(
|
|
||||||
its.vertices, its.indices);
|
|
||||||
const Vec3d z_axis(0, 0, 1);
|
|
||||||
// IMPROVE: parallelize
|
|
||||||
// collect intersection with model
|
|
||||||
const Vec3d& ray_dir = plane.normal;
|
|
||||||
Vec3d side = plane.up.cross(plane.normal);
|
|
||||||
std::vector<igl::Hit> hits;
|
|
||||||
hits.reserve(shape.points.size());
|
|
||||||
for (const Point &p : shape.points) {
|
|
||||||
Vec3d ray_point = plane.point +plane.up*p.y()+side*p.x();
|
|
||||||
igl::Hit hit;
|
|
||||||
AABBTreeIndirect::intersect_ray_first_hit(its.vertices, its.indices,
|
|
||||||
tree, ray_point, ray_dir,
|
|
||||||
hit);
|
|
||||||
hits.push_back(hit);
|
|
||||||
}
|
|
||||||
|
|
||||||
// triangle idx, changes inside triangle
|
|
||||||
std::map<size_t, TrianglePaths> changes;
|
|
||||||
|
|
||||||
std::set<size_t> remove_indices;
|
|
||||||
std::vector<Vec3f> add_vertices;
|
|
||||||
std::vector<Vec3i> add_indices;
|
|
||||||
for (size_t i = 0; i < shape.points.size(); ++i) {
|
|
||||||
size_t next_i = i + 1;
|
|
||||||
if (i == shape.points.size()) next_i = 0;
|
|
||||||
|
|
||||||
Point dir2d = shape.points[next_i] - shape.points[i];
|
|
||||||
Vec3d dir = dir2d.x() * side + dir2d.y() * plane.up;
|
|
||||||
const igl::Hit &start_hit = hits[i];
|
|
||||||
|
|
||||||
size_t ti = start_hit.id; // triangle index
|
|
||||||
const igl::Hit &end_hit = hits[next_i];
|
|
||||||
|
|
||||||
Vec3i t = its.indices[ti];
|
|
||||||
Vec3d hit_point = calc_hit_point(start_hit, t, its.vertices);
|
|
||||||
|
|
||||||
Vec3d start_point = hit_point;
|
|
||||||
std::optional<size_t> edge_index;
|
|
||||||
|
|
||||||
while (ti != end_hit.id) {
|
|
||||||
Vec3d n = calc_normal(t, its.vertices); // triangle normal
|
|
||||||
Eigen::Matrix3d rotation = create_transformation(n, z_axis);
|
|
||||||
Vec3d t_dir = n.cross(dir).cross(n); // direction on triangle surface
|
|
||||||
|
|
||||||
auto remove_z = [&](const Vec3d &point) -> Vec2d {
|
|
||||||
Vec3d rotated_point = rotation * point;
|
|
||||||
assert(abs(rotated_point.z()) < 1e-5);
|
|
||||||
return Vec2d(rotated_point.x(), rotated_point.y());
|
|
||||||
};
|
|
||||||
|
|
||||||
std::array<Vec2d, 3> triangle2d;
|
|
||||||
for (size_t i = 0; i < 3; ++i)
|
|
||||||
triangle2d[i] = remove_z(its.vertices[t[i]].cast<double>());
|
|
||||||
|
|
||||||
Vec2d start_point_2d = remove_z(start_point);
|
|
||||||
|
|
||||||
// move start point on edge of this triangle
|
|
||||||
if (edge_index.has_value()) {
|
|
||||||
size_t e2 = *edge_index +1;
|
|
||||||
if (e2 == 3) e2 = 0;
|
|
||||||
const Vec2d &p1 = triangle2d[*edge_index];
|
|
||||||
const Vec2d &p2 = triangle2d[e2];
|
|
||||||
Vec2d dir = p2 - p1;
|
|
||||||
start_point_2d = Geometry::foot_pt(p1, dir, start_point_2d);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2d dir_point_2d = remove_z(start_point+t_dir);
|
|
||||||
|
|
||||||
Vec2d next_point_2d = get_intersection(start_point_2d, dir_point_2d, triangle2d);
|
|
||||||
|
|
||||||
//next_triangle =
|
|
||||||
// Find interection with triangle border from start point in direction t_dir
|
|
||||||
// ?? Convert to 2d?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect hits over surface
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Vec3i> triangulate(const std::vector<Vec2f> & points,
|
|
||||||
const std::vector<std::pair<int, int>> &edges);
|
|
||||||
|
|
||||||
std::vector<Vec3i> triangulate(const Polygon &polygon) {
|
|
||||||
const Points &pts = polygon.points;
|
|
||||||
|
|
||||||
std::vector<Vec2f> points;
|
|
||||||
points.reserve(pts.size());
|
|
||||||
std::transform(pts.begin(), pts.end(), std::back_inserter(points),
|
|
||||||
[](const Point &p) -> Vec2f { return p.cast<float>(); });
|
|
||||||
|
|
||||||
std::vector<std::pair<int, int>> edges;
|
|
||||||
edges.reserve(pts.size());
|
|
||||||
for (int i = 1; i < pts.size(); ++i) edges.emplace_back(i - 1, i);
|
|
||||||
edges.emplace_back(pts.size() - 1, 0);
|
|
||||||
return triangulate(points, edges);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
indexed_triangle_set emboss3d(const Polygon &shape, float height) {
|
indexed_triangle_set emboss3d(const Polygon &shape, float height) {
|
||||||
// CW order of triangle indices
|
// CW order of triangle indices
|
||||||
std::vector<Vec3i> shape_triangles = triangulate(shape);
|
std::vector<Vec3i> shape_triangles = Triangulation::triangulate(shape);
|
||||||
|
|
||||||
indexed_triangle_set result;
|
indexed_triangle_set result;
|
||||||
const Points &pts = shape.points;
|
const Points &pts = shape.points;
|
||||||
@ -526,8 +404,6 @@ void emboss3d_(const Polygon& shape, const EmbossConfig &cfg, indexed_triangle_s
|
|||||||
, PMP::parameters::edge_is_constrained_map(ecm1)
|
, PMP::parameters::edge_is_constrained_map(ecm1)
|
||||||
//, PMP::parameters::do_not_modify(true)
|
//, PMP::parameters::do_not_modify(true)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//PMP::Corefinement::Intersection_of_triangle_meshes()
|
//PMP::Corefinement::Intersection_of_triangle_meshes()
|
||||||
|
|
||||||
size_t count_true = 0;
|
size_t count_true = 0;
|
||||||
@ -614,7 +490,7 @@ void emboss3d(const Polygon& shape, const EmbossConfig &cfg, indexed_triangle_se
|
|||||||
its = tm1.its; // copy
|
its = tm1.its; // copy
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Emboss polygon", "[MeshBoolean]")
|
TEST_CASE("Emboss polygon example", "[MeshBoolean]")
|
||||||
{
|
{
|
||||||
const char *font_name = "C:/windows/fonts/arialbd.ttf";
|
const char *font_name = "C:/windows/fonts/arialbd.ttf";
|
||||||
char letter = '%';
|
char letter = '%';
|
||||||
@ -638,156 +514,27 @@ TEST_CASE("Emboss polygon", "[MeshBoolean]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Triangulate by cgal", "[Triangulation]")
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
|
||||||
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
|
||||||
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
|
|
||||||
// triangulate with constrains on edges
|
|
||||||
std::vector<Vec3i> triangulate(const std::vector<Vec2f>& points,
|
|
||||||
const std::vector<std::pair<int, int>>& edges)
|
|
||||||
{
|
{
|
||||||
// use cgal triangulation
|
Points points = {Point(1, 1), Point(2, 1), Point(2, 2), Point(1, 2)};
|
||||||
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
|
Triangulation::HalfEdges edges1 = {{1, 3}};
|
||||||
using Itag = CGAL::Exact_predicates_tag;
|
std::vector<Vec3i> indices1 = Triangulation::triangulate(points, edges1);
|
||||||
using CDT = CGAL::Constrained_Delaunay_triangulation_2<K, CGAL::Default, Itag>;
|
|
||||||
using Point = CDT::Point;
|
|
||||||
|
|
||||||
// construct a constrained triangulation
|
|
||||||
CDT cdt;
|
|
||||||
std::map<CDT::Vertex_handle, int> map; // for indices
|
|
||||||
std::vector<CDT::Vertex_handle> vertices_handle; // for constriants
|
|
||||||
vertices_handle.reserve(points.size());
|
|
||||||
for (size_t i = 0; i < points.size(); ++i) {
|
|
||||||
const Vec2f &p = points[i];
|
|
||||||
Point cdt_p(p.x(), p.y());
|
|
||||||
auto handl = cdt.insert(cdt_p);
|
|
||||||
vertices_handle.push_back(handl);
|
|
||||||
map[handl] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const std::pair<int, int> &edge : edges) {
|
|
||||||
cdt.insert_constraint(vertices_handle[edge.first],
|
|
||||||
vertices_handle[edge.second]);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto faces = cdt.finite_face_handles();
|
|
||||||
std::vector<Vec3i> indices;
|
|
||||||
indices.reserve(faces.size());
|
|
||||||
for (CDT::Face_handle face : faces){
|
|
||||||
auto v0 = face->vertex(0);
|
|
||||||
auto v1 = face->vertex(1);
|
|
||||||
auto v2 = face->vertex(2);
|
|
||||||
indices.emplace_back(map[v0], map[v1], map[v2]);
|
|
||||||
|
|
||||||
/*
|
|
||||||
auto p0 = v0->point();
|
|
||||||
auto p1 = v1->point();
|
|
||||||
auto p2 = v2->point();
|
|
||||||
std::cout << "Triangle: " <<
|
|
||||||
map[v0] << " [" << p0.x() << ", " << p0.y() << "], " <<
|
|
||||||
map[v1] << " [" << p1.x() << ", " << p1.y() << "], " <<
|
|
||||||
map[v2] << " [" << p2.x() << ", " << p2.y() << "] " << std::endl;*/
|
|
||||||
}
|
|
||||||
return indices;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Vec3i> triangulate(const Vec3i & triangle,
|
|
||||||
const Vec3d & triangle_normal,
|
|
||||||
const std::vector<Vec3f> &vertices,
|
|
||||||
const TrianglePaths& paths)
|
|
||||||
{
|
|
||||||
size_t count_point = 3;
|
|
||||||
size_t count_circles = 0;
|
|
||||||
for (const auto &path : paths){
|
|
||||||
count_point += path.points.size();
|
|
||||||
if (!path.edges.has_value())
|
|
||||||
++count_circles;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Vec3f> points3d;
|
|
||||||
points3d.reserve(count_point);
|
|
||||||
std::vector<size_t> index_map;
|
|
||||||
index_map.reserve(count_point);
|
|
||||||
|
|
||||||
// add source triangle points
|
|
||||||
for (int vi : triangle) {
|
|
||||||
points3d.push_back(vertices[vi]);
|
|
||||||
index_map.push_back(vi);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add path points with edges
|
|
||||||
std::vector<std::pair<int, int>> edges;
|
|
||||||
edges.reserve(count_point - 3 - paths.size() + count_circles);
|
|
||||||
for (const auto &path : paths) {
|
|
||||||
size_t index = path.offset_id;
|
|
||||||
bool is_first = true;
|
|
||||||
for (const Vec3f &point : path.points) {
|
|
||||||
int index = points3d.size();
|
|
||||||
if (is_first) {
|
|
||||||
is_first = false;
|
|
||||||
// all path on triangle
|
|
||||||
if (!path.edges.has_value())
|
|
||||||
edges.push_back({index, index + path.points.size()});
|
|
||||||
} else {
|
|
||||||
edges.push_back({index-1, index});
|
|
||||||
}
|
|
||||||
points3d.push_back(point);
|
|
||||||
index_map.push_back(index);
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO:check tr_mat
|
|
||||||
|
|
||||||
// create transform matrix to remove z coordinate by normal
|
|
||||||
const Vec3d z_axis(0, 0, 1);
|
|
||||||
auto rotation = create_transformation(triangle_normal, z_axis);
|
|
||||||
|
|
||||||
// convert points to 2d
|
|
||||||
std::vector<Vec2f> points_2d;
|
|
||||||
points_2d.reserve(count_point);
|
|
||||||
for (const Vec3f &p : points3d) {
|
|
||||||
Vec3d p_tr = rotation * p.cast<double>();
|
|
||||||
points_2d.emplace_back(p_tr.x(), p_tr.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
// connecto to triangles
|
|
||||||
std::vector<Vec3i> indices = triangulate(points_2d, edges);
|
|
||||||
|
|
||||||
// TODO: Check thin border triangle caused by float preccision
|
|
||||||
|
|
||||||
// remap indexes
|
|
||||||
for (Vec3i &triangle : indices)
|
|
||||||
for (int &i : triangle) i = index_map[i];
|
|
||||||
return indices;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Triangulate by cgal", "[]")
|
|
||||||
{
|
|
||||||
std::vector<Vec2f> points = {
|
|
||||||
Vec2f(1, 1),
|
|
||||||
Vec2f(2, 1),
|
|
||||||
Vec2f(2, 2),
|
|
||||||
Vec2f(1, 2)
|
|
||||||
};
|
|
||||||
std::vector<std::pair<int, int>> edges1 = {{1, 3}};
|
|
||||||
std::vector<Vec3i> indices1 = triangulate(points, edges1);
|
|
||||||
|
|
||||||
auto check = [](int i1, int i2, Vec3i t)->bool { return true;
|
auto check = [](int i1, int i2, Vec3i t)->bool { return true;
|
||||||
return (t[0] == i1 || t[1] == i1 || t[2] == i1) &&
|
return (t[0] == i1 || t[1] == i1 || t[2] == i1) &&
|
||||||
(t[0] == i2 || t[1] == i2 || t[2] == i2);
|
(t[0] == i2 || t[1] == i2 || t[2] == i2);
|
||||||
};
|
};
|
||||||
REQUIRE(indices1.size() == 2);
|
REQUIRE(indices1.size() == 2);
|
||||||
int i1 = edges1.front().first,
|
int i1 = edges1.begin()->first,
|
||||||
i2 = edges1.front().second;
|
i2 = edges1.begin()->second;
|
||||||
CHECK(check(i1, i2, indices1[0]));
|
CHECK(check(i1, i2, indices1[0]));
|
||||||
CHECK(check(i1, i2, indices1[1]));
|
CHECK(check(i1, i2, indices1[1]));
|
||||||
|
|
||||||
std::vector<std::pair<int, int>> edges2 = {{0, 2}};
|
Triangulation::HalfEdges edges2 = {{0, 2}};
|
||||||
std::vector<Vec3i> indices2 = triangulate(points, edges2);
|
std::vector<Vec3i> indices2 = Triangulation::triangulate(points, edges2);
|
||||||
REQUIRE(indices2.size() == 2);
|
REQUIRE(indices2.size() == 2);
|
||||||
i1 = edges2.front().first;
|
i1 = edges2.begin()->first;
|
||||||
i2 = edges2.front().second;
|
i2 = edges2.begin()->second;
|
||||||
CHECK(check(i1, i2, indices2[0]));
|
CHECK(check(i1, i2, indices2[0]));
|
||||||
CHECK(check(i1, i2, indices2[1]));
|
CHECK(check(i1, i2, indices2[1]));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user