Cleaned up; added default input file

This commit is contained in:
Efi Fogel 2024-01-08 16:24:07 +02:00
parent fff5fa5380
commit 36d23e88b7
54 changed files with 934 additions and 2073 deletions

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -47,7 +47,6 @@ using json = nlohmann::ordered_json;
#include <CGAL/Arr_naive_point_location.h> #include <CGAL/Arr_naive_point_location.h>
#include <CGAL/Arr_point_location_result.h> #include <CGAL/Arr_point_location_result.h>
namespace { namespace {
// //#define USE_EPIC // //#define USE_EPIC
// //
@ -71,8 +70,7 @@ namespace {
static Geom_traits s_traits; static Geom_traits s_traits;
// Extended DCEL & Arrangement // Extended DCEL & Arrangement
struct Flag struct Flag {
{
bool v; bool v;
Flag() : v{ false } {} Flag() : v{ false } {}
Flag(bool init) : v{ init } {} Flag(bool init) : v{ init } {}
@ -91,18 +89,15 @@ namespace {
//using Countries_arr = //using Countries_arr =
// CGAL::Arrangement_on_surface_2<Geom_traits, Countries_topol_traits>; // CGAL::Arrangement_on_surface_2<Geom_traits, Countries_topol_traits>;
using Dir3 = Kernel::Direction_3; using Dir3 = Kernel::Direction_3;
std::ostream& operator << (std::ostream& os, const Dir3& d) std::ostream& operator << (std::ostream& os, const Dir3& d) {
{
os << d.dx() << ", " << d.dy() << ", " << d.dz(); os << d.dx() << ", " << d.dy() << ", " << d.dz();
return os; return os;
} }
using Approximate_point_2 = Geom_traits::Approximate_point_2; using Approximate_point_2 = Geom_traits::Approximate_point_2;
std::ostream& operator << (std::ostream& os, const Approximate_point_2& d)
{ std::ostream& operator << (std::ostream& os, const Approximate_point_2& d) {
os << d.dx() << ", " << d.dy() << ", " << d.dz(); os << d.dx() << ", " << d.dy() << ", " << d.dz();
return os; return os;
} }
@ -114,14 +109,12 @@ namespace {
using Direction_3 = Kernel::Direction_3; using Direction_3 = Kernel::Direction_3;
std::ostream& operator << (std::ostream& os, const Approximate_Vector_3& v) std::ostream& operator << (std::ostream& os, const Approximate_Vector_3& v) {
{
os << v.x() << ", " << v.y() << ", " << v.z(); os << v.x() << ", " << v.y() << ", " << v.z();
//os << v.hx() << ", " << v.hy() << ", " << v.hz() << ", " << v.hw(); //os << v.hx() << ", " << v.hy() << ", " << v.hz() << ", " << v.hw();
return os; return os;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// below are the helper functions used to construct the arcs from KML data // below are the helper functions used to construct the arcs from KML data
// TODO: Revisit handling of INNER & OUTER boundaries // TODO: Revisit handling of INNER & OUTER boundaries
@ -129,15 +122,13 @@ namespace {
// get curves for the given kml placemark // get curves for the given kml placemark
// NOTE: this is defined here to keep the definitions local to this cpp file // NOTE: this is defined here to keep the definitions local to this cpp file
Curves get_arcs(const Kml::Placemark& placemark) Curves get_arcs(const Kml::Placemark& placemark) {
{
//Geom_traits traits; //Geom_traits traits;
auto ctr_p = s_traits.construct_point_2_object(); auto ctr_p = s_traits.construct_point_2_object();
auto ctr_cv = s_traits.construct_curve_2_object(); auto ctr_cv = s_traits.construct_curve_2_object();
std::vector<Curve> xcvs; std::vector<Curve> xcvs;
for (const auto& polygon : placemark.polygons) for (const auto& polygon : placemark.polygons) {
{
// colect all rings into a single list (FOR NOW!!!) // colect all rings into a single list (FOR NOW!!!)
// TO-DO: PROCESS OUTER & INNER BOUNDARIES SEPARATELY!!! // TO-DO: PROCESS OUTER & INNER BOUNDARIES SEPARATELY!!!
Kml::LinearRings linear_rings; Kml::LinearRings linear_rings;
@ -147,11 +138,9 @@ namespace {
// convert the nodes to points on unit-sphere // convert the nodes to points on unit-sphere
for (const auto& lring : linear_rings) for (const auto& lring : linear_rings) {
{
std::vector<Approximate_Vector_3> sphere_points; std::vector<Approximate_Vector_3> sphere_points;
for (const auto& node : lring.nodes) for (const auto& node : lring.nodes) {
{
const auto p = node.get_coords_3d(); const auto p = node.get_coords_3d();
Approximate_Vector_3 v(p.x, p.y, p.z); Approximate_Vector_3 v(p.x, p.y, p.z);
sphere_points.push_back(v); sphere_points.push_back(v);
@ -159,8 +148,7 @@ namespace {
// add geodesic arcs for the current LinearRing // add geodesic arcs for the current LinearRing
int num_points = sphere_points.size(); int num_points = sphere_points.size();
for (int i = 0; i < num_points - 1; i++) for (int i = 0; i < num_points - 1; i++) {
{
const auto p1 = sphere_points[i]; const auto p1 = sphere_points[i];
const auto p2 = sphere_points[i + 1]; const auto p2 = sphere_points[i + 1];
xcvs.push_back(ctr_cv(ctr_p(p1.x(), p1.y(), p1.z()), xcvs.push_back(ctr_cv(ctr_p(p1.x(), p1.y(), p1.z()),
@ -190,10 +178,8 @@ namespace {
num_counted_arcs = 0; num_counted_arcs = 0;
num_counted_polygons = 0; num_counted_polygons = 0;
std::vector<Curve> xcvs; std::vector<Curve> xcvs;
for (const auto& pm : placemarks) for (const auto& pm : placemarks) {
{ for (const auto& polygon : pm.polygons) {
for (const auto& polygon : pm.polygons)
{
num_counted_polygons++; num_counted_polygons++;
// colect all rings into a single list (FOR NOW!!!) // colect all rings into a single list (FOR NOW!!!)
@ -204,12 +190,10 @@ namespace {
linear_rings.push_back(inner_boundary); linear_rings.push_back(inner_boundary);
// loop on outer and inner boundaries // loop on outer and inner boundaries
for (const auto& lring : linear_rings) for (const auto& lring : linear_rings) {
{
// convert the nodes to points on unit-sphere // convert the nodes to points on unit-sphere
std::vector<Approximate_Vector_3> sphere_points; std::vector<Approximate_Vector_3> sphere_points;
for (const auto& node : lring.nodes) for (const auto& node : lring.nodes) {
{
num_counted_nodes++; num_counted_nodes++;
const auto p = node.get_coords_3d(); const auto p = node.get_coords_3d();
Approximate_Vector_3 v(p.x, p.y, p.z); Approximate_Vector_3 v(p.x, p.y, p.z);
@ -239,8 +223,7 @@ namespace {
} }
Aos::Approx_arc get_approx_curve(Curve xcv, double error) Aos::Approx_arc get_approx_curve(Curve xcv, double error) {
{
//Geom_traits traits; //Geom_traits traits;
auto approx = s_traits.approximate_2_object(); auto approx = s_traits.approximate_2_object();
std::vector<QVector3D> approx_curve; std::vector<QVector3D> approx_curve;
@ -257,11 +240,9 @@ namespace {
return approx_curve; return approx_curve;
} }
Aos::Approx_arcs get_approx_curves(std::vector<Curve>& xcvs, double error) Aos::Approx_arcs get_approx_curves(std::vector<Curve>& xcvs, double error) {
{
Aos::Approx_arcs approx_curves; Aos::Approx_arcs approx_curves;
for (const auto& xcv : xcvs) for (const auto& xcv : xcvs) {
{
auto approx_curve = get_approx_curve(xcv, error); auto approx_curve = get_approx_curve(xcv, error);
approx_curves.push_back(std::move(approx_curve)); approx_curves.push_back(std::move(approx_curve));
} }
@ -271,8 +252,7 @@ namespace {
} }
Aos::Approx_arc Aos::get_approx_identification_curve(double error) Aos::Approx_arc Aos::get_approx_identification_curve(double error) {
{
//Geom_traits traits; //Geom_traits traits;
auto ctr_p = s_traits.construct_point_2_object(); auto ctr_p = s_traits.construct_point_2_object();
auto ctr_cv = s_traits.construct_curve_2_object(); auto ctr_cv = s_traits.construct_curve_2_object();
@ -285,8 +265,7 @@ Aos::Approx_arc Aos::get_approx_identification_curve(double error)
{ {
std::vector<Approximate_point_2> v; std::vector<Approximate_point_2> v;
auto oi2 = approx(xcv, error, std::back_insert_iterator(v)); auto oi2 = approx(xcv, error, std::back_insert_iterator(v));
for (const auto& p : v) for (const auto& p : v) {
{
const QVector3D arc_point(p.dx(), p.dy(), p.dz()); const QVector3D arc_point(p.dx(), p.dy(), p.dz());
approx_arc.push_back(arc_point); approx_arc.push_back(arc_point);
} }
@ -295,8 +274,8 @@ Aos::Approx_arc Aos::get_approx_identification_curve(double error)
return approx_arc; return approx_arc;
} }
Aos::Approx_arcs Aos::get_approx_arcs(double error) //! \brief
{ Aos::Approx_arcs Aos::get_approx_arcs(double error) {
auto ctr_p = s_traits.construct_point_2_object(); auto ctr_p = s_traits.construct_point_2_object();
auto ctr_cv = s_traits.construct_curve_2_object(); auto ctr_cv = s_traits.construct_curve_2_object();
@ -310,15 +289,17 @@ Aos::Approx_arcs Aos::get_approx_arcs(double error)
auto approx_arcs = get_approx_curves(xcvs, error); auto approx_arcs = get_approx_curves(xcvs, error);
return approx_arcs; return approx_arcs;
} }
Aos::Approx_arcs Aos::get_approx_arcs(const Kml::Placemark& placemark, double error)
{ //! \brief
auto Aos::get_approx_arcs(const Kml::Placemark& placemark, double error) ->
Approx_arcs {
auto xcvs = get_arcs(placemark); auto xcvs = get_arcs(placemark);
auto arcs = ::get_approx_curves(xcvs, error); auto arcs = ::get_approx_curves(xcvs, error);
return arcs; return arcs;
} }
void Aos::check(const Kml::Placemarks& placemarks) //! \brief
{ void Aos::check(const Kml::Placemarks& placemarks) {
//Geom_traits traits; //Geom_traits traits;
Arrangement arr(&s_traits); Arrangement arr(&s_traits);
@ -343,8 +324,8 @@ void Aos::check(const Kml::Placemarks& placemarks)
std::cout << "num arr faces = " << arr.number_of_faces() << std::endl; std::cout << "num arr faces = " << arr.number_of_faces() << std::endl;
} }
std::vector<QVector3D> Aos::ext_check(const Kml::Placemarks& placemarks) //! \brief
{ std::vector<QVector3D> Aos::ext_check(const Kml::Placemarks& placemarks) {
// Construct the arrangement from 12 geodesic arcs. // Construct the arrangement from 12 geodesic arcs.
//Geom_traits traits; //Geom_traits traits;
Ext_aos arr(&s_traits); Ext_aos arr(&s_traits);
@ -357,39 +338,33 @@ std::vector<QVector3D> Aos::ext_check(const Kml::Placemarks& placemarks)
// MARK all vertices as true // MARK all vertices as true
for (auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) for (auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit)
{
vit->set_data(Flag(true)); vit->set_data(Flag(true));
}
std::cout << "-------------------------------\n"; std::cout << "-------------------------------\n";
std::cout << "num arr vertices (before adding arcs) = " << std::cout << "num arr vertices (before adding arcs) = " <<
arr.number_of_vertices() << std::endl; arr.number_of_vertices() << std::endl;
// add arcs // add arcs
for (auto& xcv : xcvs) for (auto& xcv : xcvs) CGAL::insert(arr, xcv);
CGAL::insert(arr, xcv);
// extract all vertices that are ADDED when inserting the arcs! // extract all vertices that are ADDED when inserting the arcs!
int num_created_vertices = 0; int num_created_vertices = 0;
std::vector<QVector3D> created_vertices; std::vector<QVector3D> created_vertices;
auto approx = s_traits.approximate_2_object(); auto approx = s_traits.approximate_2_object();
for (auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) for (auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) {
{
auto& d = vit->data(); auto& d = vit->data();
if (vit->data().v == false) if (vit->data().v == false) {
{
std::cout << "-------------------------------------\n"; std::cout << "-------------------------------------\n";
std::cout << vit->point() << std::endl; std::cout << vit->point() << std::endl;
if (2 == vit->degree()) if (2 == vit->degree());//continue;
;//continue;
if (1 == vit->degree()) if (1 == vit->degree()) {
{
auto p = vit->point(); auto p = vit->point();
auto p2 = p.location(); auto p2 = p.location();
std::cout << " deg-1 vertex = " << p << std::endl; std::cout << " deg-1 vertex = " << p << std::endl;
std::cout << " deg-1 vertex: " << std::boolalpha << vit->incident_halfedges()->target()->data().v << std::endl; std::cout << " deg-1 vertex: " << std::boolalpha
<< vit->incident_halfedges()->target()->data().v << std::endl;
} }
@ -411,7 +386,8 @@ std::vector<QVector3D> Aos::ext_check(const Kml::Placemarks& placemarks)
auto curr = first; auto curr = first;
do { do {
auto tvh = curr->twin()->target(); auto tvh = curr->twin()->target();
//std::cout << std::boolalpha << svh->data().v << " - " << tvh->data().v << std::endl; //std::cout << std::boolalpha << svh->data().v << " - "
// << tvh->data().v << std::endl;
auto it = vertex_node_map.find(tvh); auto it = vertex_node_map.find(tvh);
if (it != vertex_node_map.end()) if (it != vertex_node_map.end())
std::cout << std::setprecision(16) << it->second << std::endl; std::cout << std::setprecision(16) << it->second << std::endl;
@ -442,14 +418,12 @@ std::vector<QVector3D> Aos::ext_check(const Kml::Placemarks& placemarks)
return created_vertices; return created_vertices;
} }
//! \brief
std::vector<QVector3D> Aos::ext_check_id_based(Kml::Placemarks& placemarks) std::vector<QVector3D> Aos::ext_check_id_based(Kml::Placemarks& placemarks) {
{
// Construct the arrangement from 12 geodesic arcs. // Construct the arrangement from 12 geodesic arcs.
//Geom_traits traits; //Geom_traits traits;
Ext_aos arr(&s_traits); Ext_aos arr(&s_traits);
//
auto nodes = Kml::generate_ids(placemarks); auto nodes = Kml::generate_ids(placemarks);
//auto nodes = Kml::generate_ids_approx(placemarks, 0.001); //auto nodes = Kml::generate_ids_approx(placemarks, 0.001);
@ -462,8 +436,7 @@ std::vector<QVector3D> Aos::ext_check_id_based(Kml::Placemarks& placemarks)
// //
std::vector<Point> points; std::vector<Point> points;
std::vector<Ext_aos::Vertex_handle> vertices; std::vector<Ext_aos::Vertex_handle> vertices;
for (const auto& node : nodes) for (const auto& node : nodes) {
{
auto n = node.get_coords_3d(); auto n = node.get_coords_3d();
auto p = ctr_p(n.x, n.y, n.z); auto p = ctr_p(n.x, n.y, n.z);
auto v = CGAL::insert_point(arr, p); auto v = CGAL::insert_point(arr, p);
@ -475,22 +448,17 @@ std::vector<QVector3D> Aos::ext_check_id_based(Kml::Placemarks& placemarks)
std::cout << "num points = " << points.size() << std::endl; std::cout << "num points = " << points.size() << std::endl;
// MARK all vertices as true // MARK all vertices as true
for (auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) for (auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit)
{
vit->set_data(Flag(true)); vit->set_data(Flag(true));
}
for (auto& placemark : placemarks) for (auto& placemark : placemarks) {
{ for (auto& polygon : placemark.polygons) {
for (auto& polygon : placemark.polygons)
{
num_counted_polygons++; num_counted_polygons++;
// TO DO : ADD the outer boundaries! // TO DO : ADD the outer boundaries!
auto& ids = polygon.outer_boundary.ids; auto& ids = polygon.outer_boundary.ids;
int num_nodes = ids.size(); int num_nodes = ids.size();
for (int i = 0; i < num_nodes - 1; ++i) for (int i = 0; i < num_nodes - 1; ++i) {
{
num_counted_arcs++; num_counted_arcs++;
const auto nid1 = ids[i]; const auto nid1 = ids[i];
const auto nid2 = ids[i + 1]; const auto nid2 = ids[i + 1];
@ -509,23 +477,20 @@ std::vector<QVector3D> Aos::ext_check_id_based(Kml::Placemarks& placemarks)
int num_created_vertices = 0; int num_created_vertices = 0;
std::vector<QVector3D> created_vertices; std::vector<QVector3D> created_vertices;
auto approx = s_traits.approximate_2_object(); auto approx = s_traits.approximate_2_object();
for (auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) for (auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) {
{
auto& d = vit->data(); auto& d = vit->data();
if (vit->data().v == false) if (vit->data().v == false) {
{
std::cout << "-------------------------------------\n"; std::cout << "-------------------------------------\n";
std::cout << vit->point() << std::endl; std::cout << vit->point() << std::endl;
if (2 == vit->degree()) if (2 == vit->degree());//continue;
;//continue;
if (1 == vit->degree()) if (1 == vit->degree()) {
{
auto p = vit->point(); auto p = vit->point();
auto p2 = p.location(); auto p2 = p.location();
std::cout << "deg-1 vertex = " << p << std::endl; std::cout << "deg-1 vertex = " << p << std::endl;
std::cout << "deg-1 vertex: " << std::boolalpha << vit->incident_halfedges()->target()->data().v << std::endl; std::cout << "deg-1 vertex: " << std::boolalpha
<< vit->incident_halfedges()->target()->data().v << std::endl;
} }
@ -548,7 +513,8 @@ std::vector<QVector3D> Aos::ext_check_id_based(Kml::Placemarks& placemarks)
std::cout << std::endl; std::cout << std::endl;
} }
} }
std::cout << "*** num created vertices = " << num_created_vertices << std::endl; std::cout << "*** num created vertices = " << num_created_vertices
<< std::endl;
std::cout << "-------------------------------\n"; std::cout << "-------------------------------\n";
std::cout << "num nodes = " << nodes.size() << std::endl; std::cout << "num nodes = " << nodes.size() << std::endl;
@ -565,9 +531,8 @@ std::vector<QVector3D> Aos::ext_check_id_based(Kml::Placemarks& placemarks)
return created_vertices; return created_vertices;
} }
//! brief
Aos::Approx_arcs Aos::find_new_faces(Kml::Placemarks& placemarks) auto Aos::find_new_faces(Kml::Placemarks& placemarks) -> Approx_arcs {
{
//Geom_traits traits; //Geom_traits traits;
Ext_aos arr(&s_traits); Ext_aos arr(&s_traits);
auto ctr_p = s_traits.construct_point_2_object(); auto ctr_p = s_traits.construct_point_2_object();
@ -580,7 +545,6 @@ Aos::Approx_arcs Aos::find_new_faces(Kml::Placemarks& placemarks)
auto nodes = Kml::generate_ids(placemarks); auto nodes = Kml::generate_ids(placemarks);
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// define a set of vertex-handles: use this to check if the face is // define a set of vertex-handles: use this to check if the face is
// obtained from the polygon definition, or if it is an additional face // obtained from the polygon definition, or if it is an additional face
@ -588,17 +552,14 @@ Aos::Approx_arcs Aos::find_new_faces(Kml::Placemarks& placemarks)
std::map<Vertex_handle, int> vertex_id_map; std::map<Vertex_handle, int> vertex_id_map;
std::set<std::set<int>> all_polygon_node_ids; std::set<std::set<int>> all_polygon_node_ids;
num_counted_nodes = 0; num_counted_nodes = 0;
num_counted_arcs = 0; num_counted_arcs = 0;
num_counted_polygons = 0; num_counted_polygons = 0;
std::vector<Curve> xcvs; std::vector<Curve> xcvs;
for (auto& pm : placemarks) for (auto& pm : placemarks) {
{
std::cout << pm.name << std::endl; std::cout << pm.name << std::endl;
for (auto& polygon : pm.polygons) for (auto& polygon : pm.polygons) {
{ ++num_counted_polygons;
num_counted_polygons++;
// colect all rings into a single list (FOR NOW!!!) // colect all rings into a single list (FOR NOW!!!)
// TO-DO: PROCESS OUTER & INNER BOUNDARIES SEPARATELY!!! // TO-DO: PROCESS OUTER & INNER BOUNDARIES SEPARATELY!!!
@ -618,9 +579,9 @@ Aos::Approx_arcs Aos::find_new_faces(Kml::Placemarks& placemarks)
// convert the nodes to points on unit-sphere // convert the nodes to points on unit-sphere
std::vector<Approximate_Vector_3> sphere_points; std::vector<Approximate_Vector_3> sphere_points;
//for (const auto& node : lring->nodes) //for (const auto& node : lring->nodes)
//std::cout << " NUM POLYGON-NODES SIZE = " << lring->ids.size() << std::endl; //std::cout << " NUM POLYGON-NODES SIZE = "
for (int i = 0; i < lring->ids.size(); ++i) // << lring->ids.size() << std::endl;
{ for (int i = 0; i < lring->ids.size(); ++i) {
num_counted_nodes++; num_counted_nodes++;
const auto id = lring->ids[i]; const auto id = lring->ids[i];
const auto& node = lring->nodes[i]; const auto& node = lring->nodes[i];
@ -641,7 +602,8 @@ Aos::Approx_arcs Aos::find_new_faces(Kml::Placemarks& placemarks)
vertex_id_map[vh] = id; vertex_id_map[vh] = id;
vh->data().v = true; vh->data().v = true;
} }
//std::cout << " POLYGON-NODES SET SIZE = " << polygon_node_ids.size() << std::endl; //std::cout << " POLYGON-NODES SET SIZE = "
// << polygon_node_ids.size() << std::endl;
if (lring->ids.size() != (1 + polygon_node_ids.size())) if (lring->ids.size() != (1 + polygon_node_ids.size()))
std::cout << "*** ASSERTION ERROR!!!!\n"; std::cout << "*** ASSERTION ERROR!!!!\n";
@ -671,15 +633,10 @@ Aos::Approx_arcs Aos::find_new_faces(Kml::Placemarks& placemarks)
int num_found = 0; int num_found = 0;
int num_not_found = 0; int num_not_found = 0;
std::vector<Curve> new_face_arcs; std::vector<Curve> new_face_arcs;
for (auto fh = arr.faces_begin(); fh != arr.faces_end(); ++fh) for (auto fh = arr.faces_begin(); fh != arr.faces_end(); ++fh) {
{
// skip the spherical face // skip the spherical face
std::cout << "num outer_ccbs = " << fh->number_of_outer_ccbs() << std::endl; std::cout << "num outer_ccbs = " << fh->number_of_outer_ccbs() << std::endl;
if (fh->number_of_outer_ccbs() == 0) if (fh->number_of_outer_ccbs() == 0) continue;
{
continue;
}
// construct the set of all node-ids for the current face // construct the set of all node-ids for the current face
std::set<int> face_node_ids_set; std::set<int> face_node_ids_set;
@ -690,27 +647,28 @@ Aos::Approx_arcs Aos::find_new_faces(Kml::Placemarks& placemarks)
do { do {
auto vh = curr->source(); auto vh = curr->source();
// skip if the vertex is due to intersection with the identification curve // skip if the vertex is due to intersection with the identification curve
if ((vh->data().v == false) && (vh->degree() == 2)) if ((vh->data().v == false) && (vh->degree() == 2)) continue;
continue;
auto id = vertex_id_map[vh]; auto id = vertex_id_map[vh];
face_node_ids_set.insert(id); face_node_ids_set.insert(id);
face_arcs.push_back(ctr_cv(curr->source()->point(), curr->target()->point())); face_arcs.push_back(ctr_cv(curr->source()->point(),
curr->target()->point()));
} while (++curr != first); } while (++curr != first);
//std::cout << "counted vertices = " << num_vertices << std::endl; //std::cout << "counted vertices = " << num_vertices << std::endl;
//std::cout << "vertices in the set = " << polygon_node_ids.size() << std::endl; //std::cout << "vertices in the set = " << polygon_node_ids.size()
// << std::endl;
auto it = all_polygon_node_ids.find(face_node_ids_set); auto it = all_polygon_node_ids.find(face_node_ids_set);
if (it == all_polygon_node_ids.cend()) if (it == all_polygon_node_ids.cend()) {
{
std::cout << "NOT FOUND!!!\n"; std::cout << "NOT FOUND!!!\n";
std::cout << "num nodes = " << face_node_ids_set.size() << std::endl; std::cout << "num nodes = " << face_node_ids_set.size() << std::endl;
num_not_found++; num_not_found++;
new_face_arcs.insert(new_face_arcs.end(), face_arcs.begin(), face_arcs.end()); new_face_arcs.insert(new_face_arcs.end(), face_arcs.begin(),
face_arcs.end());
} }
else else
num_found++; ++num_found;
} }
std::cout << "num not found = " << num_not_found << std::endl; std::cout << "num not found = " << num_not_found << std::endl;
@ -718,9 +676,8 @@ Aos::Approx_arcs Aos::find_new_faces(Kml::Placemarks& placemarks)
return approx_arcs; return approx_arcs;
} }
//! \brief
void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name) void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name) {
{
#ifndef USE_EPIC #ifndef USE_EPIC
//Geom_traits traits; //Geom_traits traits;
Ext_aos arr(&s_traits); Ext_aos arr(&s_traits);
@ -751,11 +708,9 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
num_counted_arcs = 0; num_counted_arcs = 0;
num_counted_polygons = 0; num_counted_polygons = 0;
std::vector<Curve> xcvs; std::vector<Curve> xcvs;
for (auto& pm : placemarks) for (auto& pm : placemarks) {
{
std::cout << pm.name << std::endl; std::cout << pm.name << std::endl;
for (auto& polygon : pm.polygons) for (auto& polygon : pm.polygons) {
{
num_counted_polygons++; num_counted_polygons++;
// colect all rings into a single list (FOR NOW!!!) // colect all rings into a single list (FOR NOW!!!)
@ -776,9 +731,9 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
// convert the nodes to points on unit-sphere // convert the nodes to points on unit-sphere
std::vector<Approximate_Vector_3> sphere_points; std::vector<Approximate_Vector_3> sphere_points;
//for (const auto& node : lring->nodes) //for (const auto& node : lring->nodes)
//std::cout << " NUM POLYGON-NODES SIZE = " << lring->ids.size() << std::endl; //std::cout << " NUM POLYGON-NODES SIZE = " << lring->ids.size()
for (int i = 0; i < lring->ids.size(); ++i) // << std::endl;
{ for (int i = 0; i < lring->ids.size(); ++i) {
num_counted_nodes++; num_counted_nodes++;
const auto id = lring->ids[i]; const auto id = lring->ids[i];
const auto& node = lring->nodes[i]; const auto& node = lring->nodes[i];
@ -799,7 +754,8 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
vertex_id_map[vh] = id; vertex_id_map[vh] = id;
vh->data().v = true; vh->data().v = true;
} }
//std::cout << " POLYGON-NODES SET SIZE = " << polygon_node_ids.size() << std::endl; //std::cout << " POLYGON-NODES SET SIZE = "
// << polygon_node_ids.size() << std::endl;
if (lring->ids.size() != (1 + polygon_node_ids.size())) if (lring->ids.size() != (1 + polygon_node_ids.size()))
std::cout << "*** ASSERTION ERROR!!!!\n"; std::cout << "*** ASSERTION ERROR!!!!\n";
@ -808,8 +764,7 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
// add curves // add curves
int num_points = sphere_points.size(); int num_points = sphere_points.size();
for (int i = 0; i < num_points - 1; i++) for (int i = 0; i < num_points - 1; ++i) {
{
num_counted_arcs++; num_counted_arcs++;
const auto p1 = sphere_points[i]; const auto p1 = sphere_points[i];
const auto p2 = sphere_points[i + 1]; const auto p2 = sphere_points[i + 1];
@ -825,9 +780,12 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
} }
} }
std::cout << "*** arr.number_of_faces = " << arr.number_of_faces() << std::endl; std::cout << "*** arr.number_of_faces = " << arr.number_of_faces()
std::cout << "*** arr.number_of_halfedges = " << arr.number_of_halfedges() << std::endl; << std::endl;
std::cout << "*** arr.number_of_vertices = " << arr.number_of_vertices() << std::endl; std::cout << "*** arr.number_of_halfedges = " << arr.number_of_halfedges()
<< std::endl;
std::cout << "*** arr.number_of_vertices = " << arr.number_of_vertices()
<< std::endl;
// DEFINE JSON OBJECT // DEFINE JSON OBJECT
json js; json js;
@ -844,9 +802,7 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
CGAL::Rational_traits<decltype(ex)> rt; CGAL::Rational_traits<decltype(ex)> rt;
typename CGAL::Algebraic_structure_traits<decltype(ex)>::Simplify simplify; typename CGAL::Algebraic_structure_traits<decltype(ex)>::Simplify simplify;
auto set_num_denum = [&](decltype(ex)& x, json& ratx) {
auto set_num_denum = [&](decltype(ex)& x, json& ratx)
{
simplify(x); simplify(x);
std::stringstream ss_x_num; std::stringstream ss_x_num;
CGAL::IO::set_ascii_mode(ss_x_num); CGAL::IO::set_ascii_mode(ss_x_num);
@ -863,17 +819,14 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
ratx["den"] = xden; ratx["den"] = xden;
}; };
using Point_ = std::decay_t<decltype(arr.vertices_begin()->point())>; using Point_ = std::decay_t<decltype(arr.vertices_begin()->point())>;
std::map<void*, int> point_pos_map; std::map<void*, int> point_pos_map;
std::vector<Point_> points; std::vector<Point_> points;
std::map<Vertex_handle, int> vertex_pos_map; std::map<Vertex_handle, int> vertex_pos_map;
for (auto vh = arr.vertices_begin(); vh != arr.vertices_end(); ++vh) for (auto vh = arr.vertices_begin(); vh != arr.vertices_end(); ++vh) {
{
// add the vertex if not found in the map // add the vertex if not found in the map
auto it = vertex_pos_map.find(vh); auto it = vertex_pos_map.find(vh);
if (it == vertex_pos_map.end()) if (it == vertex_pos_map.end()) {
{
int new_vh_pos = vertex_pos_map.size(); int new_vh_pos = vertex_pos_map.size();
vertex_pos_map[vh] = new_vh_pos; vertex_pos_map[vh] = new_vh_pos;
@ -901,13 +854,11 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
using Ext_curve = Ext_aos::X_monotone_curve_2; using Ext_curve = Ext_aos::X_monotone_curve_2;
std::map<Ext_curve*, int> curve_pos_map; std::map<Ext_curve*, int> curve_pos_map;
int num_edges = 0; int num_edges = 0;
for (auto eh = arr.edges_begin(); eh != arr.edges_end(); ++eh) for (auto eh = arr.edges_begin(); eh != arr.edges_end(); ++eh) {
{
num_edges++; num_edges++;
auto& xcv = eh->curve(); auto& xcv = eh->curve();
auto it = curve_pos_map.find(&xcv); auto it = curve_pos_map.find(&xcv);
if (it == curve_pos_map.end()) if (it == curve_pos_map.end()) {
{
int new_xcv_pos = curve_pos_map.size(); int new_xcv_pos = curve_pos_map.size();
curve_pos_map[&xcv] = new_xcv_pos; curve_pos_map[&xcv] = new_xcv_pos;
@ -947,8 +898,7 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
// VERTICES // VERTICES
// there is a one-to-one corresponce between vertices and points // there is a one-to-one corresponce between vertices and points
auto& js_vertices = js["vertices"] = json::array(); auto& js_vertices = js["vertices"] = json::array();
for (auto vh = arr.vertices_begin(); vh != arr.vertices_end(); ++vh) for (auto vh = arr.vertices_begin(); vh != arr.vertices_end(); ++vh) {
{
json js_vertex; json js_vertex;
auto vpos = vertex_pos_map[vh]; auto vpos = vertex_pos_map[vh];
js_vertex["point"] = vpos; js_vertex["point"] = vpos;
@ -999,8 +949,7 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
//std::map<void*, int> edge_pos_map; //std::map<void*, int> edge_pos_map;
std::map<void*, int> halfedge_pos_map; std::map<void*, int> halfedge_pos_map;
//Edge_const_iterator eit; //Edge_const_iterator eit;
for (auto eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) for (auto eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) {
{
auto& edge = *eit; auto& edge = *eit;
//auto it = edge_pos_map.find(&edge); //auto it = edge_pos_map.find(&edge);
//if (it == edge_pos_map.end()) //if (it == edge_pos_map.end())
@ -1037,14 +986,10 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
int num_found = 0; int num_found = 0;
int num_not_found = 0; int num_not_found = 0;
std::map<Face_handle, std::string> face_name_map; std::map<Face_handle, std::string> face_name_map;
for (auto fh = arr.faces_begin(); fh != arr.faces_end(); ++fh) for (auto fh = arr.faces_begin(); fh != arr.faces_end(); ++fh) {
{
// skip the spherical face // skip the spherical face
std::cout << "num outer_ccbs = " << fh->number_of_outer_ccbs() << std::endl; std::cout << "num outer_ccbs = " << fh->number_of_outer_ccbs() << std::endl;
if (fh->number_of_outer_ccbs() == 0) if (fh->number_of_outer_ccbs() == 0) continue;
{
continue;
}
// construct the set of all node-ids for the current face // construct the set of all node-ids for the current face
std::set<int> face_node_ids_set; std::set<int> face_node_ids_set;
@ -1088,8 +1033,7 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
// RECORD FACES // RECORD FACES
json& js_faces = js["faces"] = json::array(); json& js_faces = js["faces"] = json::array();
auto get_ccb_json = [&](Ext_aos::Ccb_halfedge_circulator first) auto get_ccb_json = [&](Ext_aos::Ccb_halfedge_circulator first) {
{
json js_edges; json js_edges;
auto& ccb_edge_indices = js_edges["halfedges"] = json::array(); auto& ccb_edge_indices = js_edges["halfedges"] = json::array();
auto curr = first; auto curr = first;
@ -1115,8 +1059,7 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
}; };
int total_num_half_edges = 0; int total_num_half_edges = 0;
for (auto fh = arr.faces_begin(); fh != arr.faces_end(); ++fh) for (auto fh = arr.faces_begin(); fh != arr.faces_end(); ++fh) {
{
//// skip the spherical face //// skip the spherical face
//if (fh->number_of_outer_ccbs() == 0) //if (fh->number_of_outer_ccbs() == 0)
// continue; // continue;
@ -1137,11 +1080,10 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
} }
// INNER CCBS // INNER CCBS
if (fh->number_of_inner_ccbs() > 0) if (fh->number_of_inner_ccbs() > 0) {
{
auto& js_inner_ccbs = js_face["inner_ccbs"] = json::array(); auto& js_inner_ccbs = js_face["inner_ccbs"] = json::array();
for (auto ccb = fh->inner_ccbs_begin(); ccb != fh->inner_ccbs_end(); ++ccb) for (auto ccb = fh->inner_ccbs_begin(); ccb != fh->inner_ccbs_end();
{ ++ccb) {
auto js_ccb = get_ccb_json(*ccb); auto js_ccb = get_ccb_json(*ccb);
js_inner_ccbs.push_back(std::move(js_ccb)); js_inner_ccbs.push_back(std::move(js_ccb));
} }
@ -1158,9 +1100,7 @@ void Aos::save_arr(Kml::Placemarks& placemarks, const std::string& file_name)
#endif #endif
} }
namespace {
namespace
{
enum Error_id { enum Error_id {
FILE_NOT_FOUND, FILE_NOT_FOUND,
ILLEGAL_EXTENSION, ILLEGAL_EXTENSION,
@ -1191,9 +1131,7 @@ namespace
// //
struct country { struct country {
//! Constructor //! Constructor
country(std::string& name) : country(std::string& name) : m_name(std::move(name)) {}
m_name(std::move(name))
{}
std::string m_name; std::string m_name;
}; };
@ -1216,6 +1154,8 @@ namespace
return true; return true;
} }
/*!
*/
template <typename FT> template <typename FT>
FT to_ft(const nlohmann::json& js_ft) { FT to_ft(const nlohmann::json& js_ft) {
using Exact_type = typename FT::Exact_type; using Exact_type = typename FT::Exact_type;
@ -1226,9 +1166,8 @@ namespace
return FT(eft); return FT(eft);
} }
template <typename Arrangement_, typename Kernel_> template <typename Kernel_, typename Arrangement_>
bool read_arrangement(const std::string& filename, Arrangement_& arr, bool read_arrangement(const std::string& filename, Arrangement_& arr) {
const Kernel_& kernel) {
using Arrangement = Arrangement_; using Arrangement = Arrangement_;
using Kernel = Kernel_; using Kernel = Kernel_;
@ -1502,45 +1441,35 @@ namespace
namespace { namespace {
/*!
*/
template<typename T> template<typename T>
Aos::Arr_handle get_handle(T* arr) Aos::Arr_handle get_handle(T* arr) {
{ return Aos::Arr_handle(arr, [](void* ptr) {
return Aos::Arr_handle(arr, [](void* ptr)
{
std::cout << "*** DELETING THE ARRANGEMENT WITH SHARED_PTR DELETER!!\n"; std::cout << "*** DELETING THE ARRANGEMENT WITH SHARED_PTR DELETER!!\n";
delete reinterpret_cast<T*>(ptr); delete reinterpret_cast<T*>(ptr);
}); });
} }
} }
Aos::Arr_handle Aos::load_arr(const std::string& file_name) /*!
{ */
Aos::Arr_handle Aos::load_arr(const std::string& file_name) {
auto* arr = new Countries_arr(&s_traits); auto* arr = new Countries_arr(&s_traits);
auto arrh = get_handle(arr); auto arrh = get_handle(arr);
auto rc = read_arrangement<Kernel>(file_name, *arr);
Kernel kernel; if (! rc) return nullptr;
auto rc = read_arrangement(file_name, *arr, kernel);
if (!rc) {
return nullptr;
}
return arrh; return arrh;
} }
Aos::Arr_handle Aos::construct(Kml::Placemarks& placemarks) {
Aos::Arr_handle Aos::construct(Kml::Placemarks& placemarks)
{
auto* arr = new Arrangement(&s_traits); auto* arr = new Arrangement(&s_traits);
auto arrh = get_handle(arr); auto arrh = get_handle(arr);
auto xcvs = get_arcs(placemarks, *arr); auto xcvs = get_arcs(placemarks, *arr);
for (auto& xcv : xcvs) for (auto& xcv : xcvs) CGAL::insert(*arr, xcv);
CGAL::insert(*arr, xcv);
return arrh; return arrh;
} }
//std::vector<QVector3D> Aos::get_triangles(Arr_handle arrh) //std::vector<QVector3D> Aos::get_triangles(Arr_handle arrh)
//{ //{
// using K = CGAL::Exact_predicates_inexact_constructions_kernel; // using K = CGAL::Exact_predicates_inexact_constructions_kernel;
@ -1798,41 +1727,34 @@ Aos::Arr_handle Aos::construct(Kml::Placemarks& placemarks)
// return result; // return result;
//} //}
Aos::Country_color_map Aos::get_color_mapping(Arr_handle arrh) {
Aos::Country_color_map Aos::get_color_mapping(Arr_handle arrh)
{
auto& arr = *reinterpret_cast<Countries_arr*>(arrh.get()); auto& arr = *reinterpret_cast<Countries_arr*>(arrh.get());
// group the faces by their country name, // group the faces by their country name,
std::vector<std::string> all_countries; std::vector<std::string> all_countries;
using Face_ = Countries_arr::Face_handle::value_type; using Face_ = Countries_arr::Face_handle::value_type;
std::map<std::string, std::vector<Face_*>> country_faces_map; std::map<std::string, std::vector<Face_*>> country_faces_map;
for (auto fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) for (auto fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) {
{
auto& face = *fit; auto& face = *fit;
const auto& country_name = fit->data(); const auto& country_name = fit->data();
// skipping spherical-face // skipping spherical-face
if (country_name.empty()) if (country_name.empty()) continue;
continue;
country_faces_map[country_name].push_back(&face); country_faces_map[country_name].push_back(&face);
all_countries.push_back(country_name); all_countries.push_back(country_name);
} }
// prepare a map of neighboring countries // prepare a map of neighboring countries
std::map<std::string, std::set<std::string>> country_neighbors_map; std::map<std::string, std::set<std::string>> country_neighbors_map;
for (auto& [country_name, faces] : country_faces_map) for (auto& [country_name, faces] : country_faces_map) {
{
// loop on all of the faces of the current country // loop on all of the faces of the current country
for (auto* face : faces) for (auto* face : faces) {
{
auto first = face->outer_ccb(); auto first = face->outer_ccb();
auto curr = first; auto curr = first;
do { do {
const auto& neighbor_country_name = curr->twin()->face()->data(); const auto& neighbor_country_name = curr->twin()->face()->data();
// skip the spherical face // skip the spherical face
if (neighbor_country_name.empty()) if (neighbor_country_name.empty()) continue;
continue;
country_neighbors_map[country_name].insert(neighbor_country_name); country_neighbors_map[country_name].insert(neighbor_country_name);
} while (++curr != first); } while (++curr != first);
@ -1841,17 +1763,14 @@ Aos::Country_color_map Aos::get_color_mapping(Arr_handle arrh)
// find a color index for each country by looking at its neighbors // find a color index for each country by looking at its neighbors
Country_color_map result; Country_color_map result;
for(const auto& country_name : all_countries) for (const auto& country_name : all_countries) {
{
// first: find a free color index // first: find a free color index
bool color_used[5] = { false, false, false, false, false }; bool color_used[5] = { false, false, false, false, false };
auto& neighbor_set = country_neighbors_map[country_name]; auto& neighbor_set = country_neighbors_map[country_name];
for (auto& neighbor : neighbor_set) for (auto& neighbor : neighbor_set) {
{
auto it = result.find(neighbor); auto it = result.find(neighbor);
// if there is a country in the map, then it must have been assigned one! // if there is a country in the map, then it must have been assigned one!
if (it != result.end()) if (it != result.end()) {
{
auto used_color_index = it->second; auto used_color_index = it->second;
color_used[used_color_index] = true; color_used[used_color_index] = true;
} }
@ -1859,10 +1778,8 @@ Aos::Country_color_map Aos::get_color_mapping(Arr_handle arrh)
// find the first color index not used // find the first color index not used
bool found = false; bool found = false;
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; ++i) {
{ if (! color_used[i]) {
if (color_used[i] == false)
{
found = true; found = true;
result[country_name] = i; result[country_name] = i;
} }
@ -1875,9 +1792,7 @@ Aos::Country_color_map Aos::get_color_mapping(Arr_handle arrh)
return result; return result;
} }
std::string Aos::locate_country(Arr_handle arrh, const QVector3D& point) {
std::string Aos::locate_country(Arr_handle arrh, const QVector3D& point)
{
using Point_2 = Countries_arr::Point_2; using Point_2 = Countries_arr::Point_2;
using Naive_pl = CGAL::Arr_naive_point_location<Countries_arr>; using Naive_pl = CGAL::Arr_naive_point_location<Countries_arr>;
@ -1911,47 +1826,39 @@ std::string Aos::locate_country(Arr_handle arrh, const QVector3D& point)
//const Face_const_handle* f; //const Face_const_handle* f;
//std::cout << "The point (" << query_point << ") is located "; //std::cout << "The point (" << query_point << ") is located ";
std::string country_name = ""; std::string country_name = "";
if (auto f = std::get_if<Face_const_handle>(&obj)) // located inside a face if (auto f = std::get_if<Face_const_handle>(&obj)) { // located inside a face
{
//std::cout << "*** QUERY: FACE\n"; //std::cout << "*** QUERY: FACE\n";
country_name = f->ptr()->data(); country_name = f->ptr()->data();
} }
else if (auto e = std::get_if<Halfedge_const_handle>(&obj)) else if (auto e = std::get_if<Halfedge_const_handle>(&obj)) {
{
// located on an edge: return one of the incident face arbitrarily // located on an edge: return one of the incident face arbitrarily
//std::cout << "*** QUERY: EDGE\n"; //std::cout << "*** QUERY: EDGE\n";
country_name = (*e)->face()->data(); country_name = (*e)->face()->data();
} }
else if (auto v = std::get_if<Vertex_const_handle>(&obj)) else if (auto v = std::get_if<Vertex_const_handle>(&obj)) {
{
// located on a vertex // located on a vertex
if ((*v)->is_isolated()) if ((*v)->is_isolated()) {
{
//std::cout << "*** QUERY: ISOLATED VERTEX\n"; //std::cout << "*** QUERY: ISOLATED VERTEX\n";
country_name = (*v)->face()->data(); country_name = (*v)->face()->data();
} }
else else {
{
//std::cout << "*** QUERY: VERTEX\n"; //std::cout << "*** QUERY: VERTEX\n";
country_name = (*v)->incident_halfedges()->face()->data(); country_name = (*v)->incident_halfedges()->face()->data();
} }
} }
else else {
{
CGAL_error_msg("Invalid object."); CGAL_error_msg("Invalid object.");
} }
return country_name; return country_name;
} }
Aos::Approx_arcs Aos::get_approx_arcs_from_faces_edges(Arr_handle arrh, Aos::Approx_arcs
float error) Aos::get_approx_arcs_from_faces_edges(Arr_handle arrh, float error) {
{
auto& arr = *reinterpret_cast<Countries_arr*>(arrh.get()); auto& arr = *reinterpret_cast<Countries_arr*>(arrh.get());
auto ctr_cv = s_traits.construct_curve_2_object(); auto ctr_cv = s_traits.construct_curve_2_object();
Curves xcvs; Curves xcvs;
for (auto eit = arr.halfedges_begin(); eit != arr.halfedges_end(); ++eit) for (auto eit = arr.halfedges_begin(); eit != arr.halfedges_end(); ++eit) {
{
auto& s = eit->curve(); auto& s = eit->curve();
xcvs.push_back( ctr_cv(s.source(), s.target()) ); xcvs.push_back( ctr_cv(s.source(), s.target()) );
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -17,9 +17,7 @@
#include "Kml_reader.h" #include "Kml_reader.h"
class Aos {
class Aos
{
public: public:
using Approx_arc = std::vector<QVector3D>; using Approx_arc = std::vector<QVector3D>;
using Approx_arcs = std::vector<Approx_arc>; using Approx_arcs = std::vector<Approx_arc>;
@ -32,8 +30,8 @@ public:
static Approx_arcs get_approx_arcs(double error); static Approx_arcs get_approx_arcs(double error);
// this is used to construct approximate arcs from KML-Placemark data // this is used to construct approximate arcs from KML-Placemark data
static Approx_arcs get_approx_arcs(const Kml::Placemark& placemark, double error); static Approx_arcs get_approx_arcs(const Kml::Placemark& placemark,
double error);
static void get_curves(); static void get_curves();
@ -83,5 +81,4 @@ public:
float error); float error);
}; };
#endif #endif

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -18,7 +18,6 @@
#include <CGAL/Arr_spherical_topology_traits_2.h> #include <CGAL/Arr_spherical_topology_traits_2.h>
#include <CGAL/Vector_3.h> #include <CGAL/Vector_3.h>
//#define USE_EPIC //#define USE_EPIC
#ifdef USE_EPIC #ifdef USE_EPIC

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -7,25 +7,19 @@
// //
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com> // Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
#include "Aos_triangulator.h"
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
#include <map> #include <map>
#include <set> #include <set>
#include <vector> #include <vector>
#include <unordered_map>
#include <boost/property_map/property_map.hpp>
#include <qmath.h> #include <qmath.h>
#include <qvector3d.h> #include <qvector3d.h>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
using json = nlohmann::ordered_json;
// Includes for Arrangements on Sphere (AOS)
#include "Aos_defs.h"
//#include "arr_print.h"
//#include "Tools.h"
// Includes for Constrained Delaunay Triangulation // Includes for Constrained Delaunay Triangulation
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
@ -34,28 +28,27 @@ using json = nlohmann::ordered_json;
#include <CGAL/mark_domain_in_triangulation.h> #include <CGAL/mark_domain_in_triangulation.h>
#include <CGAL/Polygon_2.h> #include <CGAL/Polygon_2.h>
//#include <CGAL/Projection_traits_3.h> //#include <CGAL/Projection_traits_3.h>
#include <unordered_map>
#include <boost/property_map/property_map.hpp>
#include "Aos_defs.h"
#include "Aos_triangulator.h"
//#include "arr_print.h"
//#include "Tools.h"
using json = nlohmann::ordered_json;
namespace { namespace {
// use this traits everytime you construct an arrangment! // use this traits everytime you construct an arrangment!
static Geom_traits s_traits; static Geom_traits s_traits;
using Dir3 = Kernel::Direction_3; using Dir3 = Kernel::Direction_3;
std::ostream& operator << (std::ostream& os, const Dir3& d) std::ostream& operator << (std::ostream& os, const Dir3& d) {
{
os << d.dx() << ", " << d.dy() << ", " << d.dz(); os << d.dx() << ", " << d.dy() << ", " << d.dz();
return os; return os;
} }
using Approximate_point_2 = Geom_traits::Approximate_point_2; using Approximate_point_2 = Geom_traits::Approximate_point_2;
std::ostream& operator << (std::ostream& os, const Approximate_point_2& d) std::ostream& operator << (std::ostream& os, const Approximate_point_2& d) {
{
os << d.dx() << ", " << d.dy() << ", " << d.dz(); os << d.dx() << ", " << d.dy() << ", " << d.dz();
return os; return os;
} }
@ -67,10 +60,8 @@ namespace {
using Direction_3 = Kernel::Direction_3; using Direction_3 = Kernel::Direction_3;
} }
//! \brief
std::vector<QVector3D> Aos_triangulator::get_all(Aos::Arr_handle arrh) {
std::vector<QVector3D> Aos_triangulator::get_all(Aos::Arr_handle arrh)
{
using K = CGAL::Exact_predicates_inexact_constructions_kernel; using K = CGAL::Exact_predicates_inexact_constructions_kernel;
//using K = CGAL::Projection_traits_3<K_epic>; //using K = CGAL::Projection_traits_3<K_epic>;
using Vb = CGAL::Triangulation_vertex_base_2<K>; using Vb = CGAL::Triangulation_vertex_base_2<K>;
@ -90,8 +81,7 @@ std::vector<QVector3D> Aos_triangulator::get_all(Aos::Arr_handle arrh)
std::vector<std::vector<QVector3D>> all_faces; std::vector<std::vector<QVector3D>> all_faces;
// loop on all faces of the arrangement // loop on all faces of the arrangement
for (auto fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) for (auto fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) {
{
// skip any face with no OUTER-CCB // skip any face with no OUTER-CCB
if (0 == fit->number_of_outer_ccbs()) if (0 == fit->number_of_outer_ccbs())
continue; continue;
@ -118,21 +108,17 @@ std::vector<QVector3D> Aos_triangulator::get_all(Aos::Arr_handle arrh)
std::cout << "triangulating individual faces\n"; std::cout << "triangulating individual faces\n";
// loop on all approximated faces // loop on all approximated faces
for (auto& face_points : all_faces) for (auto& face_points : all_faces) {
{
//std::cout << "num face points = " << face_points.size() << std::endl; //std::cout << "num face points = " << face_points.size() << std::endl;
// no need to triangulate if the number of points is 3 // no need to triangulate if the number of points is 3
if (face_points.size() == 3) if (face_points.size() == 3) {
{
triangles.insert(triangles.end(), face_points.begin(), face_points.end()); triangles.insert(triangles.end(), face_points.begin(), face_points.end());
continue; continue;
} }
// find the centroid of all face-points // find the centroid of all face-points
QVector3D centroid(0, 0, 0); QVector3D centroid(0, 0, 0);
for (const auto& fp : face_points) for (const auto& fp : face_points) centroid += fp;
centroid += fp;
centroid /= face_points.size(); centroid /= face_points.size();
centroid.normalize(); centroid.normalize();
auto normal = centroid; auto normal = centroid;
@ -145,8 +131,7 @@ std::vector<QVector3D> Aos_triangulator::get_all(Aos::Arr_handle arrh)
// project all points onto the plane // project all points onto the plane
K::Point_3 origin(0, 0, 0); K::Point_3 origin(0, 0, 0);
for (const auto& fp : face_points) for (const auto& fp : face_points) {
{
// define a ray through the origin and the current point // define a ray through the origin and the current point
K::Point_3 current_point(fp.x(), fp.y(), fp.z()); K::Point_3 current_point(fp.x(), fp.y(), fp.z());
K::Ray_3 ray(origin, current_point); K::Ray_3 ray(origin, current_point);
@ -162,7 +147,8 @@ std::vector<QVector3D> Aos_triangulator::get_all(Aos::Arr_handle arrh)
} }
CDT cdt; CDT cdt;
cdt.insert_constraint(polygon.vertices_begin(), polygon.vertices_end(), true); cdt.insert_constraint(polygon.vertices_begin(), polygon.vertices_end(),
true);
std::unordered_map<Face_handle, bool> in_domain_map; std::unordered_map<Face_handle, bool> in_domain_map;
boost::associative_property_map< std::unordered_map<Face_handle, bool>> boost::associative_property_map< std::unordered_map<Face_handle, bool>>
@ -172,14 +158,11 @@ std::vector<QVector3D> Aos_triangulator::get_all(Aos::Arr_handle arrh)
CGAL::mark_domain_in_triangulation(cdt, in_domain); CGAL::mark_domain_in_triangulation(cdt, in_domain);
// loop on all the triangles ("faces" in triangulation doc) // loop on all the triangles ("faces" in triangulation doc)
for (Face_handle f : cdt.finite_face_handles()) for (Face_handle f : cdt.finite_face_handles()) {
{
// if the current triangles is not inside the polygon -> skip it // if the current triangles is not inside the polygon -> skip it
if (false == get(in_domain, f)) if (false == get(in_domain, f)) continue;
continue;
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i) {
{
auto tp = f->vertex(i)->point(); auto tp = f->vertex(i)->point();
auto tp3 = plane.to_3d(tp); auto tp3 = plane.to_3d(tp);
QVector3D p3(tp3.x(), tp3.y(), tp3.z()); QVector3D p3(tp3.x(), tp3.y(), tp3.z());
@ -192,9 +175,8 @@ std::vector<QVector3D> Aos_triangulator::get_all(Aos::Arr_handle arrh)
return triangles; return triangles;
} }
//! \brief
Country_triangles_map Aos_triangulator::get_by_country(Aos::Arr_handle arrh) Country_triangles_map Aos_triangulator::get_by_country(Aos::Arr_handle arrh) {
{
using K = CGAL::Exact_predicates_inexact_constructions_kernel; using K = CGAL::Exact_predicates_inexact_constructions_kernel;
//using K = CGAL::Projection_traits_3<K_epic>; //using K = CGAL::Projection_traits_3<K_epic>;
using Vb = CGAL::Triangulation_vertex_base_2<K>; using Vb = CGAL::Triangulation_vertex_base_2<K>;
@ -212,8 +194,7 @@ Country_triangles_map Aos_triangulator::get_by_country(Aos::Arr_handle arrh)
// group the faces by their country name // group the faces by their country name
using Face_ = Countries_arr::Face_handle::value_type; using Face_ = Countries_arr::Face_handle::value_type;
std::map<std::string, std::vector<Face_*>> country_faces_map; std::map<std::string, std::vector<Face_*>> country_faces_map;
for (auto fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) for (auto fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) {
{
auto& face = *fit; auto& face = *fit;
const auto& country_name = fit->data(); const auto& country_name = fit->data();
// skipping spherical-face // skipping spherical-face
@ -224,17 +205,14 @@ Country_triangles_map Aos_triangulator::get_by_country(Aos::Arr_handle arrh)
std::cout << "triangulating individual faces\n"; std::cout << "triangulating individual faces\n";
Country_triangles_map result; Country_triangles_map result;
for (auto& [country_name, faces] : country_faces_map) for (auto& [country_name, faces] : country_faces_map) {
{
// CONVERT the face-points to QVector3D // CONVERT the face-points to QVector3D
using Face_points = std::vector<QVector3D>; using Face_points = std::vector<QVector3D>;
using Faces_ = std::vector<Face_points>; using Faces_ = std::vector<Face_points>;
Faces_ all_faces_of_current_country; Faces_ all_faces_of_current_country;
for (auto* face : faces) for (auto* face : faces) {
{
// skip any face with no OUTER-CCB // skip any face with no OUTER-CCB
if (0 == face->number_of_outer_ccbs()) if (0 == face->number_of_outer_ccbs()) continue;
continue;
std::vector<QVector3D> face_points; std::vector<QVector3D> face_points;
// loop on the egdes of the current outer-ccb // loop on the egdes of the current outer-ccb
@ -253,13 +231,12 @@ Country_triangles_map Aos_triangulator::get_by_country(Aos::Arr_handle arrh)
// RESULTING TRIANGLE POINTS (every 3 point => triangle) // RESULTING TRIANGLE POINTS (every 3 point => triangle)
auto& triangles = result[country_name]; auto& triangles = result[country_name];
// loop on all approximated faces // loop on all approximated faces
for (auto& face_points : all_faces_of_current_country) for (auto& face_points : all_faces_of_current_country) {
{
//std::cout << "num face points = " << face_points.size() << std::endl; //std::cout << "num face points = " << face_points.size() << std::endl;
// no need to triangulate if the number of points is 3 // no need to triangulate if the number of points is 3
if (face_points.size() == 3) if (face_points.size() == 3) {
{ triangles.insert(triangles.end(), face_points.begin(),
triangles.insert(triangles.end(), face_points.begin(), face_points.end()); face_points.end());
continue; continue;
} }
@ -279,8 +256,7 @@ Country_triangles_map Aos_triangulator::get_by_country(Aos::Arr_handle arrh)
// project all points onto the plane // project all points onto the plane
K::Point_3 origin(0, 0, 0); K::Point_3 origin(0, 0, 0);
for (const auto& fp : face_points) for (const auto& fp : face_points) {
{
// define a ray through the origin and the current point // define a ray through the origin and the current point
K::Point_3 current_point(fp.x(), fp.y(), fp.z()); K::Point_3 current_point(fp.x(), fp.y(), fp.z());
K::Ray_3 ray(origin, current_point); K::Ray_3 ray(origin, current_point);
@ -296,7 +272,8 @@ Country_triangles_map Aos_triangulator::get_by_country(Aos::Arr_handle arrh)
} }
CDT cdt; CDT cdt;
cdt.insert_constraint(polygon.vertices_begin(), polygon.vertices_end(), true); cdt.insert_constraint(polygon.vertices_begin(), polygon.vertices_end(),
true);
std::unordered_map<Face_handle, bool> in_domain_map; std::unordered_map<Face_handle, bool> in_domain_map;
boost::associative_property_map< std::unordered_map<Face_handle, bool> > boost::associative_property_map< std::unordered_map<Face_handle, bool> >
@ -306,14 +283,11 @@ Country_triangles_map Aos_triangulator::get_by_country(Aos::Arr_handle arrh)
CGAL::mark_domain_in_triangulation(cdt, in_domain); CGAL::mark_domain_in_triangulation(cdt, in_domain);
// loop on all the triangles ("faces" in triangulation doc) // loop on all the triangles ("faces" in triangulation doc)
for (Face_handle f : cdt.finite_face_handles()) for (Face_handle f : cdt.finite_face_handles()) {
{
// if the current triangles is not inside the polygon -> skip it // if the current triangles is not inside the polygon -> skip it
if (false == get(in_domain, f)) if (false == get(in_domain, f)) continue;
continue;
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i) {
{
auto tp = f->vertex(i)->point(); auto tp = f->vertex(i)->point();
auto tp3 = plane.to_3d(tp); auto tp3 = plane.to_3d(tp);
QVector3D p3(tp3.x(), tp3.y(), tp3.z()); QVector3D p3(tp3.x(), tp3.y(), tp3.z());

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -17,14 +17,10 @@
#include "Aos.h" #include "Aos.h"
using Country_triangles_map = std::map<std::string, std::vector<QVector3D>>; using Country_triangles_map = std::map<std::string, std::vector<QVector3D>>;
class Aos_triangulator {
class Aos_triangulator
{
public: public:
static std::vector<QVector3D> get_all(Aos::Arr_handle arrh); static std::vector<QVector3D> get_all(Aos::Arr_handle arrh);
static Country_triangles_map get_by_country(Aos::Arr_handle arrh); static Country_triangles_map get_by_country(Aos::Arr_handle arrh);

View File

@ -1,14 +1,20 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.1...3.23)
project(earth LANGUAGES CXX) project(earth LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR) if(NOT POLICY CMP0070 AND POLICY CMP0053)
set(INSTALL_EXAMPLESDIR "examples") # Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning.
cmake_policy(SET CMP0053 OLD)
endif() endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/earth") if(POLICY CMP0071)
cmake_policy(SET CMP0071 NEW)
endif()
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL OpenGLWidgets Widgets Xml) # if(NOT DEFINED INSTALL_EXAMPLESDIR)
add_definitions(-DQT_NO_VERSION_TAGGING) # set(INSTALL_EXAMPLESDIR "examples")
# endif()
# set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/earth")
# CGAL and its components # CGAL and its components
find_package(CGAL QUIET COMPONENTS) find_package(CGAL QUIET COMPONENTS)
@ -18,6 +24,9 @@ if (NOT CGAL_FOUND)
return() return()
endif() endif()
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL OpenGLWidgets Widgets Xml)
add_definitions(-DQT_NO_VERSION_TAGGING)
# Boost and its components # Boost and its components
find_package(Boost REQUIRED) find_package(Boost REQUIRED)
@ -44,7 +53,6 @@ source_group("Aos" FILES ${source_files_aos})
# GIS # GIS
file(GLOB source_files_gis file(GLOB source_files_gis
Kml_reader.h Kml_reader.cpp Kml_reader.h Kml_reader.cpp
Shapefile.h Shapefile.cpp
) )
source_group("GIS" FILES ${source_files_gis}) source_group("GIS" FILES ${source_files_gis})

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -9,16 +9,15 @@
#include "Camera.h" #include "Camera.h"
//! \brief
Camera::Camera() : Camera::Camera() :
m_ux(1, 0, 0), m_ux(1, 0, 0),
m_uy(0, 1, 0), m_uy(0, 1, 0),
m_uz(0, 0, 1) m_uz(0, 0, 1)
{ {}
}
void Camera::perspective(float fov, float aspect, float z_near, float z_far) //! \brief
{ void Camera::perspective(float fov, float aspect, float z_near, float z_far) {
m_z_near = z_near; m_z_near = z_near;
m_z_far = z_far; m_z_far = z_far;
@ -26,18 +25,16 @@ void Camera::perspective(float fov, float aspect, float z_near, float z_far)
m_projection.perspective(fov, aspect, z_near, z_far); m_projection.perspective(fov, aspect, z_near, z_far);
} }
//! \brief
QMatrix4x4 Camera::get_view_matrix() const QMatrix4x4 Camera::get_view_matrix() const {
{
QMatrix4x4 view; QMatrix4x4 view;
const QVector3D center = m_pos - m_uz; const QVector3D center = m_pos - m_uz;
view.lookAt(m_pos, center, m_uy); view.lookAt(m_pos, center, m_uy);
return view; return view;
} }
//! \brief
void Camera::rotate_from_init_config(float theta, float phi) void Camera::rotate_from_init_config(float theta, float phi) {
{
// TO-DO: use the following logic to eliminate the QT-deprecation warnings! // TO-DO: use the following logic to eliminate the QT-deprecation warnings!
//QMatrix4x4 rot; //QMatrix4x4 rot;
//rot.rotate(theta, m_ux); //rot.rotate(theta, m_ux);
@ -72,32 +69,32 @@ void Camera::rotate_from_init_config(float theta, float phi)
m_uz = r.map(QVector3D(0, 0, 1)); m_uz = r.map(QVector3D(0, 0, 1));
} }
void Camera::rotate(QMatrix4x4 rot) //! \brief
{ void Camera::rotate(QMatrix4x4 rot) {
m_pos = rot.map(m_pos); m_pos = rot.map(m_pos);
m_ux = rot.map(m_ux); m_ux = rot.map(m_ux);
m_uy = rot.map(m_uy); m_uy = rot.map(m_uy);
m_uz = rot.map(m_uz); m_uz = rot.map(m_uz);
} }
void Camera::save_config() //! \brief
{ void Camera::save_config() {
m_saved_pos = m_pos; m_saved_pos = m_pos;
m_saved_ux = m_ux; m_saved_ux = m_ux;
m_saved_uy = m_uy; m_saved_uy = m_uy;
m_saved_uz = m_uz; m_saved_uz = m_uz;
} }
void Camera::rotate_from_saved_config(QMatrix4x4 rot) //! \brief
{ void Camera::rotate_from_saved_config(QMatrix4x4 rot) {
m_pos = rot.map(m_saved_pos); m_pos = rot.map(m_saved_pos);
m_ux = rot.map(m_saved_ux); m_ux = rot.map(m_saved_ux);
m_uy = rot.map(m_saved_uy); m_uy = rot.map(m_saved_uy);
m_uz = rot.map(m_saved_uz); m_uz = rot.map(m_saved_uz);
} }
void Camera::move_forward(float distance) //! \brief
{ void Camera::move_forward(float distance) {
// recall that in OpenGL camera model, camera's z-axis points always // recall that in OpenGL camera model, camera's z-axis points always
// out of the screen (towards the user). // out of the screen (towards the user).
m_pos -= distance * m_uz; m_pos -= distance * m_uz;

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -10,15 +10,11 @@
#ifndef CAMERA_H #ifndef CAMERA_H
#define CAMERA_H #define CAMERA_H
#include <qvector3d.h> #include <qvector3d.h>
#include <qmatrix4x4.h> #include <qmatrix4x4.h>
class Camera {
class Camera
{
public: public:
Camera(); Camera();
void set_pos(const QVector3D& pos) { m_pos = pos; } void set_pos(const QVector3D& pos) { m_pos = pos; }
@ -59,5 +55,4 @@ private:
QMatrix4x4 m_projection; QMatrix4x4 m_projection;
}; };
#endif #endif

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University(Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -9,8 +9,4 @@
#include "Camera_manip.h" #include "Camera_manip.h"
Camera_manip::Camera_manip(Camera& camera) : m_camera(camera) {}
Camera_manip::Camera_manip(Camera& camera) :
m_camera(camera)
{
}

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -16,9 +16,7 @@
#include "Camera.h" #include "Camera.h"
#include "GUI_event_handler.h" #include "GUI_event_handler.h"
class Camera_manip : public GUI_event_handler {
class Camera_manip : public GUI_event_handler
{
public: public:
Camera_manip(Camera& camera); Camera_manip(Camera& camera);

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -9,20 +9,13 @@
#include "Camera_manip_rot.h" #include "Camera_manip_rot.h"
Camera_manip_rot::Camera_manip_rot(Camera& camera) : Camera_manip(camera) {}
Camera_manip_rot::Camera_manip_rot(Camera& camera) : void Camera_manip_rot::mouse_move_event(QMouseEvent* e) {
Camera_manip(camera) if (m_left_mouse_button_down) {
{
}
void Camera_manip_rot::mouse_move_event(QMouseEvent* e)
{
if (m_left_mouse_button_down)
{
const float rotation_scale_factor = 0.1f; const float rotation_scale_factor = 0.1f;
m_theta += rotation_scale_factor * m_diff.x(); m_theta += rotation_scale_factor * m_diff.x();
m_phi += rotation_scale_factor * m_diff.y(); m_phi += rotation_scale_factor * m_diff.y();
m_camera.rotate_from_init_config(-m_theta, -m_phi); m_camera.rotate_from_init_config(-m_theta, -m_phi);
} }
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -15,9 +15,7 @@
#include "Camera_manip.h" #include "Camera_manip.h"
class Camera_manip_rot : public Camera_manip {
class Camera_manip_rot : public Camera_manip
{
public: public:
Camera_manip_rot(Camera& camera); Camera_manip_rot(Camera& camera);
@ -25,7 +23,8 @@ protected:
virtual void mouse_move_event(QMouseEvent* e) override; virtual void mouse_move_event(QMouseEvent* e) override;
private: private:
float m_theta = 0, m_phi = 0; float m_theta = 0;
float m_phi = 0;
}; };
#endif #endif

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -9,22 +9,19 @@
#include "Camera_manip_rot_bpa.h" #include "Camera_manip_rot_bpa.h"
//! \brief
Camera_manip_rot_bpa::Camera_manip_rot_bpa(Camera& camera) : Camera_manip_rot_bpa::Camera_manip_rot_bpa(Camera& camera) :
Camera_manip(camera) Camera_manip(camera)
{ {}
//! \brief
void Camera_manip_rot_bpa::mouse_press_event(QMouseEvent* e) {
// for the backprojected diff-vector method:
if (m_left_mouse_button_down) m_camera.save_config();
} }
void Camera_manip_rot_bpa::mouse_press_event(QMouseEvent* e) //! \brief
{ void Camera_manip_rot_bpa::mouse_move_event(QMouseEvent* e) {
// for the backprojected diff-vector method:
if (m_left_mouse_button_down)
{
m_camera.save_config();
}
}
void Camera_manip_rot_bpa::mouse_move_event(QMouseEvent* e)
{
const float rotation_scale_factor = 0.1f; const float rotation_scale_factor = 0.1f;
// ROTATION AROUND AN AXIS ORTHOGONAL TO THE BACKPROJECTED DIF-VECTOR // ROTATION AROUND AN AXIS ORTHOGONAL TO THE BACKPROJECTED DIF-VECTOR
@ -52,14 +49,13 @@ void Camera_manip_rot_bpa::mouse_move_event(QMouseEvent* e)
rot_matrix.rotate(-rot_angle, rot_axis); rot_matrix.rotate(-rot_angle, rot_axis);
m_camera.rotate_from_saved_config(rot_matrix); m_camera.rotate_from_saved_config(rot_matrix);
}
} //! \brief
void Camera_manip_rot_bpa::mouse_release_event(QMouseEvent* e) void Camera_manip_rot_bpa::mouse_release_event(QMouseEvent* e) {}
{
} //! \brief
void Camera_manip_rot_bpa::resize(int w, int h) void Camera_manip_rot_bpa::resize(int w, int h) {
{
m_vp_width = w; m_vp_width = w;
m_vp_height = h; m_vp_height = h;
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -15,9 +15,7 @@
#include "Camera_manip.h" #include "Camera_manip.h"
class Camera_manip_rot_bpa : public Camera_manip {
class Camera_manip_rot_bpa : public Camera_manip
{
public: public:
Camera_manip_rot_bpa(Camera& camera); Camera_manip_rot_bpa(Camera& camera);

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -11,26 +11,19 @@
#include "Message_manager.h" #include "Message_manager.h"
Camera_manip_zoom::Camera_manip_zoom(Camera& camera) : Camera_manip(camera) {}
Camera_manip_zoom::Camera_manip_zoom(Camera& camera) : //! \brief
Camera_manip(camera) void Camera_manip_zoom::mouse_move_event(QMouseEvent* e) {
{ if (m_middle_mouse_button_down) {
}
void Camera_manip_zoom::mouse_move_event(QMouseEvent* e)
{
if (m_middle_mouse_button_down)
{
const float zoom_scale_factor = 0.01f; const float zoom_scale_factor = 0.01f;
const auto distance = zoom_scale_factor * m_diff.y(); const auto distance = zoom_scale_factor * m_diff.y();
m_camera.move_forward(distance); m_camera.move_forward(distance);
} }
} }
void Camera_manip_zoom::mouse_release_event(QMouseEvent* e)
{ //! \brief
void Camera_manip_zoom::mouse_release_event(QMouseEvent* e) {
if (e->button() == Qt::MiddleButton) if (e->button() == Qt::MiddleButton)
{
Message_manager::notify_all("zoom_changed"); Message_manager::notify_all("zoom_changed");
} }
}

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -15,17 +15,13 @@
#include "Camera_manip.h" #include "Camera_manip.h"
class Camera_manip_zoom : public Camera_manip {
class Camera_manip_zoom : public Camera_manip
{
public: public:
Camera_manip_zoom(Camera& camera); Camera_manip_zoom(Camera& camera);
protected: protected:
virtual void mouse_move_event(QMouseEvent* e) override; virtual void mouse_move_event(QMouseEvent* e) override;
virtual void mouse_release_event(QMouseEvent* e) override; virtual void mouse_release_event(QMouseEvent* e) override;
private:
}; };
#endif #endif

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -10,14 +10,9 @@
#ifndef COMMON_DEFS_H #ifndef COMMON_DEFS_H
#define COMMON_DEFS_H #define COMMON_DEFS_H
#include <qopenglfunctions_3_3_core.h> #include <qopenglfunctions_3_3_core.h>
//#include <qopenglfunctions_4_5_core.h> //#include <qopenglfunctions_4_5_core.h>
using OpenGLFunctionsBase = QOpenGLFunctions_3_3_Core; using OpenGLFunctionsBase = QOpenGLFunctions_3_3_Core;
#endif #endif

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -11,19 +11,16 @@
//#include <qvector3d.h> //#include <qvector3d.h>
//! \brief
GUI_country_pick_handler::GUI_country_pick_handler(Main_widget& main_widget) : GUI_country_pick_handler::GUI_country_pick_handler(Main_widget& main_widget) :
m_main_widget(main_widget), m_main_widget(main_widget),
m_camera(main_widget.get_camera()) m_camera(main_widget.get_camera())
{ {}
} //! \brief
void GUI_country_pick_handler::mouse_press_event(QMouseEvent* e) {
void GUI_country_pick_handler::mouse_press_event(QMouseEvent* e)
{
// handle country selection // handle country selection
if (e->button() == Qt::RightButton) if (e->button() == Qt::RightButton) {
{
auto p = e->pos(); auto p = e->pos();
QVector3D sp0(p.x(), m_vp_height - p.y(), 0); QVector3D sp0(p.x(), m_vp_height - p.y(), 0);
QVector3D sp1(p.x(), m_vp_height - p.y(), 1); QVector3D sp1(p.x(), m_vp_height - p.y(), 1);
@ -51,30 +48,23 @@ void GUI_country_pick_handler::mouse_press_event(QMouseEvent* e)
auto d = b * b - 4 * a * c; auto d = b * b - 4 * a * c;
float ti = -1; float ti = -1;
if (abs(d) < std::numeric_limits<float>::epsilon()) if (abs(d) < std::numeric_limits<float>::epsilon()) {
{
// single intersection // single intersection
ti = -b / (2 * a); ti = -b / (2 * a);
} }
else else {
{ if (d < 0) {
if (d < 0)
{
// no intersection // no intersection
return; return;
} }
else else {
{
// two intersections // two intersections
auto sd = sqrt(d); auto sd = sqrt(d);
auto t1 = (-b - sd) / (2 * a); auto t1 = (-b - sd) / (2 * a);
auto t2 = (-b + sd) / (2 * a); auto t2 = (-b + sd) / (2 * a);
if (t1 > 0 && t2 > 0) if (t1 > 0 && t2 > 0) ti = std::min(t1, t2);
ti = std::min(t1, t2); else if (t1 > 0) ti = t1;
else if (t1 > 0) else ti = t2;
ti = t1;
else
ti = t2;
} }
} }
@ -110,8 +100,9 @@ void GUI_country_pick_handler::mouse_press_event(QMouseEvent* e)
// prev_picked_country = picked_country; // prev_picked_country = picked_country;
} }
} }
void GUI_country_pick_handler::resize(int w, int h)
{ //! \brief
void GUI_country_pick_handler::resize(int w, int h) {
m_vp_width = w; m_vp_width = w;
m_vp_height = h; m_vp_height = h;
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -16,9 +16,7 @@
#include "GUI_event_handler.h" #include "GUI_event_handler.h"
#include "Main_widget.h" #include "Main_widget.h"
class GUI_country_pick_handler : public GUI_event_handler {
class GUI_country_pick_handler : public GUI_event_handler
{
public: public:
GUI_country_pick_handler(Main_widget& main_widget); GUI_country_pick_handler(Main_widget& main_widget);
@ -28,7 +26,8 @@ protected:
Main_widget& m_main_widget; Main_widget& m_main_widget;
Camera& m_camera; Camera& m_camera;
int m_vp_width, m_vp_height; int m_vp_width;
int m_vp_height;
}; };

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -9,11 +9,10 @@
#include "GUI_event_handler.h" #include "GUI_event_handler.h"
//! \brief
void GUI_event_handler::set_mouse_button_pressed_flag(QMouseEvent* e, bool flag) void
{ GUI_event_handler::set_mouse_button_pressed_flag(QMouseEvent* e, bool flag) {
switch (e->button()) switch (e->button()) {
{
case Qt::LeftButton: case Qt::LeftButton:
m_left_mouse_button_down = flag; m_left_mouse_button_down = flag;
break; break;
@ -23,16 +22,18 @@ void GUI_event_handler::set_mouse_button_pressed_flag(QMouseEvent* e, bool flag)
break; break;
} }
} }
void GUI_event_handler::mousePressEvent(QMouseEvent* e)
{ //! \brief
void GUI_event_handler::mousePressEvent(QMouseEvent* e) {
set_mouse_button_pressed_flag(e, true); set_mouse_button_pressed_flag(e, true);
m_mouse_press_pos = m_last_mouse_pos = QVector2D(e->position()); m_mouse_press_pos = m_last_mouse_pos = QVector2D(e->position());
// call the function overridden by the derived class // call the function overridden by the derived class
mouse_press_event(e); mouse_press_event(e);
} }
void GUI_event_handler::mouseMoveEvent(QMouseEvent* e)
{ //! \brief
void GUI_event_handler::mouseMoveEvent(QMouseEvent* e) {
m_current_mouse_pos = QVector2D(e->position()); m_current_mouse_pos = QVector2D(e->position());
m_diff = m_current_mouse_pos - m_last_mouse_pos; m_diff = m_current_mouse_pos - m_last_mouse_pos;
@ -41,15 +42,14 @@ void GUI_event_handler::mouseMoveEvent(QMouseEvent* e)
m_last_mouse_pos = m_current_mouse_pos; m_last_mouse_pos = m_current_mouse_pos;
} }
void GUI_event_handler::mouseReleaseEvent(QMouseEvent* e)
{ //! \brief
void GUI_event_handler::mouseReleaseEvent(QMouseEvent* e) {
set_mouse_button_pressed_flag(e, false); set_mouse_button_pressed_flag(e, false);
// call the function overridden by the derived class // call the function overridden by the derived class
mouse_release_event(e); mouse_release_event(e);
} }
void GUI_event_handler::resizeGL(int w, int h)
{
resize(w, h);
}
//! \brief
void GUI_event_handler::resizeGL(int w, int h) { resize(w, h); }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -13,9 +13,7 @@
#include <qevent.h> #include <qevent.h>
#include <qvector2d.h> #include <qvector2d.h>
class GUI_event_handler {
class GUI_event_handler
{
public: public:
virtual ~GUI_event_handler() {}; virtual ~GUI_event_handler() {};
@ -32,7 +30,6 @@ protected:
virtual void mouse_release_event(QMouseEvent* e) {} virtual void mouse_release_event(QMouseEvent* e) {}
virtual void resize(int w, int h) {} virtual void resize(int w, int h) {}
bool m_left_mouse_button_down = false; bool m_left_mouse_button_down = false;
bool m_middle_mouse_button_down = false; bool m_middle_mouse_button_down = false;
QVector2D m_current_mouse_pos; QVector2D m_current_mouse_pos;

View File

@ -1,5 +1,11 @@
// Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
#include "Geodesic_arcs.h" // All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
@ -15,7 +21,7 @@
#include <CGAL/Vector_3.h> #include <CGAL/Vector_3.h>
#include "arr_print.h" #include "arr_print.h"
#include "Geodesic_arcs.h"
using Kernel = CGAL::Exact_predicates_exact_constructions_kernel; using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
using Geom_traits = CGAL::Arr_geodesic_arc_on_sphere_traits_2<Kernel>; using Geom_traits = CGAL::Arr_geodesic_arc_on_sphere_traits_2<Kernel>;
@ -24,17 +30,14 @@ using Curve = Geom_traits::Curve_2;
using Topol_traits = CGAL::Arr_spherical_topology_traits_2<Geom_traits>; using Topol_traits = CGAL::Arr_spherical_topology_traits_2<Geom_traits>;
using Arrangement = CGAL::Arrangement_on_surface_2<Geom_traits, Topol_traits>; using Arrangement = CGAL::Arrangement_on_surface_2<Geom_traits, Topol_traits>;
using Dir3 = Kernel::Direction_3; using Dir3 = Kernel::Direction_3;
std::ostream& operator << (std::ostream& os, const Dir3& d) std::ostream& operator << (std::ostream& os, const Dir3& d) {
{
os << d.dx() << ", " << d.dy() << ", " << d.dz(); os << d.dx() << ", " << d.dy() << ", " << d.dz();
return os; return os;
} }
using Approximate_point_2 = Geom_traits::Approximate_point_2; using Approximate_point_2 = Geom_traits::Approximate_point_2;
std::ostream& operator << (std::ostream& os, const Approximate_point_2& d) std::ostream& operator << (std::ostream& os, const Approximate_point_2& d) {
{
os << d.dx() << ", " << d.dy() << ", " << d.dz(); os << d.dx() << ", " << d.dy() << ", " << d.dz();
return os; return os;
} }
@ -45,17 +48,13 @@ using Approximate_Vector_3 = CGAL::Vector_3<Approximate_kernel>;
using Approximate_Direction_3 = Approximate_kernel::Direction_3; using Approximate_Direction_3 = Approximate_kernel::Direction_3;
using Direction_3 = Kernel::Direction_3; using Direction_3 = Kernel::Direction_3;
std::ostream& operator << (std::ostream& os, const Approximate_Vector_3& v) {
std::ostream& operator << (std::ostream& os, const Approximate_Vector_3& v)
{
os << v.x() << ", " << v.y() << ", " << v.z(); os << v.x() << ", " << v.y() << ", " << v.z();
//os << v.hx() << ", " << v.hy() << ", " << v.hz() << ", " << v.hw(); //os << v.hx() << ", " << v.hy() << ", " << v.hz() << ", " << v.hw();
return os; return os;
} }
auto Geodesic_arcs::get_approx_arcs(double error) -> Approx_arcs {
Geodesic_arcs::Approx_arcs Geodesic_arcs::get_approx_arcs(double error)
{
// Construct the arrangement from 12 geodesic arcs. // Construct the arrangement from 12 geodesic arcs.
Geom_traits traits; Geom_traits traits;
Arrangement arr(&traits); Arrangement arr(&traits);
@ -63,7 +62,6 @@ Geodesic_arcs::Approx_arcs Geodesic_arcs::get_approx_arcs(double error)
auto ctr_p = traits.construct_point_2_object(); auto ctr_p = traits.construct_point_2_object();
auto ctr_cv = traits.construct_curve_2_object(); auto ctr_cv = traits.construct_curve_2_object();
std::vector<Curve> xcvs; std::vector<Curve> xcvs;
xcvs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, 1, 0))); xcvs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, 1, 0)));
xcvs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, 0, 1))); xcvs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, 0, 1)));
@ -73,16 +71,13 @@ Geodesic_arcs::Approx_arcs Geodesic_arcs::get_approx_arcs(double error)
auto approx = traits.approximate_2_object(); auto approx = traits.approximate_2_object();
std::vector<std::vector<QVector3D>> arcs; std::vector<std::vector<QVector3D>> arcs;
for (const auto& xcv : xcvs) for (const auto& xcv : xcvs) {
{
std::vector<Approximate_point_2> v; std::vector<Approximate_point_2> v;
auto oi2 = approx(xcv, error, std::back_insert_iterator(v)); auto oi2 = approx(xcv, error, std::back_insert_iterator(v));
std::vector<QVector3D> arc_points; std::vector<QVector3D> arc_points;
for (const auto& p : v) for (const auto& p : v) {
{
const QVector3D arc_point(p.dx(), p.dy(), p.dz()); const QVector3D arc_point(p.dx(), p.dy(), p.dz());
arc_points.push_back(arc_point); arc_points.push_back(arc_point);
} }
@ -93,17 +88,14 @@ Geodesic_arcs::Approx_arcs Geodesic_arcs::get_approx_arcs(double error)
return arcs; return arcs;
} }
auto Geodesic_arcs::get_approx_arcs(const Kml::Placemark&
Geodesic_arcs::Approx_arcs Geodesic_arcs::get_approx_arcs(const Kml::Placemark& placemark, double error) -> Approx_arcs {
placemark, double error)
{
Geom_traits traits; Geom_traits traits;
auto ctr_p = traits.construct_point_2_object(); auto ctr_p = traits.construct_point_2_object();
auto ctr_cv = traits.construct_curve_2_object(); auto ctr_cv = traits.construct_curve_2_object();
std::vector<Curve> xcvs; std::vector<Curve> xcvs;
for (const auto& polygon : placemark.polygons) for (const auto& polygon : placemark.polygons) {
{
// colect all rings into a single list (FOR NOW!!!) // colect all rings into a single list (FOR NOW!!!)
// TO-DO: PROCESS OUTER & INNER BOUNDARIES SEPARATELY!!! // TO-DO: PROCESS OUTER & INNER BOUNDARIES SEPARATELY!!!
Kml::LinearRings linear_rings; Kml::LinearRings linear_rings;
@ -113,11 +105,9 @@ Geodesic_arcs::Approx_arcs Geodesic_arcs::get_approx_arcs(const Kml::Placemark&
// convert the nodes to points on unit-sphere // convert the nodes to points on unit-sphere
for (const auto& lring : linear_rings) for (const auto& lring : linear_rings) {
{
std::vector<Approximate_Vector_3> sphere_points; std::vector<Approximate_Vector_3> sphere_points;
for (const auto& node : lring.nodes) for (const auto& node : lring.nodes) {
{
const auto p = node.get_coords_3d(); const auto p = node.get_coords_3d();
Approximate_Vector_3 v(p.x, p.y, p.z); Approximate_Vector_3 v(p.x, p.y, p.z);
sphere_points.push_back(v); sphere_points.push_back(v);
@ -125,8 +115,7 @@ Geodesic_arcs::Approx_arcs Geodesic_arcs::get_approx_arcs(const Kml::Placemark&
// add geodesic arcs for the current LinearRing // add geodesic arcs for the current LinearRing
int num_points = sphere_points.size(); int num_points = sphere_points.size();
for (int i = 0; i < num_points - 1; i++) for (int i = 0; i < num_points - 1; ++i) {
{
const auto p1 = sphere_points[i]; const auto p1 = sphere_points[i];
const auto p2 = sphere_points[i + 1]; const auto p2 = sphere_points[i + 1];
xcvs.push_back(ctr_cv(ctr_p(p1.x(), p1.y(), p1.z()), xcvs.push_back(ctr_cv(ctr_p(p1.x(), p1.y(), p1.z()),
@ -137,14 +126,12 @@ Geodesic_arcs::Approx_arcs Geodesic_arcs::get_approx_arcs(const Kml::Placemark&
auto approx = traits.approximate_2_object(); auto approx = traits.approximate_2_object();
std::vector<std::vector<QVector3D>> arcs; std::vector<std::vector<QVector3D>> arcs;
for (const auto& xcv : xcvs) for (const auto& xcv : xcvs) {
{
std::vector<Approximate_point_2> v; std::vector<Approximate_point_2> v;
auto oi2 = approx(xcv, error, std::back_insert_iterator(v)); auto oi2 = approx(xcv, error, std::back_insert_iterator(v));
std::vector<QVector3D> arc_points; std::vector<QVector3D> arc_points;
for (const auto& p : v) for (const auto& p : v) {
{
const QVector3D arc_point(p.dx(), p.dy(), p.dz()); const QVector3D arc_point(p.dx(), p.dy(), p.dz());
arc_points.push_back(arc_point); arc_points.push_back(arc_point);
} }

View File

@ -1,3 +1,11 @@
// Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
#ifndef GEODESIC_ARCS_H #ifndef GEODESIC_ARCS_H
#define GEODESIC_ARCS_H #define GEODESIC_ARCS_H
@ -7,13 +15,10 @@
#include "Kml_reader.h" #include "Kml_reader.h"
class Geodesic_arcs {
class Geodesic_arcs
{
public: public:
using Approx_arcs = std::vector<std::vector<QVector3D>>; using Approx_arcs = std::vector<std::vector<QVector3D>>;
Approx_arcs get_approx_arcs(double error); Approx_arcs get_approx_arcs(double error);
// generate approximate arcs from KML data // generate approximate arcs from KML data

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -17,20 +17,19 @@
#include <qfile.h> #include <qfile.h>
#include <qxmlstream.h> #include <qxmlstream.h>
//! \brief
double Kml::Node::distance_to(const Node& r) const double Kml::Node::distance_to(const Node& r) const {
{
const auto dx = lon - r.lon; const auto dx = lon - r.lon;
const auto dy = lat - r.lat; const auto dy = lat - r.lat;
return sqrt(dx * dx + dy * dy); return sqrt(dx * dx + dy * dy);
} }
//! \brief
bool Kml::Node::operator == (const Node& r) const bool Kml::Node::operator == (const Node& r) const
{ { return (lon == r.lon) && (lat == r.lat); }
return (lon == r.lon) && (lat == r.lat);
} //! \brief
Kml::Vec3d Kml::Node::get_coords_3d(const double r) const Kml::Vec3d Kml::Node::get_coords_3d(const double r) const {
{
const long double phi = qDegreesToRadians(lat); const long double phi = qDegreesToRadians(lat);
const long double theta = qDegreesToRadians(lon); const long double theta = qDegreesToRadians(lon);
const auto z = r * std::sin(phi); const auto z = r * std::sin(phi);
@ -40,71 +39,61 @@ Kml::Vec3d Kml::Node::get_coords_3d(const double r) const
return Vec3d{ (double)x, (double)y, (double)z }; return Vec3d{ (double)x, (double)y, (double)z };
} }
QVector3D Kml::Node::get_coords_3f(const double r) const
{ //! \brief
QVector3D Kml::Node::get_coords_3f(const double r) const {
const auto v = get_coords_3d(r); const auto v = get_coords_3d(r);
return QVector3D(v.x, v.y, v.z); return QVector3D(v.x, v.y, v.z);
} }
std::ostream& operator << (std::ostream& os, const Kml::Node& n)
{ //! \brief
std::ostream& operator << (std::ostream& os, const Kml::Node& n) {
os << n.lon << ", " << n.lat; os << n.lon << ", " << n.lat;
return os; return os;
} }
//! \brief
int Kml::get_number_of_polygons(Placemarks& placemarks) int Kml::get_number_of_polygons(Placemarks& placemarks) {
{
int total_number_of_polygons = 0; int total_number_of_polygons = 0;
for (auto& placemark : placemarks) for (auto& placemark : placemarks)
{
total_number_of_polygons += placemark.polygons.size(); total_number_of_polygons += placemark.polygons.size();
}
return total_number_of_polygons; return total_number_of_polygons;
} }
Kml::Placemarks Kml::read(const std::string& file_name) //! \brief
{ Kml::Placemarks Kml::read(const std::string& file_name) {
LinearRing lring; LinearRing lring;
Polygon polygon; Polygon polygon;
Placemark placemark; Placemark placemark;
Placemarks placemarks; Placemarks placemarks;
QFile file(file_name.c_str()); QFile file(file_name.c_str());
if (file.open(QIODevice::ReadOnly)) if (file.open(QIODevice::ReadOnly)) {
{
QXmlStreamReader xmlReader; QXmlStreamReader xmlReader;
xmlReader.setDevice(&file); xmlReader.setDevice(&file);
xmlReader.readNext(); xmlReader.readNext();
// Reading from the file // Reading from the file
while (!xmlReader.isEndDocument()) while (!xmlReader.isEndDocument()) {
{
QString name = xmlReader.name().toString(); QString name = xmlReader.name().toString();
if (xmlReader.isStartElement()) if (xmlReader.isStartElement()) {
{ if (name == "Placemark") {
if (name == "Placemark")
{
placemark = Placemark{}; placemark = Placemark{};
} }
else if (name == "Polygon") else if (name == "Polygon") {
{
polygon = Polygon{}; polygon = Polygon{};
} }
else if (name == "LinearRing") else if (name == "LinearRing") {
{
lring = LinearRing{}; lring = LinearRing{};
} }
else if (name == "coordinates") else if (name == "coordinates") {
{
xmlReader.readNext(); xmlReader.readNext();
auto str = xmlReader.text().toString(); auto str = xmlReader.text().toString();
auto node_strs = str.split(" "); auto node_strs = str.split(" ");
for (const auto& node_str : node_strs) for (const auto& node_str : node_strs) {
{ if (node_str.isEmpty()) continue;
if (node_str.isEmpty())
continue;
auto coord_strs = node_str.split(","); auto coord_strs = node_str.split(",");
const auto lon = coord_strs[0].toDouble(); const auto lon = coord_strs[0].toDouble();
@ -112,8 +101,7 @@ Kml::Placemarks Kml::read(const std::string& file_name)
lring.nodes.push_back(Node{ lon, lat }); lring.nodes.push_back(Node{ lon, lat });
} }
} }
else if (name == "SimpleData") else if (name == "SimpleData") {
{
auto attributes = xmlReader.attributes(); auto attributes = xmlReader.attributes();
auto attr_name = attributes[0].name().toString(); auto attr_name = attributes[0].name().toString();
auto attr_value = attributes[0].value().toString(); auto attr_value = attributes[0].value().toString();
@ -124,31 +112,25 @@ Kml::Placemarks Kml::read(const std::string& file_name)
} }
} }
} }
else if (xmlReader.isEndElement()) else if (xmlReader.isEndElement()) {
{
if (name == "Placemark") if (name == "Placemark")
{ {
placemarks.push_back(std::move(placemark)); placemarks.push_back(std::move(placemark));
} }
else if (name == "Polygon") else if (name == "Polygon") {
{
placemark.polygons.push_back(std::move(polygon)); placemark.polygons.push_back(std::move(polygon));
} }
else if (name == "outerBoundaryIs") else if (name == "outerBoundaryIs") {
{
polygon.outer_boundary = std::move(lring); polygon.outer_boundary = std::move(lring);
} }
else if (name == "innerBoundaryIs") else if (name == "innerBoundaryIs") {
{
polygon.inner_boundaries.push_back(std::move(lring)); polygon.inner_boundaries.push_back(std::move(lring));
} }
else if (name == "LinearRing") else if (name == "LinearRing") {
{
// LinearRing is moved to the correct locations via other tags above // LinearRing is moved to the correct locations via other tags above
assert(*lring.nodes.begin() == *(--lring.nodes.end())); assert(*lring.nodes.begin() == *(--lring.nodes.end()));
} }
else if (name == "coordinates") else if (name == "coordinates") {
{
// no need to do anything here: the coordinates are read above! // no need to do anything here: the coordinates are read above!
} }
} }
@ -156,8 +138,7 @@ Kml::Placemarks Kml::read(const std::string& file_name)
xmlReader.readNext(); xmlReader.readNext();
} }
if (xmlReader.hasError()) if (xmlReader.hasError()) {
{
std::cout << "XML error: " << xmlReader.errorString().data() << std::endl; std::cout << "XML error: " << xmlReader.errorString().data() << std::endl;
} }
} }
@ -165,15 +146,13 @@ Kml::Placemarks Kml::read(const std::string& file_name)
return placemarks; return placemarks;
} }
Kml::Nodes Kml::get_duplicates(const Placemarks& placemarks) //! \brief
{ Kml::Nodes Kml::get_duplicates(const Placemarks& placemarks) {
// collect all nodes into a single vector // collect all nodes into a single vector
int polygon_count = 0; int polygon_count = 0;
std::vector<Kml::Node> nodes; std::vector<Kml::Node> nodes;
for (const auto& pm : placemarks) for (const auto& pm : placemarks) {
{ for (const auto& polygon : pm.polygons) {
for (const auto& polygon : pm.polygons)
{
polygon_count++; polygon_count++;
Kml::LinearRings linear_rings; Kml::LinearRings linear_rings;
@ -181,10 +160,8 @@ Kml::Nodes Kml::get_duplicates(const Placemarks& placemarks)
for (const auto& inner_boundary : polygon.inner_boundaries) for (const auto& inner_boundary : polygon.inner_boundaries)
linear_rings.push_back(inner_boundary); linear_rings.push_back(inner_boundary);
for(const auto& lring : linear_rings) for(const auto& lring : linear_rings) {
{ for (const auto& node : lring.nodes) nodes.push_back(node);
for (const auto& node : lring.nodes)
nodes.push_back(node);
} }
} }
} }
@ -199,38 +176,30 @@ Kml::Nodes Kml::get_duplicates(const Placemarks& placemarks)
std::unordered_map<int, int> dup_count_map; std::unordered_map<int, int> dup_count_map;
Nodes duplicate_nodes; Nodes duplicate_nodes;
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i) {
{
// if the current node has been detected as duplicate skip it // if the current node has been detected as duplicate skip it
if (num_duplicates[i] > 0) if (num_duplicates[i] > 0)
continue; continue;
const auto& curr_node = nodes[i]; const auto& curr_node = nodes[i];
std::vector<int> curr_dup; // current set of duplicates std::vector<int> curr_dup; // current set of duplicates
for (int j = i + 1; j < count; ++j) for (int j = i + 1; j < count; ++j) {
{ if (curr_node == nodes[j]) curr_dup.push_back(j);
if (curr_node == nodes[j])
{
curr_dup.push_back(j);
}
} }
// if duplicates found // if duplicates found
if (!curr_dup.empty()) if (!curr_dup.empty()) {
{
dup_count++; dup_count++;
int num_dup = curr_dup.size() + 1; // +1 for the i'th node int num_dup = curr_dup.size() + 1; // +1 for the i'th node
num_duplicates[i] = num_dup; num_duplicates[i] = num_dup;
for (const auto di : curr_dup) for (const auto di : curr_dup) num_duplicates[di] = num_dup;
num_duplicates[di] = num_dup;
duplicate_nodes.push_back(curr_node); duplicate_nodes.push_back(curr_node);
dup_count_map[num_dup]++; dup_count_map[num_dup]++;
} }
} }
qDebug() << "dup count = " << dup_count; qDebug() << "dup count = " << dup_count;
for (const auto& p : dup_count_map) for (const auto& p : dup_count_map) {
{
const auto dup_count = p.first; const auto dup_count = p.first;
const auto num_nodes_with_this_dup_count = p.second; const auto num_nodes_with_this_dup_count = p.second;
qDebug() << dup_count << ": " << num_nodes_with_this_dup_count; qDebug() << dup_count << ": " << num_nodes_with_this_dup_count;
@ -239,16 +208,13 @@ Kml::Nodes Kml::get_duplicates(const Placemarks& placemarks)
return duplicate_nodes; return duplicate_nodes;
} }
//! \brief
Kml::Nodes Kml::generate_ids(Placemarks& placemarks) Kml::Nodes Kml::generate_ids(Placemarks& placemarks) {
{
// collect all nodes into a single vector // collect all nodes into a single vector
int polygon_count = 0; int polygon_count = 0;
std::vector<Node> nodes; std::vector<Node> nodes;
for (auto& pm : placemarks) for (auto& pm : placemarks) {
{ for (auto& polygon : pm.polygons) {
for (auto& polygon : pm.polygons)
{
polygon_count++; polygon_count++;
std::vector<LinearRing*> linear_rings; std::vector<LinearRing*> linear_rings;
@ -256,21 +222,17 @@ Kml::Nodes Kml::generate_ids(Placemarks& placemarks)
for (auto& inner_boundary : polygon.inner_boundaries) for (auto& inner_boundary : polygon.inner_boundaries)
linear_rings.push_back(&inner_boundary); linear_rings.push_back(&inner_boundary);
for (auto* lring : linear_rings) for (auto* lring : linear_rings) {
{ for (const auto& node : lring->nodes) {
for (const auto& node : lring->nodes)
{
// check if the node is in the nodes // check if the node is in the nodes
auto it = std::find(nodes.begin(), nodes.end(), node); auto it = std::find(nodes.begin(), nodes.end(), node);
if (nodes.end() == it) if (nodes.end() == it) {
{
// insert new node // insert new node
nodes.push_back(node); nodes.push_back(node);
const int node_id = nodes.size() - 1; const int node_id = nodes.size() - 1;
lring->ids.push_back(node_id); lring->ids.push_back(node_id);
} }
else else {
{
// get the existing node // get the existing node
const int node_id = std::distance(nodes.begin(), it); const int node_id = std::distance(nodes.begin(), it);
lring->ids.push_back(node_id); lring->ids.push_back(node_id);
@ -280,26 +242,21 @@ Kml::Nodes Kml::generate_ids(Placemarks& placemarks)
assert(lring->nodes.size() == lring->ids.size()); assert(lring->nodes.size() == lring->ids.size());
for (int i = 0; i < lring->nodes.size(); ++i) for (int i = 0; i < lring->nodes.size(); ++i)
{
assert(lring->nodes[i] == nodes[lring->ids[i]]); assert(lring->nodes[i] == nodes[lring->ids[i]]);
} }
}
} }
} }
return nodes; return nodes;
} }
Kml::Nodes Kml::generate_ids_approx(Placemarks& placemarks, const double eps) //! \breif
{ Kml::Nodes Kml::generate_ids_approx(Placemarks& placemarks, const double eps) {
// collect all nodes into a single vector // collect all nodes into a single vector
int polygon_count = 0; int polygon_count = 0;
std::vector<Node> nodes; std::vector<Node> nodes;
for (auto& pm : placemarks) for (auto& pm : placemarks) {
{ for (auto& polygon : pm.polygons) {
for (auto& polygon : pm.polygons)
{
polygon_count++; polygon_count++;
std::vector<LinearRing*> linear_rings; std::vector<LinearRing*> linear_rings;
@ -307,34 +264,27 @@ Kml::Nodes Kml::generate_ids_approx(Placemarks& placemarks, const double eps)
for (auto& inner_boundary : polygon.inner_boundaries) for (auto& inner_boundary : polygon.inner_boundaries)
linear_rings.push_back(&inner_boundary); linear_rings.push_back(&inner_boundary);
for (auto* lring : linear_rings) for (auto* lring : linear_rings) {
{
lring->ids.clear(); lring->ids.clear();
for (const auto& node : lring->nodes) for (const auto& node : lring->nodes) {
{
// check if there is a node sufficiently close to the current one // check if there is a node sufficiently close to the current one
int node_index = -1; int node_index = -1;
for (int i = 0; i < nodes.size(); ++i) for (int i = 0; i < nodes.size(); ++i) {
{
const auto dist = node.distance_to(nodes[i]); const auto dist = node.distance_to(nodes[i]);
if (dist < eps) if (dist < eps) {
{
node_index = i; node_index = i;
break; break;
} }
} }
if (node_index < 0) {
if (node_index < 0)
{
// insert new node // insert new node
nodes.push_back(node); nodes.push_back(node);
const int node_id = nodes.size() - 1; const int node_id = nodes.size() - 1;
lring->ids.push_back(node_id); lring->ids.push_back(node_id);
} }
else else {
{
// get the existing node // get the existing node
const int node_id = node_index; const int node_id = node_index;
lring->ids.push_back(node_id); lring->ids.push_back(node_id);
@ -354,13 +304,10 @@ Kml::Nodes Kml::generate_ids_approx(Placemarks& placemarks, const double eps)
double min_dist = std::numeric_limits<double>::max(); double min_dist = std::numeric_limits<double>::max();
int ni1, ni2; int ni1, ni2;
int num_nodes = nodes.size(); int num_nodes = nodes.size();
for (int i = 0; i < num_nodes - 1; ++i) for (int i = 0; i < num_nodes - 1; ++i) {
{ for (int j = i + 1; j < num_nodes; ++j) {
for (int j = i + 1; j < num_nodes; ++j)
{
const auto dist = nodes[i].distance_to(nodes[j]); const auto dist = nodes[i].distance_to(nodes[j]);
if (min_dist > dist) if (min_dist > dist) {
{
min_dist = dist; min_dist = dist;
ni1 = i; ni1 = i;
ni2 = j; ni2 = j;
@ -376,16 +323,14 @@ Kml::Nodes Kml::generate_ids_approx(Placemarks& placemarks, const double eps)
return nodes; return nodes;
} }
//! \brief
Kml::Nodes Kml::Polygon::get_all_nodes() const Kml::Nodes Kml::Polygon::get_all_nodes() const {
{
Nodes all_nodes; Nodes all_nodes;
auto source_first = outer_boundary.nodes.begin(); auto source_first = outer_boundary.nodes.begin();
auto source_last = outer_boundary.nodes.end(); auto source_last = outer_boundary.nodes.end();
all_nodes.insert(all_nodes.begin(), source_first, source_last); all_nodes.insert(all_nodes.begin(), source_first, source_last);
for (const auto& inner_boundary : inner_boundaries) for (const auto& inner_boundary : inner_boundaries) {
{
auto source_first = inner_boundary.nodes.begin(); auto source_first = inner_boundary.nodes.begin();
auto source_last = inner_boundary.nodes.end(); auto source_last = inner_boundary.nodes.end();
all_nodes.insert(all_nodes.begin(), source_first, source_last); all_nodes.insert(all_nodes.begin(), source_first, source_last);
@ -393,8 +338,9 @@ Kml::Nodes Kml::Polygon::get_all_nodes() const
return all_nodes; return all_nodes;
} }
std::vector<Kml::LinearRing*> Kml::Polygon::get_all_boundaries()
{ //! \brief
std::vector<Kml::LinearRing*> Kml::Polygon::get_all_boundaries() {
std::vector<LinearRing*> linear_rings; std::vector<LinearRing*> linear_rings;
linear_rings.push_back(&outer_boundary); linear_rings.push_back(&outer_boundary);
for (auto& inner_boundary : inner_boundaries) for (auto& inner_boundary : inner_boundaries)
@ -403,11 +349,10 @@ std::vector<Kml::LinearRing*> Kml::Polygon::get_all_boundaries()
return linear_rings; return linear_rings;
} }
Kml::Nodes Kml::Placemark::get_all_nodes() const //! \brief
{ Kml::Nodes Kml::Placemark::get_all_nodes() const {
Nodes all_nodes; Nodes all_nodes;
for (const auto& polygon : polygons) for (const auto& polygon : polygons) {
{
auto polygon_nodes = polygon.get_all_nodes(); auto polygon_nodes = polygon.get_all_nodes();
auto first = std::make_move_iterator(polygon_nodes.begin()); auto first = std::make_move_iterator(polygon_nodes.begin());
auto last = std::make_move_iterator(polygon_nodes.end()); auto last = std::make_move_iterator(polygon_nodes.end());
@ -416,41 +361,39 @@ Kml::Nodes Kml::Placemark::get_all_nodes() const
return all_nodes; return all_nodes;
} }
int Kml::Placemark::get_all_nodes_count() const
{ //! \brief
int Kml::Placemark::get_all_nodes_count() const {
int num_nodes = 0; int num_nodes = 0;
for (const auto& polygon : polygons) for (const auto& polygon : polygons) {
{
auto polygon_nodes = polygon.get_all_nodes(); auto polygon_nodes = polygon.get_all_nodes();
num_nodes += polygon_nodes.size(); num_nodes += polygon_nodes.size();
} }
return num_nodes; return num_nodes;
} }
Kml::Arcs Kml::LinearRing::get_arcs() const //! \brief
{ Kml::Arcs Kml::LinearRing::get_arcs() const {
Arcs arcs; Arcs arcs;
const int num_nodes = nodes.size(); const int num_nodes = nodes.size();
for (int i = 0; i < num_nodes - 1; ++i) for (int i = 0; i < num_nodes - 1; ++i) {
{
const auto from = nodes[i]; const auto from = nodes[i];
const auto to = nodes[i + 1]; const auto to = nodes[i + 1];
arcs.push_back(Arc{ from, to }); arcs.push_back(Arc{ from, to });
} }
return arcs; return arcs;
} }
void Kml::LinearRing::get_arcs(Arcs& arcs) const
{ //! \brief
void Kml::LinearRing::get_arcs(Arcs& arcs) const {
auto a = get_arcs(); auto a = get_arcs();
arcs.insert(arcs.end(), a.begin(), a.end()); arcs.insert(arcs.end(), a.begin(), a.end());
} }
Kml::Arcs Kml::Placemark::get_all_arcs() const Kml::Arcs Kml::Placemark::get_all_arcs() const {
{
Arcs all_arcs; Arcs all_arcs;
for (const auto& polygon : polygons) for (const auto& polygon : polygons) {
{
polygon.outer_boundary.get_arcs(all_arcs); polygon.outer_boundary.get_arcs(all_arcs);
for (const auto& inner_boundary : polygon.inner_boundaries) for (const auto& inner_boundary : polygon.inner_boundaries)
inner_boundary.get_arcs(all_arcs); inner_boundary.get_arcs(all_arcs);
@ -458,4 +401,3 @@ Kml::Arcs Kml::Placemark::get_all_arcs() const
return all_arcs; return all_arcs;
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -16,24 +16,19 @@
#include <qvector3d.h> #include <qvector3d.h>
class Kml {
class Kml
{
public: public:
// double precision 3D-point (QVector3D has float coordinates) // double precision 3D-point (QVector3D has float coordinates)
struct Vec3d struct Vec3d {
{
double x, y, z; double x, y, z;
friend std::ostream& operator << (std::ostream& os, const Vec3d& v) friend std::ostream& operator << (std::ostream& os, const Vec3d& v) {
{
os << v.x << ", " << v.y << ", " << v.z; os << v.x << ", " << v.y << ", " << v.z;
return os; return os;
} }
}; };
struct Node struct Node {
{
double lon, lat; double lon, lat;
Node() : lon(-1111), lat(-1111) {}; Node() : lon(-1111), lat(-1111) {};
@ -48,14 +43,13 @@ public:
}; };
using Nodes = std::vector<Node>; using Nodes = std::vector<Node>;
struct Arc struct Arc {
{
Node from, to; Node from, to;
}; };
using Arcs = std::vector<Arc>; using Arcs = std::vector<Arc>;
struct LinearRing struct LinearRing {
{
std::vector<Node> nodes; std::vector<Node> nodes;
std::vector<int> ids; std::vector<int> ids;
@ -64,9 +58,7 @@ public:
}; };
using LinearRings = std::vector<LinearRing>; using LinearRings = std::vector<LinearRing>;
struct Polygon {
struct Polygon
{
LinearRing outer_boundary; LinearRing outer_boundary;
LinearRings inner_boundaries; LinearRings inner_boundaries;
@ -77,9 +69,7 @@ public:
std::vector<LinearRing*> get_all_boundaries(); std::vector<LinearRing*> get_all_boundaries();
}; };
struct Placemark {
struct Placemark
{
std::vector<Polygon> polygons; std::vector<Polygon> polygons;
std::string name; std::string name;
@ -89,11 +79,11 @@ public:
Arcs get_all_arcs() const; Arcs get_all_arcs() const;
}; };
using Placemarks = std::vector<Placemark>; using Placemarks = std::vector<Placemark>;
static int get_number_of_polygons(Placemarks& placemarks); static int get_number_of_polygons(Placemarks& placemarks);
static Placemarks read(const std::string& file_name); static Placemarks read(const std::string& file_name);
static Nodes get_duplicates(const Placemarks& placemarks); static Nodes get_duplicates(const Placemarks& placemarks);
@ -107,5 +97,4 @@ public:
static Nodes generate_ids_approx(Placemarks& placemarks, const double eps); static Nodes generate_ids_approx(Placemarks& placemarks, const double eps);
}; };
#endif #endif

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -7,13 +7,12 @@
// //
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com> // Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
#include "Line_strips.h"
#include <iostream> #include <iostream>
#include "Line_strips.h"
Line_strips::Line_strips(std::vector<QVector3D>& line_strip_points) //! \brief
{ Line_strips::Line_strips(std::vector<QVector3D>& line_strip_points) {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
std::vector<QVector3D> vertex_data; std::vector<QVector3D> vertex_data;
@ -24,7 +23,6 @@ Line_strips::Line_strips(std::vector<QVector3D>& line_strip_points)
const auto end_of_current_arc_points = vertex_data.size(); const auto end_of_current_arc_points = vertex_data.size();
m_offsets.push_back(end_of_current_arc_points); m_offsets.push_back(end_of_current_arc_points);
// DEFINE OPENGL BUFFERS // DEFINE OPENGL BUFFERS
glGenVertexArrays(1, &m_vao); glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
@ -34,19 +32,14 @@ Line_strips::Line_strips(std::vector<QVector3D>& line_strip_points)
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size(); auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size();
auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data()); auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data());
glBufferData(GL_ARRAY_BUFFER, glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
vertex_buffer_size,
vertex_buffer_data,
GL_STATIC_DRAW); GL_STATIC_DRAW);
// Position Vertex-Attribute // Position Vertex-Attribute
GLint position_attrib_index = 0; GLint position_attrib_index = 0;
const void* position_offset = 0; const void* position_offset = 0;
GLsizei stride = 0; GLsizei stride = 0;
glVertexAttribPointer(position_attrib_index, glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
3,
GL_FLOAT, GL_FALSE,
stride,
position_offset); position_offset);
glEnableVertexAttribArray(position_attrib_index); glEnableVertexAttribArray(position_attrib_index);
@ -54,27 +47,23 @@ Line_strips::Line_strips(std::vector<QVector3D>& line_strip_points)
glBindVertexArray(0); glBindVertexArray(0);
} }
Line_strips::Line_strips(std::vector<std::vector<QVector3D>>& arcs) //! \brief
{ Line_strips::Line_strips(std::vector<std::vector<QVector3D>>& arcs) {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
std::vector<QVector3D> vertex_data; std::vector<QVector3D> vertex_data;
m_offsets.push_back(0); m_offsets.push_back(0);
for (const auto& arc : arcs) for (const auto& arc : arcs) {
{ for(const auto& p : arc) vertex_data.push_back(p);
for(const auto& p : arc)
vertex_data.push_back(p);
const auto end_of_current_arc_points = vertex_data.size(); const auto end_of_current_arc_points = vertex_data.size();
m_offsets.push_back(end_of_current_arc_points); m_offsets.push_back(end_of_current_arc_points);
} }
// DEFINE OPENGL BUFFERS // DEFINE OPENGL BUFFERS
glGenVertexArrays(1, &m_vao); glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
// Vertex Buffer // Vertex Buffer
glGenBuffers(1, &m_vbo); glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
@ -89,10 +78,7 @@ Line_strips::Line_strips(std::vector<std::vector<QVector3D>>& arcs)
GLint position_attrib_index = 0; GLint position_attrib_index = 0;
const void* position_offset = 0; const void* position_offset = 0;
GLsizei stride = 0; GLsizei stride = 0;
glVertexAttribPointer(position_attrib_index, glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
3,
GL_FLOAT, GL_FALSE,
stride,
position_offset); position_offset);
glEnableVertexAttribArray(position_attrib_index); glEnableVertexAttribArray(position_attrib_index);
@ -100,13 +86,11 @@ Line_strips::Line_strips(std::vector<std::vector<QVector3D>>& arcs)
glBindVertexArray(0); glBindVertexArray(0);
} }
int Line_strips::get_num_line_strips() const //! \brief
{ int Line_strips::get_num_line_strips() const { return m_offsets.size() - 1; }
return m_offsets.size() - 1;
}
void Line_strips::draw(int line_strip_index) //! \brief
{ void Line_strips::draw(int line_strip_index) {
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
const auto first = m_offsets[line_strip_index]; const auto first = m_offsets[line_strip_index];
const auto count = m_offsets[line_strip_index + 1] - first; const auto count = m_offsets[line_strip_index + 1] - first;
@ -115,16 +99,13 @@ void Line_strips::draw(int line_strip_index)
} }
void Line_strips::draw() //! \brief
{ void Line_strips::draw() {
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
{ for (int i = 1; i < m_offsets.size(); i++) {
for (int i = 1; i < m_offsets.size(); i++)
{
const auto first = m_offsets[i - 1]; const auto first = m_offsets[i - 1];
const auto count = m_offsets[i] - first; const auto count = m_offsets[i] - first;
glDrawArrays(GL_LINE_STRIP, first, count); glDrawArrays(GL_LINE_STRIP, first, count);
} }
}
glBindVertexArray(0); glBindVertexArray(0);
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -14,9 +14,7 @@
#include <qvector3d.h> #include <qvector3d.h>
#include "Common_defs.h" #include "Common_defs.h"
class Line_strips : protected OpenGLFunctionsBase {
class Line_strips : protected OpenGLFunctionsBase
{
public: public:
Line_strips(std::vector<QVector3D>& line_strip_points); Line_strips(std::vector<QVector3D>& line_strip_points);
Line_strips(std::vector<std::vector<QVector3D>>& arcs); Line_strips(std::vector<std::vector<QVector3D>>& arcs);
@ -26,9 +24,9 @@ public:
void draw(); void draw();
private: private:
GLuint m_vao, m_vbo; GLuint m_vao;
GLuint m_vbo;
std::vector<GLuint> m_offsets; std::vector<GLuint> m_offsets;
}; };

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -23,35 +23,29 @@
#include "GUI_country_pick_handler.h" #include "GUI_country_pick_handler.h"
#include "Kml_reader.h" #include "Kml_reader.h"
#include "Message_manager.h" #include "Message_manager.h"
#include "Shapefile.h"
#include "Timer.h" #include "Timer.h"
#include "Tools.h" #include "Tools.h"
#include "Verification.h" #include "Verification.h"
//! \brief
Main_widget::Main_widget(const QString& file_name) : m_file_name(file_name) {}
//! \brief
Main_widget::Main_widget(const QString& file_name) : Main_widget::~Main_widget() {
m_file_name(file_name)
{
}
Main_widget::~Main_widget()
{
// Make sure the context is current when deleting the texture and the buffers. // Make sure the context is current when deleting the texture and the buffers.
makeCurrent(); makeCurrent();
doneCurrent(); doneCurrent();
} }
//! \brief
void Main_widget::set_mouse_pos(const QVector3D mouse_pos) void Main_widget::set_mouse_pos(const QVector3D mouse_pos)
{ { m_gr_mouse_vertex->set_pos(mouse_pos); }
m_gr_mouse_vertex->set_pos(mouse_pos);
} //! \brief
void Main_widget::hightlight_country(const std::string& country_name) void Main_widget::hightlight_country(const std::string& country_name) {
{
static std::string prev_picked_country; static std::string prev_picked_country;
if (!prev_picked_country.empty()) if (! prev_picked_country.empty()) {
{
// dim the previous country color // dim the previous country color
auto& prev_country = m_gr_country_triangles[prev_picked_country]; auto& prev_country = m_gr_country_triangles[prev_picked_country];
auto color = prev_country->get_color(); auto color = prev_country->get_color();
@ -60,8 +54,7 @@ void Main_widget::hightlight_country(const std::string& country_name)
prev_country->set_color(color); prev_country->set_color(color);
} }
if (!country_name.empty()) if (! country_name.empty()) {
{
// highlight the current country color // highlight the current country color
auto& curr_country = m_gr_country_triangles[country_name]; auto& curr_country = m_gr_country_triangles[country_name];
auto color = curr_country->get_color(); auto color = curr_country->get_color();
@ -73,42 +66,39 @@ void Main_widget::hightlight_country(const std::string& country_name)
prev_picked_country = country_name; prev_picked_country = country_name;
} }
void Main_widget::mousePressEvent(QMouseEvent* e)
{ //! \brief
void Main_widget::mousePressEvent(QMouseEvent* e) {
// forward the event to the camera manipulators // forward the event to the camera manipulators
m_camera_manip_rot->mousePressEvent(e); m_camera_manip_rot->mousePressEvent(e);
m_camera_manip_zoom->mousePressEvent(e); m_camera_manip_zoom->mousePressEvent(e);
m_pick_handler->mousePressEvent(e); m_pick_handler->mousePressEvent(e);
} }
void Main_widget::mouseMoveEvent(QMouseEvent* e)
{ //! \brief
void Main_widget::mouseMoveEvent(QMouseEvent* e) {
// forward the event to the camera manipulator // forward the event to the camera manipulator
m_camera_manip_rot->mouseMoveEvent(e); m_camera_manip_rot->mouseMoveEvent(e);
m_camera_manip_zoom->mouseMoveEvent(e); m_camera_manip_zoom->mouseMoveEvent(e);
m_pick_handler->mouseMoveEvent(e); m_pick_handler->mouseMoveEvent(e);
} }
void Main_widget::mouseReleaseEvent(QMouseEvent* e)
{ //! \brief
void Main_widget::mouseReleaseEvent(QMouseEvent* e) {
// forward the event to the camera manipulator // forward the event to the camera manipulator
m_camera_manip_rot->mouseReleaseEvent(e); m_camera_manip_rot->mouseReleaseEvent(e);
m_camera_manip_zoom->mouseReleaseEvent(e); m_camera_manip_zoom->mouseReleaseEvent(e);
m_pick_handler->mouseReleaseEvent(e); m_pick_handler->mouseReleaseEvent(e);
} }
void Main_widget::timerEvent(QTimerEvent*)
{
update();
}
//! \brief
void Main_widget::timerEvent(QTimerEvent*) { update(); }
void Main_widget::keyPressEvent(QKeyEvent* event) //! \brief
{ void Main_widget::keyPressEvent(QKeyEvent* event) {}
}
//! \brief
void Main_widget::initializeGL() {
void Main_widget::initializeGL()
{
m_pick_handler = std::make_unique<GUI_country_pick_handler>(*this); m_pick_handler = std::make_unique<GUI_country_pick_handler>(*this);
QVector3D initial_mouse_pos(0, -1, 0); QVector3D initial_mouse_pos(0, -1, 0);
@ -121,8 +111,7 @@ void Main_widget::initializeGL()
//m_arrh = Aos::load_arr("../../../Data/data/arrangements_3/sphere/ne_110m_admin_0_countries.json"); //m_arrh = Aos::load_arr("../../../Data/data/arrangements_3/sphere/ne_110m_admin_0_countries.json");
//m_arrh = Aos::load_arr("C:/work/gsoc2023/ne_110m_admin_0_countries.json"); //m_arrh = Aos::load_arr("C:/work/gsoc2023/ne_110m_admin_0_countries.json");
m_arrh = Aos::load_arr(m_file_name.toStdString()); m_arrh = Aos::load_arr(m_file_name.toStdString());
if (m_arrh == nullptr) if (m_arrh == nullptr) {
{
qDebug() << "FAILED TO LOAD THE ARRANGEMENT !!!"; qDebug() << "FAILED TO LOAD THE ARRANGEMENT !!!";
exit(1); exit(1);
} }
@ -136,8 +125,7 @@ void Main_widget::initializeGL()
//qDebug() << "color map size = " << color_map.size(); //qDebug() << "color map size = " << color_map.size();
qDebug() << "num countries = " << country_triangles_map.size(); qDebug() << "num countries = " << country_triangles_map.size();
auto rndm = [] {return rand() / double(RAND_MAX); }; auto rndm = [] {return rand() / double(RAND_MAX); };
for (auto& [country_name, triangle_points] : country_triangles_map) for (auto& [country_name, triangle_points] : country_triangles_map) {
{
auto country_triangles = std::make_unique<Triangles>(triangle_points); auto country_triangles = std::make_unique<Triangles>(triangle_points);
auto color = QVector4D(rndm(), rndm(), rndm(), 1); auto color = QVector4D(rndm(), rndm(), rndm(), 1);
auto m = std::max(color.x(), std::max(color.y(), color.z())); auto m = std::max(color.x(), std::max(color.y(), color.z()));
@ -153,7 +141,6 @@ void Main_widget::initializeGL()
//m_gr_all_triangles = std::make_unique<Triangles>(triangle_points); //m_gr_all_triangles = std::make_unique<Triangles>(triangle_points);
} }
initializeOpenGLFunctions(); initializeOpenGLFunctions();
init_camera(); init_camera();
@ -171,9 +158,8 @@ void Main_widget::initializeGL()
m_timer.start(12, this); m_timer.start(12, this);
} }
//! \brief
void Main_widget::init_camera() void Main_widget::init_camera() {
{
m_camera.set_pos(0, 0, 3); m_camera.set_pos(0, 0, 3);
m_camera_manip_rot = std::make_unique<Camera_manip_rot>(m_camera); m_camera_manip_rot = std::make_unique<Camera_manip_rot>(m_camera);
//m_camera_manip_rot = std::make_unique<Camera_manip_rot_bpa>(m_camera); //m_camera_manip_rot = std::make_unique<Camera_manip_rot_bpa>(m_camera);
@ -183,8 +169,8 @@ void Main_widget::init_camera()
m_model.rotate(-90, 1, 0, 0); m_model.rotate(-90, 1, 0, 0);
// register the zoom-changed function // register the zoom-changed function
Message_manager::add("zoom_changed", [&] Message_manager::add("zoom_changed",
{ [&] {
qDebug() << "ZOOM CHANGED!!!"; qDebug() << "ZOOM CHANGED!!!";
//const auto error = compute_backprojected_error(0.5); //const auto error = compute_backprojected_error(0.5);
//qDebug() << "new error = " << error; //qDebug() << "new error = " << error;
@ -193,8 +179,9 @@ void Main_widget::init_camera()
//init_country_borders(error); //init_country_borders(error);
}); });
} }
void Main_widget::init_geometry()
{ //! \brief
void Main_widget::init_geometry() {
// SPHERE // SPHERE
int num_slices, num_stacks; int num_slices, num_stacks;
num_slices = num_stacks = 64; num_slices = num_stacks = 64;
@ -211,16 +198,17 @@ void Main_widget::init_geometry()
const float axes_length = 2; const float axes_length = 2;
m_gr_world_coord_axes = std::make_unique<World_coord_axes>(axes_length); m_gr_world_coord_axes = std::make_unique<World_coord_axes>(axes_length);
} }
void Main_widget::init_shader_programs()
{ //! \brief
void Main_widget::init_shader_programs() {
Shader_program::set_shader_path("shaders/"); Shader_program::set_shader_path("shaders/");
m_sp_smooth.init_with_vs_fs("smooth");; m_sp_smooth.init_with_vs_fs("smooth");;
m_sp_per_vertex_color.init_with_vs_fs("per_vertex_color"); m_sp_per_vertex_color.init_with_vs_fs("per_vertex_color");
m_sp_arc.init_with_vs_fs("arc"); m_sp_arc.init_with_vs_fs("arc");
} }
void Main_widget::init_country_borders(float error) //! \brief
{ void Main_widget::init_country_borders(float error) {
// this part does the same as the code below but using arrangement! // this part does the same as the code below but using arrangement!
// NOTE: the old code interferes with some logic (NEEDS REFACTORING!!!) // NOTE: the old code interferes with some logic (NEEDS REFACTORING!!!)
m_gr_all_country_borders.reset(nullptr); m_gr_all_country_borders.reset(nullptr);
@ -229,9 +217,8 @@ void Main_widget::init_country_borders(float error)
m_gr_all_country_borders = std::make_unique<Line_strips>(all_approx_arcs); m_gr_all_country_borders = std::make_unique<Line_strips>(all_approx_arcs);
} }
//! \brief
float Main_widget::compute_backprojected_error(float pixel_error) float Main_widget::compute_backprojected_error(float pixel_error) {
{
// compute the back-projected error // compute the back-projected error
QRect vp(0, 0, m_vp_width, m_vp_height); QRect vp(0, 0, m_vp_width, m_vp_height);
auto proj = m_camera.get_projection_matrix(); auto proj = m_camera.get_projection_matrix();
@ -254,9 +241,8 @@ float Main_widget::compute_backprojected_error(float pixel_error)
return err; return err;
} }
//! \brief
void Main_widget::resizeGL(int w, int h) void Main_widget::resizeGL(int w, int h) {
{
m_camera_manip_rot->resizeGL(w, h); m_camera_manip_rot->resizeGL(w, h);
m_pick_handler->resizeGL(w, h); m_pick_handler->resizeGL(w, h);
@ -272,22 +258,17 @@ void Main_widget::resizeGL(int w, int h)
m_update_approx_error = true; m_update_approx_error = true;
} }
//! \brief
template<typename T> template<typename T>
void draw_safe(T& ptr) void draw_safe(T& ptr) { if (ptr) ptr->draw(); }
{
if (ptr)
ptr->draw();
}
void Main_widget::paintGL() //! \brief
{ void Main_widget::paintGL() {
if (m_update_approx_error) if (m_update_approx_error) {
{
const auto error = compute_backprojected_error(0.5); const auto error = compute_backprojected_error(0.5);
qDebug() << "new approx error = " << error; qDebug() << "new approx error = " << error;
qDebug() << "current error = " << m_current_approx_error; qDebug() << "current error = " << m_current_approx_error;
if(error < m_current_approx_error) if (error < m_current_approx_error) {
{
init_country_borders(error); init_country_borders(error);
m_current_approx_error = error; m_current_approx_error = error;
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -10,15 +10,15 @@
#ifndef MAIN_WIDGET_H #ifndef MAIN_WIDGET_H
#define MAIN_WIDGET_H #define MAIN_WIDGET_H
#include <functional>
#include <memory>
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <QMatrix4x4> #include <QMatrix4x4>
#include <QQuaternion> #include <QQuaternion>
#include <QVector2D> #include <QVector2D>
#include <QBasicTimer> #include <QBasicTimer>
#include <functional>
#include <memory>
#include <qopenglwidget.h> #include <qopenglwidget.h>
#include "Aos.h" #include "Aos.h"
@ -35,9 +35,7 @@
#include "Vertices.h" #include "Vertices.h"
#include "World_coordinate_axes.h" #include "World_coordinate_axes.h"
class Main_widget : public QOpenGLWidget, protected OpenGLFunctionsBase {
class Main_widget : public QOpenGLWidget, protected OpenGLFunctionsBase
{
Q_OBJECT Q_OBJECT
public: public:
@ -46,7 +44,6 @@ public:
Main_widget(const QString& file_name); Main_widget(const QString& file_name);
~Main_widget(); ~Main_widget();
auto& get_camera() { return m_camera; } auto& get_camera() { return m_camera; }
auto& get_model_matrix() { return m_model; } auto& get_model_matrix() { return m_model; }
auto& get_arr_handle() { return m_arrh; } auto& get_arr_handle() { return m_arrh; }
@ -73,7 +70,6 @@ protected:
void init_country_borders(float error); void init_country_borders(float error);
// This is called when the required approximation of the arcs is below the // This is called when the required approximation of the arcs is below the
// currently required one defined by the zoom level and window size. If you // currently required one defined by the zoom level and window size. If you
// zoom-in or increase the window-size this can be called. But once a minimum // zoom-in or increase the window-size this can be called. But once a minimum
@ -81,7 +77,6 @@ protected:
// SEE the definition of "m_current_approx_error" member variable below! // SEE the definition of "m_current_approx_error" member variable below!
float compute_backprojected_error(float pixel_error); float compute_backprojected_error(float pixel_error);
private: private:
// COUNTRY ARRANGEMENT SPECIFIC DATA // COUNTRY ARRANGEMENT SPECIFIC DATA
QString m_file_name; QString m_file_name;
@ -123,7 +118,8 @@ private:
QMatrix4x4 m_model; QMatrix4x4 m_model;
// view-port // view-port
int m_vp_width = 0, m_vp_height = 0; int m_vp_width = 0;
int m_vp_height = 0;
// After zooming in or making the viewport larger, the approximation-error // After zooming in or making the viewport larger, the approximation-error
// needs to be updated and checked against the old value. If a lower approxi- // needs to be updated and checked against the old value. If a lower approxi-

View File

@ -1,657 +0,0 @@
// Copyright(c) 2023 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
#include "Main_widget.h"
#include <cmath>
#include <iostream>
#include <string>
#include <QMouseEvent>
#include "Aos.h"
#include "Aos_triangulator.h"
#include "Camera_manip_rot.h"
#include "Camera_manip_rot_bpa.h"
#include "Camera_manip_zoom.h"
#include "Kml_reader.h"
#include "Message_manager.h"
#include "Shapefile.h"
#include "Timer.h"
#include "Tools.h"
#include "Verification.h"
namespace {
// used when dimming / highlighting selected countries
float s_dimming_factor = 0.4;
}
Main_widget::~Main_widget() {
// Make sure the context is current when deleting the texture and the buffers.
makeCurrent();
doneCurrent();
}
void Main_widget::handle_country_picking(QMouseEvent* e) {
//// handle country selection
//if (e->button() == Qt::RightButton)
//{
// auto p = e->pos();
// QVector3D sp0(p.x(), m_vp_height - p.y(), 0);
// QVector3D sp1(p.x(), m_vp_height - p.y(), 1);
// auto proj = m_camera.get_projection_matrix();
// auto view = m_camera.get_view_matrix();
// auto model_view = view * m_model;
// QRect viewport(0, 0, m_vp_width, m_vp_height);
// auto wp0 = sp0.unproject(model_view, proj, viewport);
// auto wp1 = sp1.unproject(model_view, proj, viewport);
// // ASSERTION!!!
// m_mouse_pos = wp0;
// // define a ray from the camera pos to the world-point
// //auto o = m_camera.get_pos();
// //auto u = wp - o;
// auto o = wp0;
// auto u = wp1 - wp0;
// // solve the quadratic equation to check for intersection of ray with sphere
// auto a = QVector3D::dotProduct(u, u);
// auto b = 2 * QVector3D::dotProduct(u, o);
// auto c = QVector3D::dotProduct(o, o) - 1;
// auto d = b * b - 4 * a * c;
// float ti = -1;
// if (abs(d) < std::numeric_limits<float>::epsilon())
// {
// // single intersection
// ti = -b / (2 * a);
// }
// else
// {
// if (d < 0)
// {
// // no intersection
// return;
// }
// else
// {
// // two intersections
// auto sd = sqrt(d);
// auto t1 = (-b - sd) / (2 * a);
// auto t2 = (-b + sd) / (2 * a);
// if (t1 > 0 && t2 > 0)
// ti = std::min(t1, t2);
// else if (t1 > 0)
// ti = t1;
// else
// ti = t2;
// }
// }
// m_mouse_pos = o + ti * u;
// static std::string prev_picked_country;
// auto picked_country = Aos::locate_country(m_arrh, m_mouse_pos);
// if (!prev_picked_country.empty())
// {
// // dim the previous country color
// auto& prev_country = m_country_triangles[prev_picked_country];
// auto color = prev_country->get_color();
// color *= s_dimming_factor;
// color.setW(1);
// prev_country->set_color(color);
// }
// if (!picked_country.empty())
// {
// // highlight the current country color
// auto& curr_country = m_country_triangles[picked_country];
// auto color = curr_country->get_color();
// color /= s_dimming_factor;
// color.setW(1);
// curr_country->set_color(color);
// qDebug() << "SELECTED COUNTRY: " << picked_country;
// }
// prev_picked_country = picked_country;
//}
}
void Main_widget::hightlight_country(const std::string& country_name) {
static std::string prev_picked_country;
if (!prev_picked_country.empty()) {
// dim the previous country color
auto& prev_country = m_country_triangles[prev_picked_country];
auto color = prev_country->get_color();
color *= s_dimming_factor;
color.setW(1);
prev_country->set_color(color);
}
if (! country_name.empty()) {
// highlight the current country color
auto& curr_country = m_country_triangles[country_name];
auto color = curr_country->get_color();
color /= s_dimming_factor;
color.setW(1);
curr_country->set_color(color);
qDebug() << "SELECTED COUNTRY: " << country_name;
}
prev_picked_country = country_name;
}
void Main_widget::mousePressEvent(QMouseEvent* e) {
// forward the event to the camera manipulators
m_camera_manip_rot->mousePressEvent(e);
m_camera_manip_zoom->mousePressEvent(e);
m_pick_handler->mousePressEvent(e);
//handle_country_picking(e);
}
void Main_widget::mouseMoveEvent(QMouseEvent* e) {
// forward the event to the camera manipulator
m_camera_manip_rot->mouseMoveEvent(e);
m_camera_manip_zoom->mouseMoveEvent(e);
m_pick_handler->mouseMoveEvent(e);
}
void Main_widget::mouseReleaseEvent(QMouseEvent* e) {
// forward the event to the camera manipulator
m_camera_manip_rot->mouseReleaseEvent(e);
m_camera_manip_zoom->mouseReleaseEvent(e);
m_pick_handler->mouseReleaseEvent(e);
}
void Main_widget::timerEvent(QTimerEvent*) { update(); }
void Main_widget::keyPressEvent(QKeyEvent* event) {
switch (event->key()) {
case Qt::Key_Q:
{
auto num_arcs =
m_country_borders[m_selected_country_index]->get_num_line_strips();
if (++m_selected_arc_index == num_arcs) m_selected_arc_index--;
qDebug() << "---------------------------------------";
qDebug() << "selected arc index = " << m_selected_arc_index;
const auto& arc = m_selected_country_arcs[m_selected_arc_index];
std::cout << arc.from << " TO " << arc.to << std::endl;
}
break;
case Qt::Key_A:
{
auto num_arcs =
m_country_borders[m_selected_country_index]->get_num_line_strips();
if (--m_selected_arc_index < 0) m_selected_arc_index = 0;
std::cout << "selected arc = " << m_selected_arc_index << std::endl;
}
break;
case Qt::Key_Up:
m_selected_country_index++;
if (m_selected_country_index == m_country_names.size())
m_selected_country_index--;
std::cout << m_selected_country_index << ": "
<< m_country_names[m_selected_country_index] << std::endl;
m_selected_arc_index = 0;
m_selected_country = &m_countries[m_selected_country_index];
m_selected_country_nodes = m_selected_country->get_all_nodes();
m_selected_country_arcs = m_selected_country->get_all_arcs();
{
auto num_arcs =
m_country_borders[m_selected_country_index]->get_num_line_strips();
qDebug() << "num KML arcs = " << m_selected_country_arcs.size();
qDebug() << "num arcs = " << num_arcs;
}
break;
case Qt::Key_Down:
m_selected_country_index--;
if (m_selected_country_index < 0) m_selected_country_index = 0;
std::cout << m_selected_country_index << ": "
<< m_country_names[m_selected_country_index] << std::endl;
m_selected_arc_index = 0;
m_selected_country = &m_countries[m_selected_country_index];
m_selected_country_nodes = m_selected_country->get_all_nodes();
break;
}
}
//!\brief
void Main_widget::init_problematic_nodes() {
Kml::Nodes prob_nodes = {
{23.8058134294668,8.66631887454253},
{24.1940677211877,8.7286964724039 },
{24.5673690121521,8.22918793378547},
{23.8869795808607,8.61972971293307}
};
std::vector<QVector3D> prob_vertices;
for (const auto& node : prob_nodes)
prob_vertices.push_back(node.get_coords_3f());
m_problematic_vertices = std::make_unique<Vertices>(prob_vertices);
}
#include "GUI_country_pick_handler.h"
void Main_widget::initializeGL() {
m_pick_handler = std::make_unique<GUI_country_pick_handler>(*this);
// verify that the node (180.0, -84.71338) in Antarctica is redundant
//Verification::verify_antarctica_node_is_redundant();
//init_problematic_nodes();
m_mouse_pos = QVector3D(0, -1, 0);
m_mouse_vertex = std::make_unique<SingleVertex>(m_mouse_pos);
std::string data_path = "C:/work/gsoc2023/data/";
//std::string shape_file_path = data_path + "ne_110m_admin_0_countries/";
//auto shape_file_name = shape_file_path + "ne_110m_admin_0_countries.shp";
//Shapefile::read(shape_file_name);
//const auto file_name = data_path + "world_countries.kml";
//const auto file_name = data_path + "ne_110m_admin_0_countries.kml";
//const auto file_name = data_path + "ne_110m_admin_0_countries_africa.kml";
const auto file_name = data_path + "ne_110m_admin_0_countries_equatorial_guinea.kml";
m_countries = Kml::read(file_name);
// find the country with the least number of nodes
if (0) {
std::string smallest;
int min_num_nodes = std::numeric_limits<int>::max();
for (auto& p : m_countries) {
int num_nodes = p.get_all_nodes_count();
if (min_num_nodes > num_nodes) {
min_num_nodes = num_nodes;
smallest = p.name;
}
qDebug() << p.name << " = " << p.get_all_nodes_count();
}
qDebug() << "smallest = " << smallest;
exit(0);
}
auto dup_nodes = Kml::get_duplicates(m_countries);
//auto all_nodes = Kml::generate_ids(m_countries);
qDebug() << "*** KML number of polygons = " <<
Kml::get_number_of_polygons(m_countries);
if(0)
{
auto created_faces = Aos::find_new_faces(m_countries);
m_new_faces = std::make_unique<Line_strips>(created_faces);
}
// SAVING ARR
if(0) {
std::string dest_path = "C:/work/gsoc2023/";
//std::string file_name = "ne_110m_admin_0_countries.json";
//std::string file_name = "ne_110m_admin_0_countries_africa_1.json";
std::string file_name = "ne_110m_admin_0_countries_equatorial_guinea.json";
auto full_path = dest_path + file_name;
Aos::save_arr(m_countries, full_path);
qDebug() << "done saving!";
exit(0);
}
// triangulation
{
qDebug() << "loading arr..";
//auto arrh = Aos::construct(m_countries);
m_arrh = Aos::load_arr("C:/work/gsoc2023/ne_110m_admin_0_countries.json");
if (m_arrh == nullptr) {
qDebug() << "** FAILED TO LOAD THE ARRANGEMENT!!!";
exit(1);
}
qDebug() << "generating triangles..";
//auto triangle_points = Aos::get_triangles(arrh);
//auto triangle_points = Aos_triangulator::get_all(arrh);
//auto country_triangles_map = Aos::get_triangles_by_country(m_arrh);
auto country_triangles_map = Aos_triangulator::get_by_country(m_arrh);
//auto color_map = Aos::get_color_mapping(m_arrh);
//qDebug() << "color map size = " << color_map.size();
qDebug() << "num countries = " << country_triangles_map.size();
auto rndm = [] {return rand() / double(RAND_MAX); };
//QVector4D colors[] = {
// QVector4D(1,0,0,1),
// QVector4D(0,1,0,1),
// QVector4D(0,0,1,1),
// QVector4D(1,1,0,1),
// QVector4D(1,0,1,1)
//};
for (auto& [country_name, triangle_points] : country_triangles_map) {
auto country_triangles = std::make_unique<Triangles>(triangle_points);
auto color = QVector4D(rndm(), rndm(), rndm(), 1);
auto m = std::max(color.x(), std::max(color.y(), color.z()));
color /= m;
color *= s_dimming_factor;
color.setW(1);
country_triangles->set_color(color);
//country_triangles->set_color(colors[color_map[country_name]]);
m_country_triangles.emplace(country_name, std::move(country_triangles));
}
//qDebug() << "num triangles = " << triangle_points.size() / 3;
//m_all_triangles = std::make_unique<Triangles>(triangle_points);
}
// initialize rendering of DUPLICATE VERTICES
if(0) {
qDebug() << "identifying duplicate nodes";
std::vector<QVector3D> vertices;
for (const auto& node : dup_nodes)
vertices.push_back(node.get_coords_3f());
m_vertices = std::make_unique<Vertices>(vertices);
}
if(0) {
// check the arrangement constructed from the GIS data-set
auto created_vertices = Aos::ext_check(m_countries);
//auto created_vertices = Aos::ext_check_id_based(m_countries);
m_vertices = std::make_unique<Vertices>(created_vertices);
}
initializeOpenGLFunctions();
init_camera();
init_geometry();
init_shader_programs();
m_current_approx_error = 0.001;
init_country_borders(m_current_approx_error);
init_country_selection();
glClearColor(0, 0, 0, 1);
glEnable(GL_DEPTH_TEST); // Enable depth buffer
//glEnable(GL_CULL_FACE); // Enable back face culling
// Use QBasicTimer because its faster than QTimer
m_timer.start(12, this);
}
void Main_widget::init_camera() {
m_camera.set_pos(0, 0, 3);
m_camera_manip_rot = std::make_unique<Camera_manip_rot>(m_camera);
//m_camera_manip_rot = std::make_unique<Camera_manip_rot_bpa>(m_camera);
m_camera_manip_zoom = std::make_unique<Camera_manip_zoom>(m_camera);
// this makes z-axes point upwards!
m_model.rotate(-90, 1, 0, 0);
// register the zoom-changed function
Message_manager::add("zoom_changed", [&]
{
qDebug() << "ZOOM CHANGED!!!";
//const auto error = compute_backprojected_error(0.5);
//qDebug() << "new error = " << error;
m_update_approx_error = true;
//qDebug() << "re-initializing the country borders..";
//init_country_borders(error);
});
}
void Main_widget::init_geometry() {
// SPHERE
int num_slices, num_stacks;
num_slices = num_stacks = 64;
float r = 1;
m_sphere = std::make_unique<Sphere>(num_slices, num_stacks, r);
const float c = 0.8;
m_sphere->set_color(c, c, c, 1);
// IDENTIFICATION CURVE
const double error = 0.001;
auto approx_ident_curve = Aos::get_approx_identification_curve(error);
m_identification_curve = std::make_unique<Line_strips>(approx_ident_curve);
const float axes_length = 2;
m_world_coord_axes = std::make_unique<World_coord_axes>(axes_length);
}
void Main_widget::init_shader_programs() {
Shader_program::set_shader_path("shaders/");
m_sp_smooth.init_with_vs_fs("smooth");;
m_sp_per_vertex_color.init_with_vs_fs("per_vertex_color");
m_sp_arc.init_with_vs_fs("arc");
}
void Main_widget::init_country_borders(float error) {
// this part does the same as the code below but using arrangement!
// NOTE: the old code interferes with some logic (NEEDS REFACTORING!!!)
{
m_country_borders.clear();
qDebug() << "approximating the arcs of each edge of all faces..";
auto all_approx_arcs = Aos::get_approx_arcs_from_faces_edges(m_arrh, error);
m_gr_all_approx_arcs = std::make_unique<Line_strips>(all_approx_arcs);
return;
}
// TO-DO: move this code to resizeGL (when viewport is initialized)
// has to be defined after camera has been defined:
// because we want to compute the error based on camera parameters!
//const double error = 0.001; // calculate this from cam parameters!
//auto lsa = Aos::get_approx_arcs(countries, error);
//auto lsa = Aos::get_approx_arcs(error);
//m_geodesic_arcs = std::make_unique<Line_strips>(lsa);
m_country_borders.clear();
for (const auto& country : m_countries) {
m_country_names.push_back(country.name);
auto approx_arcs = Aos::get_approx_arcs(country, error);
auto country_border = std::make_unique<Line_strips>(approx_arcs);
m_country_borders.push_back(std::move(country_border));
}
}
void Main_widget::init_country_selection() {
m_selected_country_index = 0;
//m_selected_country_index = 159; // ANTARCTICA
m_selected_country = &m_countries[m_selected_country_index];
m_selected_country_nodes = m_selected_country->get_all_nodes();
m_selected_country_arcs = m_selected_country->get_all_arcs();
m_selected_arc_index = 0;
}
float Main_widget::compute_backprojected_error(float pixel_error) {
// compute the back-projected error
QRect vp(0, 0, m_vp_width, m_vp_height);
auto proj = m_camera.get_projection_matrix();
auto view = m_camera.get_view_matrix();
QMatrix4x4 model;
auto model_view = view * model;
QVector3D p0(m_vp_width / 2, m_vp_height / 2, 0);
QVector3D p1(p0.x() + pixel_error, p0.y(), 0);
auto wp0 = p0.unproject(model_view, proj, vp);
auto wp1 = p1.unproject(model_view, proj, vp);
const float z_near = m_camera.get_z_near();
const float r = 1.f; // sphere radius
const QVector3D origin(0, 0, 0);
const float dist_to_cam = m_camera.get_pos().distanceToPoint(origin);
float d = dist_to_cam - r;
float err = wp0.distanceToPoint(wp1) * (d / z_near);
//find_minimum_projected_error_on_sphere(err);
return err;
}
void Main_widget::resizeGL(int w, int h) {
m_camera_manip_rot->resizeGL(w, h);
m_pick_handler->resizeGL(w, h);
m_vp_width = w;
m_vp_height = h;
// Reset projection
qreal aspect = qreal(w) / qreal(h ? h : 1);
const qreal z_near = 0.1, z_far = 100.0, fov = 45.0;
m_camera.perspective(fov, aspect, z_near, z_far);
// signal to look into the approximation error
m_update_approx_error = true;
}
template <typename T>
void draw_safe(T& ptr) {
if (ptr)
ptr->draw();
}
void Main_widget::paintGL() {
if (m_update_approx_error) {
const auto error = compute_backprojected_error(0.5);
qDebug() << "new approx error = " << error;
qDebug() << "current error = " << m_current_approx_error;
if(error < m_current_approx_error) {
init_country_borders(error);
m_current_approx_error = error;
}
m_update_approx_error = false;
}
const auto view = m_camera.get_view_matrix();
const auto projection = m_camera.get_projection_matrix();
const auto model_view = view * m_model;
const auto mvp = projection * model_view;
const auto normal_matrix = model_view.normalMatrix();
// compute the cutting plane
// remember that we are passing the local vertex positions of the sphere
// between the vertex and fragment shader stages, so we need to convert
// the camera-pos in world coords to sphere's local coords!
auto c = m_model.inverted() * m_camera.get_pos();
const auto d = c.length();
const auto r = 1.0f;
const auto sin_alpha = r / d;
const auto n = (c / d); // plane unit normal vector
const auto cos_beta = sin_alpha;
const auto p = (r * cos_beta) * n;
QVector4D plane(n.x(), n.y(), n.z(), -QVector3D::dotProduct(p, n));
// Clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// SPHERE
{
glEnable(GL_DEPTH_TEST);
auto& sp = m_sp_smooth;
sp.use();
sp.set_uniform("u_mvp", mvp);
sp.set_uniform("u_normal_matrix", normal_matrix);
auto sphere_color = QVector4D(167, 205, 242, 255) / 255;
sp.set_uniform("u_color", sphere_color);
sp.set_uniform("u_plane", QVector4D(0,0,0,0));
//sp.set_uniform("u_color", m_sphere->get_color());
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
m_sphere->draw();
// DRAW SOLID FACES
if(1)
{
glDisable(GL_DEPTH_TEST);
//auto face_color = QVector4D(241, 141, 0, 255) / 255;
//sp.set_uniform("u_color", face_color);
sp.set_uniform("u_plane", plane);
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//m_all_triangles->draw();
for (auto& [country_name, country] : m_country_triangles)
{
sp.set_uniform("u_color", country->get_color());
country->draw();
}
//sp.set_uniform("u_color", QVector4D(0,0,0,1));
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
//m_all_triangles->draw();
}
sp.unuse();
}
// WORLD COORDINATE AXES
{
auto& sp = m_sp_per_vertex_color;
sp.use();
sp.set_uniform("u_mvp", mvp);
glEnable(GL_DEPTH_TEST);
m_world_coord_axes->draw();
sp.unuse();
}
// VERTICES & GEODESIC ARCS
{
glDisable(GL_DEPTH_TEST);
auto& sp = m_sp_arc;
sp.use();
sp.set_uniform("u_mvp", mvp);
const QVector4D arc_color(0, 0.5, 1, 1);
glLineWidth(5);
sp.set_uniform("u_plane", plane);
// IDENTIFICATION CURVE
sp.set_uniform("u_color", QVector4D(0, 1, 1, 1));
m_identification_curve->draw(m_selected_arc_index);
// draw all countries
float a = 0.0;
sp.set_uniform("u_color", QVector4D(a, a, a, 1));
//for(auto& country_border : m_country_borders)
// country_border->draw();
m_gr_all_approx_arcs->draw();
//// draw the SELECTED COUNTRY in BLUE
//auto& selected_country = m_country_borders[m_selected_country_index];
//sp.set_uniform("u_color", QVector4D(0, .6, 1, 1));
//selected_country->draw();
//// draw the CURRENT ARC of the selected country in YELLOW
//sp.set_uniform("u_color", QVector4D(1, 1, 0, 1));
//selected_country->draw(m_selected_arc_index);
//const QVector4D vertex_color(1, 0, 0, 1);
//sp.set_uniform("u_color", vertex_color);
//glPointSize(3);
////m_vertices->draw();
//sp.set_uniform("u_color", QVector4D(0,1,0,1));
//glPointSize(2);
////m_problematic_vertices->draw();
//draw_safe(m_problematic_vertices);
//// NEW FACES in RED
//sp.set_uniform("u_color", QVector4D(1, 0, 0, 1));
////m_new_faces->draw();
// MOUSE VERTEX
{
glPointSize(5);
sp.set_uniform("u_color", QVector4D(1, 0, 0, 1));
//auto pos = m_mouse_vertex->get_pos();
//pos.setX(pos.x() + 0.01);
//m_mouse_vertex->set_pos(pos);
m_mouse_vertex->set_pos(m_mouse_pos);
draw_safe(m_mouse_vertex);
}
sp.unuse();
}
}

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -35,16 +35,13 @@
#include "Vertices.h" #include "Vertices.h"
#include "World_coordinate_axes.h" #include "World_coordinate_axes.h"
class Main_widget : public QOpenGLWidget, protected OpenGLFunctionsBase {
class Main_widget : public QOpenGLWidget, protected OpenGLFunctionsBase
{
Q_OBJECT Q_OBJECT
public: public:
using QOpenGLWidget::QOpenGLWidget; using QOpenGLWidget::QOpenGLWidget;
~Main_widget(); ~Main_widget();
auto& get_camera() { return m_camera; } auto& get_camera() { return m_camera; }
auto& get_model_matrix() { return m_model; } auto& get_model_matrix() { return m_model; }
auto& get_arr_handle() { return m_arrh; } auto& get_arr_handle() { return m_arrh; }
@ -114,7 +111,8 @@ private:
std::vector<std::unique_ptr<Line_strips>> m_country_borders; std::vector<std::unique_ptr<Line_strips>> m_country_borders;
// boundary-arcs by country // boundary-arcs by country
int m_selected_country_index, m_selected_arc_index; int m_selected_country_index;
int m_selected_arc_index;
Kml::Nodes m_selected_country_nodes; Kml::Nodes m_selected_country_nodes;
Kml::Arcs m_selected_country_arcs; Kml::Arcs m_selected_country_arcs;
Kml::Placemark* m_selected_country; Kml::Placemark* m_selected_country;
@ -123,7 +121,6 @@ private:
std::unique_ptr<Triangles> m_all_triangles; std::unique_ptr<Triangles> m_all_triangles;
std::map<std::string, std::unique_ptr<Triangles>> m_country_triangles; std::map<std::string, std::unique_ptr<Triangles>> m_country_triangles;
// Shaders // Shaders
Shader_program m_sp_smooth; Shader_program m_sp_smooth;
Shader_program m_sp_per_vertex_color; Shader_program m_sp_per_vertex_color;
@ -136,7 +133,8 @@ private:
QMatrix4x4 m_model; QMatrix4x4 m_model;
// view-port // view-port
int m_vp_width = 0, m_vp_height = 0; int m_vp_width = 0;
int m_vp_height = 0;
// After zooming in or making the viewport larger, the approximation-error // After zooming in or making the viewport larger, the approximation-error
// needs to be updated and checked against the old value. If a lower approxi- // needs to be updated and checked against the old value. If a lower approxi-

View File

@ -1,26 +1,16 @@
#include "Message_manager.h" #include "Message_manager.h"
std::map<std::string, Message_manager::Callbacks> std::map<std::string, Message_manager::Callbacks>
Message_manager::s_message_map; Message_manager::s_message_map;
void Message_manager::add(const std::string& msg_name, void Message_manager::add(const std::string& msg_name,
std::function<void()> callback) std::function<void()> callback)
{ { s_message_map[msg_name].push_back(callback); }
s_message_map[msg_name].push_back(callback);
}
void Message_manager::notify_all(const std::string& msg_name) void Message_manager::notify_all(const std::string& msg_name) {
{
auto it = s_message_map.find(msg_name); auto it = s_message_map.find(msg_name);
if (s_message_map.cend() != it) if (s_message_map.cend() != it) {
{
auto& callbacks = it->second; auto& callbacks = it->second;
for (auto& cb : callbacks) for (auto& cb : callbacks) cb();
cb();
} }
} }

View File

@ -1,3 +1,11 @@
// Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
#ifndef MESSAGE_MANAGER_H #ifndef MESSAGE_MANAGER_H
#define MESSAGE_MANAGER_H #define MESSAGE_MANAGER_H
@ -5,10 +13,9 @@
#include <functional> #include <functional>
#include <map> #include <map>
#include <string> #include <string>
#include <vector>
class Message_manager {
class Message_manager
{
public: public:
static void add(const std::string& msg_name, std::function<void()> callback); static void add(const std::string& msg_name, std::function<void()> callback);
static void notify_all(const std::string& msg_name); static void notify_all(const std::string& msg_name);
@ -16,7 +23,6 @@ public:
protected: protected:
using Callbacks = std::vector<std::function<void()>>; using Callbacks = std::vector<std::function<void()>>;
static std::map<std::string, Callbacks> s_message_map; static std::map<std::string, Callbacks> s_message_map;
}; };

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -7,38 +7,33 @@
// //
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com> // Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
#include "Shader_program.h"
#include <iostream> #include <iostream>
#include "Tools.h" #include "Tools.h"
#include "Shader_program.h"
std::string Shader_program::s_shader_path; std::string Shader_program::s_shader_path;
//! \brief
void Shader_program::set_shader_path(const char* path) void Shader_program::set_shader_path(const char* path)
{ { s_shader_path = std::string(path); }
s_shader_path = std::string(path);
}
bool Shader_program::init() //! \brief
{ bool Shader_program::init() {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
m_program = glCreateProgram(); m_program = glCreateProgram();
if (!m_program) if (! m_program) {
{
std::cout << "error creating shader program!\n"; std::cout << "error creating shader program!\n";
return false; return false;
} }
return true; return true;
} }
bool Shader_program::init(const char* vs, const char* gs, const char* fs)
{ //! \brief
if (init() == false) bool Shader_program::init(const char* vs, const char* gs, const char* fs) {
return false; if (! init()) return false;
add_shader_from_file(vs, GL_VERTEX_SHADER); add_shader_from_file(vs, GL_VERTEX_SHADER);
add_shader_from_file(gs, GL_GEOMETRY_SHADER); add_shader_from_file(gs, GL_GEOMETRY_SHADER);
@ -49,21 +44,23 @@ bool Shader_program::init(const char* vs, const char* gs, const char* fs)
return true; return true;
} }
//! \brief
bool Shader_program::init(const std::string& vs, bool Shader_program::init(const std::string& vs,
const std::string& gs, const std::string& gs,
const std::string& fs) const std::string& fs)
{ { return init(vs.c_str(), gs.c_str(), fs.c_str()); }
return init(vs.c_str(), gs.c_str(), fs.c_str());
} //! \brief
bool Shader_program::init_with_vs_fs(const char* shader_file_prefix) bool Shader_program::init_with_vs_fs(const char* shader_file_prefix) {
{
std::string prefix(shader_file_prefix); std::string prefix(shader_file_prefix);
std::string vs = s_shader_path + prefix + "_vs.glsl"; std::string vs = s_shader_path + prefix + "_vs.glsl";
std::string fs = s_shader_path + prefix + "_fs.glsl"; std::string fs = s_shader_path + prefix + "_fs.glsl";
return init(vs, "", fs); return init(vs, "", fs);
} }
void Shader_program::add_shader(const char* shader_code, GLenum shader_type)
{ //! \brief
void Shader_program::add_shader(const char* shader_code, GLenum shader_type) {
GLuint the_shader = glCreateShader(shader_type); GLuint the_shader = glCreateShader(shader_type);
const GLchar* the_code[] = { shader_code }; const GLchar* the_code[] = { shader_code };
@ -76,11 +73,9 @@ void Shader_program::add_shader(const char* shader_code, GLenum shader_type)
GLint result = 0; GLint result = 0;
GLchar elog[1024] = { 0 }; GLchar elog[1024] = { 0 };
glGetShaderiv(the_shader, GL_COMPILE_STATUS, &result); glGetShaderiv(the_shader, GL_COMPILE_STATUS, &result);
if (!result) if (! result) {
{
std::string shader_type_name; std::string shader_type_name;
switch (shader_type) switch (shader_type) {
{
case GL_VERTEX_SHADER: shader_type_name = "VERTEX"; break; case GL_VERTEX_SHADER: shader_type_name = "VERTEX"; break;
case GL_GEOMETRY_SHADER: shader_type_name = "GEOMETRY"; break; case GL_GEOMETRY_SHADER: shader_type_name = "GEOMETRY"; break;
case GL_FRAGMENT_SHADER: shader_type_name = "FRAGMENT"; break; case GL_FRAGMENT_SHADER: shader_type_name = "FRAGMENT"; break;
@ -93,33 +88,33 @@ void Shader_program::add_shader(const char* shader_code, GLenum shader_type)
glAttachShader(m_program, the_shader); glAttachShader(m_program, the_shader);
} }
//! \brief
void Shader_program::add_shader_from_file(const char* shader_file, void Shader_program::add_shader_from_file(const char* shader_file,
GLenum shader_type) GLenum shader_type) {
{ if (strlen(shader_file) == 0) return;
if (strlen(shader_file) == 0)
return;
auto src = read_file(shader_file); auto src = read_file(shader_file);
add_shader(src.c_str(), shader_type); add_shader(src.c_str(), shader_type);
} }
bool Shader_program::link() //! \brief
{ bool Shader_program::link() {
GLint result = 0; GLint result = 0;
GLchar elog[1024] = { 0 }; GLchar elog[1024] = { 0 };
glLinkProgram(m_program); glLinkProgram(m_program);
glGetProgramiv(m_program, GL_LINK_STATUS, &result); glGetProgramiv(m_program, GL_LINK_STATUS, &result);
if (!result) if (! result) {
{
glGetProgramInfoLog(m_program, sizeof(elog), NULL, elog); glGetProgramInfoLog(m_program, sizeof(elog), NULL, elog);
std::cout << "! error linking program:\n" << elog << std::endl; std::cout << "! error linking program:\n" << elog << std::endl;
return false; return false;
} }
return true; return true;
} }
bool Shader_program::validate()
{ //! \brief
bool Shader_program::validate() {
GLint result = 0; GLint result = 0;
GLchar elog[1024] = { 0 }; GLchar elog[1024] = { 0 };
@ -134,47 +129,44 @@ bool Shader_program::validate()
return true; return true;
} }
GLint Shader_program::get_uniform_location(const GLchar* name) //! \brief
{ GLint Shader_program::get_uniform_location(const GLchar* name) {
const auto uniform_loc = glGetUniformLocation(m_program, name); const auto uniform_loc = glGetUniformLocation(m_program, name);
return uniform_loc; return uniform_loc;
} }
void Shader_program::use() //! \brief
{ void Shader_program::use() { glUseProgram(m_program); }
glUseProgram(m_program);
}
void Shader_program::unuse()
{
glUseProgram(0);
}
//! \brief
void Shader_program::unuse() { glUseProgram(0); }
//! \brief
void Shader_program::set_uniform(GLint uniform_loc, const QMatrix4x4& m) void Shader_program::set_uniform(GLint uniform_loc, const QMatrix4x4& m)
{ { glUniformMatrix4fv(uniform_loc, 1, GL_FALSE, m.data()); }
glUniformMatrix4fv(uniform_loc, 1, GL_FALSE, m.data());
} //! \brief
void Shader_program::set_uniform(const GLchar* name, const QMatrix4x4& m) void Shader_program::set_uniform(const GLchar* name, const QMatrix4x4& m) {
{
const auto uniform_loc = get_uniform_location(name); const auto uniform_loc = get_uniform_location(name);
set_uniform(uniform_loc, m); set_uniform(uniform_loc, m);
} }
//! \brief
void Shader_program::set_uniform(GLint uniform_loc, const QMatrix3x3& m) void Shader_program::set_uniform(GLint uniform_loc, const QMatrix3x3& m)
{ { glUniformMatrix3fv(uniform_loc, 1, GL_FALSE, m.data()); }
glUniformMatrix3fv(uniform_loc, 1, GL_FALSE, m.data());
} //! \brief
void Shader_program::set_uniform(const GLchar* name, const QMatrix3x3& m) void Shader_program::set_uniform(const GLchar* name, const QMatrix3x3& m) {
{
const auto uniform_loc = get_uniform_location(name); const auto uniform_loc = get_uniform_location(name);
set_uniform(uniform_loc, m); set_uniform(uniform_loc, m);
} }
//! \brief
void Shader_program::set_uniform(GLint uniform_loc, const QVector4D& v) void Shader_program::set_uniform(GLint uniform_loc, const QVector4D& v)
{ { glUniform4f(uniform_loc, v.x(), v.y(), v.z(), v.w()); }
glUniform4f(uniform_loc, v.x(), v.y(), v.z(), v.w());
} //! \brief
void Shader_program::set_uniform(const GLchar* name, const QVector4D& v) void Shader_program::set_uniform(const GLchar* name, const QVector4D& v) {
{
const auto uniform_loc = get_uniform_location(name); const auto uniform_loc = get_uniform_location(name);
set_uniform(uniform_loc, v); set_uniform(uniform_loc, v);
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -12,22 +12,20 @@
#include <string> #include <string>
#include <qmatrix4x4.h> #include <qmatrix4x4.h>
#include "Common_defs.h" #include "Common_defs.h"
class Shader_program : protected OpenGLFunctionsBase {
class Shader_program : protected OpenGLFunctionsBase
{
public: public:
static void set_shader_path(const char* path); static void set_shader_path(const char* path);
bool init(); bool init();
bool init(const char* vs, const char* gs, const char* fs); bool init(const char* vs, const char* gs, const char* fs);
bool init(const std::string& vs, bool init(const std::string& vs, const std::string& gs,
const std::string& gs,
const std::string& fs); const std::string& fs);
// initialize with just the vertex and fragment shaders /*! Initialize with just the vertex and fragment shaders
*/
bool init_with_vs_fs(const char* shader_file_prefix); bool init_with_vs_fs(const char* shader_file_prefix);
void add_shader(const char* shader_code, GLenum shader_type); void add_shader(const char* shader_code, GLenum shader_type);

View File

@ -1,52 +0,0 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
//
//#include "Shapefile.h"
//
//#include <iostream>
//
//#include <shapefil.h>
//
//
//void Shapefile::read(const std::string& filename)
//{
// // Open the shapefile
// SHPHandle shp = SHPOpen(filename.c_str(), "rb");
// if (shp == nullptr) {
// std::cerr << "Failed to open shapefile: " << filename << std::endl;
// return;
// }
//
// // Get shapefile information
// int numEntities, shapeType;
// double minBounds[4], maxBounds[4];
// SHPGetInfo(shp, &numEntities, &shapeType, minBounds, maxBounds);
// std::cout << "Number of entities: " << numEntities << std::endl;
// std::cout << "Shape type: " << shapeType << std::endl;
// std::cout << "Bounds: (" << minBounds[0] << ", " << minBounds[1] << "), ("
// << maxBounds[0] << ", " << maxBounds[1] << ")" << std::endl;
// //SHPT_POLYGON
// // Read individual shapes
// for (int i = 0; i < numEntities; ++i) {
// SHPObject* shape = SHPReadObject(shp, i);
//
// // Process the shape data
// // Example: Print the shape's type and number of points
// std::cout << "Shape " << i << ": Type " << shape->nSHPType
// << ", Number of parts: " << shape->nParts
// << ", Number of points: " << shape->nVertices << std::endl;
//
// // Clean up the shape object
// SHPDestroyObject(shape);
// }
//
// // Close the shapefile
// SHPClose(shp);
//}

View File

@ -1,23 +0,0 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
//
//#ifndef SHAPEFILE_H
//#define SHAPEFILE_H
//
//#include <string>
//
//
//class Shapefile
//{
//public:
// static void read(const std::string& filename);
//};
//
//#endif

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -9,9 +9,8 @@
#include "Single_vertex.h" #include "Single_vertex.h"
//!\brief
Single_vertex::Single_vertex(const QVector3D& pos) Single_vertex::Single_vertex(const QVector3D& pos) {
{
initializeOpenGLFunctions(); initializeOpenGLFunctions();
m_pos = pos; m_pos = pos;
@ -26,19 +25,14 @@ Single_vertex::Single_vertex(const QVector3D& pos)
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
auto vertex_buffer_size = sizeof(m_pos); auto vertex_buffer_size = sizeof(m_pos);
auto vertex_buffer_data = reinterpret_cast<const void*>(&m_pos); auto vertex_buffer_data = reinterpret_cast<const void*>(&m_pos);
glBufferData(GL_ARRAY_BUFFER, glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
vertex_buffer_size,
vertex_buffer_data,
GL_DYNAMIC_DRAW); GL_DYNAMIC_DRAW);
// Position Vertex-Attribute // Position Vertex-Attribute
GLint position_attrib_index = 0; GLint position_attrib_index = 0;
const void* position_offset = 0; const void* position_offset = 0;
GLsizei stride = 0; GLsizei stride = 0;
glVertexAttribPointer(position_attrib_index, glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
3,
GL_FLOAT, GL_FALSE,
stride,
position_offset); position_offset);
glEnableVertexAttribArray(position_attrib_index); glEnableVertexAttribArray(position_attrib_index);
@ -46,35 +40,27 @@ Single_vertex::Single_vertex(const QVector3D& pos)
glBindVertexArray(0); glBindVertexArray(0);
} }
//!\brief
void Single_vertex::set_visible(bool flag) { m_visible = flag; }
void Single_vertex::set_visible(bool flag) //!\brief
{ void Single_vertex::set_pos(const QVector3D& pos) {
m_visible = flag;
}
void Single_vertex::set_pos(const QVector3D& pos)
{
m_pos = pos; m_pos = pos;
m_update = true; m_update = true;
} }
const QVector3D& Single_vertex::get_pos() const
{
return m_pos;
}
//!\brief
const QVector3D& Single_vertex::get_pos() const { return m_pos; }
void Single_vertex::draw() //!\brief
{ void Single_vertex::draw() {
if (m_visible) if (m_visible) {
{ if (m_update) {
if (m_update)
{
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
auto vertex_buffer_size = sizeof(m_pos); auto vertex_buffer_size = sizeof(m_pos);
auto vertex_buffer_data = reinterpret_cast<const void*>(&m_pos); auto vertex_buffer_data = reinterpret_cast<const void*>(&m_pos);
auto offset = 0; auto offset = 0;
glBufferSubData(GL_ARRAY_BUFFER, glBufferSubData(GL_ARRAY_BUFFER, offset, vertex_buffer_size,
offset,
vertex_buffer_size,
vertex_buffer_data); vertex_buffer_data);
m_update = false; m_update = false;
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -14,9 +14,7 @@
#include <qvector3d.h> #include <qvector3d.h>
#include "Common_defs.h" #include "Common_defs.h"
class Single_vertex : protected OpenGLFunctionsBase {
class Single_vertex : protected OpenGLFunctionsBase
{
public: public:
Single_vertex(const QVector3D& pos); Single_vertex(const QVector3D& pos);
@ -29,7 +27,8 @@ public:
private: private:
bool m_visible; bool m_visible;
bool m_update = true; // flag to update the VBO (set_pos sets this) bool m_update = true; // flag to update the VBO (set_pos sets this)
GLuint m_vao, m_vbo; GLuint m_vao;
GLuint m_vbo;
QVector3D m_pos; QVector3D m_pos;
}; };

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -7,16 +7,15 @@
// //
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com> // Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
#include "Sphere.h"
#include <cmath> #include <cmath>
#include <vector> #include <vector>
#include <qvector3d.h> #include <qvector3d.h>
#include "Sphere.h"
Sphere::Sphere(int num_slices, int num_stacks, float r) //! \brief
{ Sphere::Sphere(int num_slices, int num_stacks, float r) {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
num_stacks = std::max<int>(2, num_stacks); num_stacks = std::max<int>(2, num_stacks);
@ -31,15 +30,13 @@ Sphere::Sphere(int num_slices, int num_stacks, float r)
normals.push_back(QVector3D(0, 0, -1)); normals.push_back(QVector3D(0, 0, -1));
int starting_index_of_middle_vertices = vertices.size(); int starting_index_of_middle_vertices = vertices.size();
for (int j = 1; j < num_stacks; ++j) for (int j = 1; j < num_stacks; ++j) {
{
// Calculate the latitude (vertical angle) for the current stack // Calculate the latitude (vertical angle) for the current stack
float lat = M_PI * j / num_stacks; float lat = M_PI * j / num_stacks;
float rxy = r * std::sin(lat); float rxy = r * std::sin(lat);
float z = r * std::cos(lat); float z = r * std::cos(lat);
for (int i = 0; i < num_slices; ++i) for (int i = 0; i < num_slices; ++i) {
{
// Calculate the longitude (horizontal angle) for the current slice // Calculate the longitude (horizontal angle) for the current slice
float lon = 2 * M_PI * i / num_slices; float lon = 2 * M_PI * i / num_slices;
@ -56,8 +53,7 @@ Sphere::Sphere(int num_slices, int num_stacks, float r)
// strided vertex-data // strided vertex-data
std::vector<QVector3D> vertex_data; std::vector<QVector3D> vertex_data;
for (int i = 0; i < vertices.size(); ++i) for (int i = 0; i < vertices.size(); ++i) {
{
vertex_data.push_back(vertices[i]); vertex_data.push_back(vertices[i]);
vertex_data.push_back(normals[i]); vertex_data.push_back(normals[i]);
} }
@ -69,8 +65,7 @@ Sphere::Sphere(int num_slices, int num_stacks, float r)
// NORTH CAP // NORTH CAP
const int north_vertex_index = 0; const int north_vertex_index = 0;
const int north_cap_vertex_index_start = starting_index_of_middle_vertices; const int north_cap_vertex_index_start = starting_index_of_middle_vertices;
for (int i = 0; i < num_slices; i++) for (int i = 0; i < num_slices; i++) {
{
indices.push_back(north_vertex_index); indices.push_back(north_vertex_index);
indices.push_back(north_cap_vertex_index_start + i); indices.push_back(north_cap_vertex_index_start + i);
indices.push_back(north_cap_vertex_index_start + (i + 1) % num_slices); indices.push_back(north_cap_vertex_index_start + (i + 1) % num_slices);
@ -90,8 +85,7 @@ Sphere::Sphere(int num_slices, int num_stacks, float r)
const int south_vertex_index = 1; const int south_vertex_index = 1;
const int south_cap_index_start = starting_index_of_middle_vertices + const int south_cap_index_start = starting_index_of_middle_vertices +
(num_stacks - 2) * num_slices; (num_stacks - 2) * num_slices;
for (int i = 0; i < num_slices; ++i) for (int i = 0; i < num_slices; ++i) {
{
const auto vi0 = south_vertex_index; const auto vi0 = south_vertex_index;
const auto vi1 = south_cap_index_start + i; const auto vi1 = south_cap_index_start + i;
const auto vi2 = south_cap_index_start + (i + 1) % num_slices; const auto vi2 = south_cap_index_start + (i + 1) % num_slices;
@ -101,13 +95,11 @@ Sphere::Sphere(int num_slices, int num_stacks, float r)
} }
// MIDDLE TRIANGLES // MIDDLE TRIANGLES
for (int k = 0; k < num_stacks - 2; ++k) for (int k = 0; k < num_stacks - 2; ++k) {
{
const int stack_start_index = starting_index_of_middle_vertices + const int stack_start_index = starting_index_of_middle_vertices +
k * num_slices; k * num_slices;
const int next_stack_start_index = stack_start_index + num_slices; const int next_stack_start_index = stack_start_index + num_slices;
for (int i = 0; i < num_slices; ++i) for (int i = 0; i < num_slices; ++i) {
{
// check why the following code snippet does not work (winding order?) // check why the following code snippet does not work (winding order?)
//int vi0 = stackStartIndex + i; //int vi0 = stackStartIndex + i;
//int vi1 = nextStackStartIndex + i; //int vi1 = nextStackStartIndex + i;
@ -129,7 +121,6 @@ Sphere::Sphere(int num_slices, int num_stacks, float r)
} }
m_num_indices = indices.size(); m_num_indices = indices.size();
// DEFINE OPENGL BUFFERS // DEFINE OPENGL BUFFERS
glGenVertexArrays(1, &m_vao); glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
@ -139,9 +130,7 @@ Sphere::Sphere(int num_slices, int num_stacks, float r)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
auto indices_size = sizeof(GLuint) * indices.size(); auto indices_size = sizeof(GLuint) * indices.size();
auto indices_data = reinterpret_cast<const void*>(indices.data()); auto indices_data = reinterpret_cast<const void*>(indices.data());
glBufferData(GL_ELEMENT_ARRAY_BUFFER, glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_size, indices_data,
indices_size,
indices_data,
GL_STATIC_DRAW); GL_STATIC_DRAW);
// Vertex Buffer // Vertex Buffer
@ -149,30 +138,21 @@ Sphere::Sphere(int num_slices, int num_stacks, float r)
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size(); auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size();
auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data()); auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data());
glBufferData(GL_ARRAY_BUFFER, glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
vertex_buffer_size,
vertex_buffer_data,
GL_STATIC_DRAW); GL_STATIC_DRAW);
// Position Vertex-Attribute // Position Vertex-Attribute
GLint position_attrib_index = 0; GLint position_attrib_index = 0;
const void* position_offset = 0; const void* position_offset = 0;
GLsizei stride = 6 * sizeof(float); GLsizei stride = 6 * sizeof(float);
glVertexAttribPointer(position_attrib_index, glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
3,
GL_FLOAT, GL_FALSE,
stride,
position_offset); position_offset);
glEnableVertexAttribArray(position_attrib_index); glEnableVertexAttribArray(position_attrib_index);
// Normal Vertex-Attribute // Normal Vertex-Attribute
GLint normal_attrib_index = 1; GLint normal_attrib_index = 1;
auto* normal_offset = reinterpret_cast<const void*>(3 * sizeof(float)); auto* normal_offset = reinterpret_cast<const void*>(3 * sizeof(float));
glVertexAttribPointer(normal_attrib_index, glVertexAttribPointer(normal_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
3,
GL_FLOAT,
GL_FALSE,
stride,
normal_offset); normal_offset);
glEnableVertexAttribArray(normal_attrib_index); glEnableVertexAttribArray(normal_attrib_index);
@ -182,17 +162,18 @@ Sphere::Sphere(int num_slices, int num_stacks, float r)
// Note: calling this before glBindVertexArray(0) results in no output! // Note: calling this before glBindVertexArray(0) results in no output!
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
} }
//! \brief
void Sphere::set_color(float r, float g, float b, float a) void Sphere::set_color(float r, float g, float b, float a)
{ { m_color = QVector4D(r, g, b, a); }
m_color = QVector4D(r, g, b, a);
} //! \brief
void Sphere::draw() void Sphere::draw() {
{
// DRAW TRIANGLES // DRAW TRIANGLES
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
{
//glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); //glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
glDrawElements(GL_TRIANGLES, m_num_indices, GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLES, m_num_indices, GL_UNSIGNED_INT, 0);
}
glBindVertexArray(0); glBindVertexArray(0);
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -13,9 +13,7 @@
#include "Common_defs.h" #include "Common_defs.h"
#include <qvector4d.h> #include <qvector4d.h>
class Sphere : protected OpenGLFunctionsBase {
class Sphere : protected OpenGLFunctionsBase
{
public: public:
Sphere(int num_slices, int num_stacks, float r); Sphere(int num_slices, int num_stacks, float r);
@ -25,7 +23,10 @@ public:
void draw(); void draw();
private: private:
GLuint m_vao, m_vbo, m_ibo, m_num_indices; GLuint m_vao;
GLuint m_vbo;
GLuint m_ibo;
GLuint m_num_indices;
QVector4D m_color; QVector4D m_color;
}; };

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -14,46 +14,33 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
class Timer {
class Timer
{
public: public:
Timer() Timer() { reset(); }
{
reset();
}
void reset() void reset() { m_Start = std::chrono::high_resolution_clock::now(); }
{
m_Start = std::chrono::high_resolution_clock::now();
}
float elapsed() float elapsed() {
{
return std::chrono::duration_cast<std::chrono::nanoseconds>( return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::high_resolution_clock::now() - m_Start).count() std::chrono::high_resolution_clock::now() - m_Start).count()
* 0.001f * 0.001f * 0.001f; * 0.001f * 0.001f * 0.001f;
} }
float elapsed_millis() float elapsed_millis() { return elapsed() * 1000.0f; }
{
return elapsed() * 1000.0f;
}
private: private:
std::chrono::time_point<std::chrono::high_resolution_clock> m_Start; std::chrono::time_point<std::chrono::high_resolution_clock> m_Start;
}; };
class ScopedTimer class ScopedTimer {
{
public: public:
ScopedTimer(const std::string& name) ScopedTimer(const std::string& name) : m_Name(name) {}
: m_Name(name) {}
~ScopedTimer() ~ScopedTimer() {
{
float time = m_Timer.elapsed_millis(); float time = m_Timer.elapsed_millis();
std::cout << "[TIMER] " << m_Name << " - " << time << "ms\n"; std::cout << "[TIMER] " << m_Name << " - " << time << "ms\n";
} }
private: private:
std::string m_Name; std::string m_Name;
Timer m_Timer; Timer m_Timer;

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -13,14 +13,12 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
//! \brief
std::string read_file(const std::string& file_name) std::string read_file(const std::string& file_name) {
{
const auto flags = std::ios::in | std::ios::binary | std::ios::ate; const auto flags = std::ios::in | std::ios::binary | std::ios::ate;
std::ifstream ifs(file_name.c_str(), flags); std::ifstream ifs(file_name.c_str(), flags);
if (ifs.is_open() == false) if (! ifs.is_open()) {
{
std::cout << "could not open file: " << file_name << std::endl; std::cout << "could not open file: " << file_name << std::endl;
return ""; return "";
} }
@ -34,18 +32,20 @@ std::string read_file(const std::string& file_name)
return std::string(&bytes[0], file_size); return std::string(&bytes[0], file_size);
} }
std::ostream& operator << (std::ostream& os, const QVector2D& v) //! \brief
{ std::ostream& operator << (std::ostream& os, const QVector2D& v) {
os << v.x() << ", " << v.y(); os << v.x() << ", " << v.y();
return os; return os;
} }
std::ostream& operator << (std::ostream& os, const QVector3D& v)
{ //! \brief
std::ostream& operator << (std::ostream& os, const QVector3D& v) {
os << v.x() << ", " << v.y() << ", " << v.z(); os << v.x() << ", " << v.y() << ", " << v.z();
return os; return os;
} }
std::ostream& operator << (std::ostream& os, const QVector4D& v)
{ //! \brief
std::ostream& operator << (std::ostream& os, const QVector4D& v) {
os << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w(); os << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w();
return os; return os;
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -15,7 +15,6 @@
#include <QVector2D> #include <QVector2D>
#include <QVector3D> #include <QVector3D>
std::string read_file(const std::string& file_name); std::string read_file(const std::string& file_name);
std::ostream& operator << (std::ostream& os, const QVector2D& v); std::ostream& operator << (std::ostream& os, const QVector2D& v);

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -11,15 +11,13 @@
#include <iostream> #include <iostream>
//! \brief
Triangles::Triangles(std::vector<QVector3D>& vertices) Triangles::Triangles(std::vector<QVector3D>& vertices) {
{
initializeOpenGLFunctions(); initializeOpenGLFunctions();
// computer the normals of each vertex // computer the normals of each vertex
std::vector<QVector3D> normals; std::vector<QVector3D> normals;
for(const auto& p : vertices) for(const auto& p : vertices) {
{
auto n = p; auto n = p;
n.normalize(); n.normalize();
normals.push_back(n); normals.push_back(n);
@ -29,13 +27,11 @@ Triangles::Triangles(std::vector<QVector3D>& vertices)
// strided vertex-data // strided vertex-data
std::vector<QVector3D> vertex_data; std::vector<QVector3D> vertex_data;
for (int i = 0; i < vertices.size(); ++i) for (int i = 0; i < vertices.size(); ++i) {
{
vertex_data.push_back(vertices[i]); vertex_data.push_back(vertices[i]);
vertex_data.push_back(normals[i]); vertex_data.push_back(normals[i]);
} }
// DEFINE OPENGL BUFFERS // DEFINE OPENGL BUFFERS
glGenVertexArrays(1, &m_vao); glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
@ -46,30 +42,21 @@ Triangles::Triangles(std::vector<QVector3D>& vertices)
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size(); auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size();
auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data()); auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data());
glBufferData(GL_ARRAY_BUFFER, glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
vertex_buffer_size,
vertex_buffer_data,
GL_STATIC_DRAW); GL_STATIC_DRAW);
// Position Vertex-Attribute // Position Vertex-Attribute
GLint position_attrib_index = 0; GLint position_attrib_index = 0;
const void* position_offset = 0; const void* position_offset = 0;
GLsizei stride = 6 * sizeof(float); GLsizei stride = 6 * sizeof(float);
glVertexAttribPointer(position_attrib_index, glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
3,
GL_FLOAT, GL_FALSE,
stride,
position_offset); position_offset);
glEnableVertexAttribArray(position_attrib_index); glEnableVertexAttribArray(position_attrib_index);
// Normal Vertex-Attribute // Normal Vertex-Attribute
GLint normal_attrib_index = 1; GLint normal_attrib_index = 1;
auto* normal_offset = reinterpret_cast<const void*>(3 * sizeof(float)); auto* normal_offset = reinterpret_cast<const void*>(3 * sizeof(float));
glVertexAttribPointer(normal_attrib_index, glVertexAttribPointer(normal_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
3,
GL_FLOAT,
GL_FALSE,
stride,
normal_offset); normal_offset);
glEnableVertexAttribArray(normal_attrib_index); glEnableVertexAttribArray(normal_attrib_index);
@ -77,20 +64,17 @@ Triangles::Triangles(std::vector<QVector3D>& vertices)
glBindVertexArray(0); glBindVertexArray(0);
} }
//! \brief
void Triangles::set_color(const QVector4D& rgba) void Triangles::set_color(const QVector4D& rgba)
{ { m_color = rgba; }
m_color = rgba;
}
const QVector4D& Triangles::get_color() const
{
return m_color;
}
void Triangles::draw() //! \brief
{ const QVector4D& Triangles::get_color() const { return m_color; }
//! \brief
void Triangles::draw() {
// DRAW TRIANGLES // DRAW TRIANGLES
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
glDrawArrays(GL_TRIANGLES, 0, m_num_vertices); glDrawArrays(GL_TRIANGLES, 0, m_num_vertices);
glBindVertexArray(0); glBindVertexArray(0);
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -14,9 +14,7 @@
#include <qvector3d.h> #include <qvector3d.h>
#include "Common_defs.h" #include "Common_defs.h"
class Triangles : protected OpenGLFunctionsBase {
class Triangles : protected OpenGLFunctionsBase
{
public: public:
// IMPORTANT: we assume that the triangles are on the sphere! // IMPORTANT: we assume that the triangles are on the sphere!
// this means that all vertex-normals are actually the normal vector on the // this means that all vertex-normals are actually the normal vector on the
@ -30,7 +28,8 @@ public:
void draw(); void draw();
private: private:
GLuint m_vao, m_vbo; GLuint m_vao;
GLuint m_vbo;
int m_num_vertices; int m_num_vertices;
QVector4D m_color; QVector4D m_color;
}; };

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -13,10 +13,10 @@
#include "Kml_reader.h" #include "Kml_reader.h"
void Verification::find_minimum_projected_error_on_sphere(float we,
void Verification::find_minimum_projected_error_on_sphere(float we, Camera& cam, Camera& cam,
int vp_width, int vp_height) int vp_width,
{ int vp_height) {
QRect vp(0, 0, vp_width, vp_height); QRect vp(0, 0, vp_width, vp_height);
auto proj = cam.get_projection_matrix(); auto proj = cam.get_projection_matrix();
auto view = cam.get_view_matrix(); auto view = cam.get_view_matrix();
@ -33,14 +33,12 @@ void Verification::find_minimum_projected_error_on_sphere(float we, Camera& cam,
const float r1 = 1.f; const float r1 = 1.f;
const float r2 = r1 - we; const float r2 = r1 - we;
for (int i = 0; i <= num_divs; i++) for (int i = 0; i <= num_divs; ++i) {
{
const float theta = dtheta * i; const float theta = dtheta * i;
const float cos_theta = std::cos(theta); const float cos_theta = std::cos(theta);
const float sin_theta = std::sin(theta); const float sin_theta = std::sin(theta);
for (int j = 0; j <= num_divs; j++) for (int j = 0; j <= num_divs; ++j) {
{
QVector3D p1, p2; QVector3D p1, p2;
const float phi = dphi * j; const float phi = dphi * j;
const float cos_phi = std::cos(phi); const float cos_phi = std::cos(phi);
@ -62,8 +60,7 @@ void Verification::find_minimum_projected_error_on_sphere(float we, Camera& cam,
auto wp2 = p2.project(model_view, proj, vp); auto wp2 = p2.project(model_view, proj, vp);
const auto pe = wp1.distanceToPoint(wp2); const auto pe = wp1.distanceToPoint(wp2);
if (max_err < pe) if (max_err < pe) {
{
max_err = pe; max_err = pe;
max_theta = theta; max_theta = theta;
max_phi = phi; max_phi = phi;
@ -99,8 +96,8 @@ void Verification::find_minimum_projected_error_on_sphere(float we, Camera& cam,
//std::cout << QVector3D(0, 0, 0).project(model_view, proj, vp) << std::endl; //std::cout << QVector3D(0, 0, 0).project(model_view, proj, vp) << std::endl;
} }
void Verification::verify_antarctica_node_is_redundant() //! \brief
{ void Verification::verify_antarctica_node_is_redundant() {
Kml::Node n1(178.277211542064, -84.4725179992025), Kml::Node n1(178.277211542064, -84.4725179992025),
n2(180.0, -84.71338), n2(180.0, -84.71338),
n3(-179.942499356179, -84.7214433735525); n3(-179.942499356179, -84.7214433735525);

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -15,23 +15,18 @@
#include "Camera.h" #include "Camera.h"
//
// This class contains code to verify or compute certain hypotheses // This class contains code to verify or compute certain hypotheses
// //
class Verification class Verification {
{
public: public:
// Use this to find the approximate of the true minimum projected error. // Use this to find the approximate of the true minimum projected error.
// we are ot using this complicated method, but provide it for completeness. // we are ot using this complicated method, but provide it for completeness.
static void find_minimum_projected_error_on_sphere(float we, Camera& cam, static void find_minimum_projected_error_on_sphere(float we, Camera& cam,
int vp_width, int vp_height); int vp_width,
int vp_height);
// verify that the node (180.0, -84.71338) in Antarctica is redundant // verify that the node (180.0, -84.71338) in Antarctica is redundant
static void verify_antarctica_node_is_redundant(); static void verify_antarctica_node_is_redundant();
}; };
#endif #endif

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -9,9 +9,8 @@
#include "Vertices.h" #include "Vertices.h"
//! brief
Vertices::Vertices(const std::vector<QVector3D>& vertices) Vertices::Vertices(const std::vector<QVector3D>& vertices) {
{
initializeOpenGLFunctions(); initializeOpenGLFunctions();
auto& vertex_data = vertices; auto& vertex_data = vertices;
@ -26,19 +25,14 @@ Vertices::Vertices(const std::vector<QVector3D>& vertices)
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size(); auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size();
auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data()); auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data());
glBufferData(GL_ARRAY_BUFFER, glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
vertex_buffer_size,
vertex_buffer_data,
GL_STATIC_DRAW); GL_STATIC_DRAW);
// Position Vertex-Attribute // Position Vertex-Attribute
GLint position_attrib_index = 0; GLint position_attrib_index = 0;
const void* position_offset = 0; const void* position_offset = 0;
GLsizei stride = 0; GLsizei stride = 0;
glVertexAttribPointer(position_attrib_index, glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
3,
GL_FLOAT, GL_FALSE,
stride,
position_offset); position_offset);
glEnableVertexAttribArray(position_attrib_index); glEnableVertexAttribArray(position_attrib_index);
@ -46,11 +40,9 @@ Vertices::Vertices(const std::vector<QVector3D>& vertices)
glBindVertexArray(0); glBindVertexArray(0);
} }
void Vertices::draw() //! brief
{ void Vertices::draw() {
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
{
glDrawArrays(GL_POINTS, 0, m_num_indices); glDrawArrays(GL_POINTS, 0, m_num_indices);
}
glBindVertexArray(0); glBindVertexArray(0);
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -12,20 +12,20 @@
#include <vector> #include <vector>
#include <qvector3d.h> #include <qvector3d.h>
#include "Common_defs.h" #include "Common_defs.h"
class Vertices : protected OpenGLFunctionsBase {
class Vertices : protected OpenGLFunctionsBase
{
public: public:
Vertices(const std::vector<QVector3D>& vertices); Vertices(const std::vector<QVector3D>& vertices);
void draw(); void draw();
private: private:
GLuint m_vao, m_vbo, m_num_indices; GLuint m_vao;
GLuint m_vbo;
GLuint m_num_indices;
std::vector<GLuint> m_offsets; std::vector<GLuint> m_offsets;
}; };
#endif #endif

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -7,15 +7,14 @@
// //
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com> // Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
#include "World_coordinate_axes.h"
#include <vector> #include <vector>
#include <qvector3d.h> #include <qvector3d.h>
#include "World_coordinate_axes.h"
World_coord_axes::World_coord_axes(float length) //! \brief
{ World_coord_axes::World_coord_axes(float length) {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
const auto a = length; const auto a = length;
@ -31,41 +30,30 @@ World_coord_axes::World_coord_axes(float length)
QVector3D(0,0,a), QVector3D(c,c,1) QVector3D(0,0,a), QVector3D(c,c,1)
}; };
// DEFINE OPENGL BUFFERS // DEFINE OPENGL BUFFERS
glGenVertexArrays(1, &m_vao); glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
// Vertex Buffer // Vertex Buffer
glGenBuffers(1, &m_vbo); glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size(); auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size();
auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data()); auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data());
glBufferData(GL_ARRAY_BUFFER, glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
vertex_buffer_size,
vertex_buffer_data,
GL_STATIC_DRAW); GL_STATIC_DRAW);
// Position Vertex-Attribute // Position Vertex-Attribute
GLint position_attrib_index = 0; GLint position_attrib_index = 0;
const void* position_offset = 0; const void* position_offset = 0;
GLsizei stride = 6 * sizeof(float); GLsizei stride = 6 * sizeof(float);
glVertexAttribPointer(position_attrib_index, glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
3,
GL_FLOAT, GL_FALSE,
stride,
position_offset); position_offset);
glEnableVertexAttribArray(position_attrib_index); glEnableVertexAttribArray(position_attrib_index);
// Color Vertex-Attribute // Color Vertex-Attribute
GLint color_attrib_index = 1; GLint color_attrib_index = 1;
auto* color_offset = reinterpret_cast<const void*>(3 * sizeof(float)); auto* color_offset = reinterpret_cast<const void*>(3 * sizeof(float));
glVertexAttribPointer(color_attrib_index, glVertexAttribPointer(color_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
3,
GL_FLOAT,
GL_FALSE,
stride,
color_offset); color_offset);
glEnableVertexAttribArray(color_attrib_index); glEnableVertexAttribArray(color_attrib_index);
@ -73,12 +61,10 @@ World_coord_axes::World_coord_axes(float length)
glBindVertexArray(0); glBindVertexArray(0);
} }
void World_coord_axes::draw() //! \brief
{ void World_coord_axes::draw() {
glBindVertexArray(m_vao); glBindVertexArray(m_vao);
{
const int count = 2 * 3; // = 2 * number of lines const int count = 2 * 3; // = 2 * number of lines
glDrawArrays(GL_LINES, 0, count); glDrawArrays(GL_LINES, 0, count);
}
glBindVertexArray(0); glBindVertexArray(0);
} }

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -10,19 +10,19 @@
#ifndef WORLD_COORD_AXES_H #ifndef WORLD_COORD_AXES_H
#define WORLD_COORD_AXES_H #define WORLD_COORD_AXES_H
#include "Common_defs.h"
#include <qvector4d.h> #include <qvector4d.h>
#include "Common_defs.h"
class World_coord_axes : protected OpenGLFunctionsBase class World_coord_axes : protected OpenGLFunctionsBase {
{
public: public:
World_coord_axes(float length); World_coord_axes(float length);
void draw(); void draw();
private: private:
GLuint m_vao, m_vbo; GLuint m_vao;
GLuint m_vbo;
}; };

View File

@ -1,10 +1,19 @@
#ifndef _PRINT_ARR_H_ // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
#define _PRINT_ARR_H_ // All rights reserved.
//-----------------------------------------------------------------------------
// Print all neighboring vertices to a given arrangement vertex.
// //
template<class Arrangement> // This file is part of CGAL (www.cgal.org).
//
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s): Engin Deniz Diktas <denizdiktas@gmail.com>
// : Efi Fogel <efifogel@gmail.com>
#ifndef PRINT_ARR_H
#define PRINT_ARR_H
/*! Print all neighboring vertices to a given arrangement vertex.
*/
template <typename Arrangement>
void print_neighboring_vertices(typename Arrangement::Vertex_const_handle v) { void print_neighboring_vertices(typename Arrangement::Vertex_const_handle v) {
if (v->is_isolated()) { if (v->is_isolated()) {
std::cout << "The vertex (" << v->point() << ") is isolated\n"; std::cout << "The vertex (" << v->point() << ") is isolated\n";
@ -19,10 +28,9 @@ void print_neighboring_vertices(typename Arrangement::Vertex_const_handle v) {
std::cout << std::endl; std::cout << std::endl;
} }
//----------------------------------------------------------------------------- /*! Print all vertices (points) and edges (curves) along a connected component
// Print all vertices (points) and edges (curves) along a connected component * boundary.
// boundary. */
//
template <typename Arrangement> template <typename Arrangement>
void print_ccb(typename Arrangement::Ccb_halfedge_const_circulator circ) { void print_ccb(typename Arrangement::Ccb_halfedge_const_circulator circ) {
std::cout << "(" << circ->source()->point() << ")"; std::cout << "(" << circ->source()->point() << ")";
@ -35,9 +43,8 @@ void print_ccb(typename Arrangement::Ccb_halfedge_const_circulator circ) {
std::cout << std::endl; std::cout << std::endl;
} }
//----------------------------------------------------------------------------- /*! Print the boundary description of an arrangement face.
// Print the boundary description of an arrangement face. */
//
template <typename Arrangement> template <typename Arrangement>
void print_face(typename Arrangement::Face_const_handle f) { void print_face(typename Arrangement::Face_const_handle f) {
// Print the outer boundary. // Print the outer boundary.
@ -66,9 +73,8 @@ void print_face(typename Arrangement::Face_const_handle f) {
} }
} }
//----------------------------------------------------------------------------- /*! Print the given arrangement.
// Print the given arrangement. */
//
template <typename Arrangement> template <typename Arrangement>
void print_arrangement(const Arrangement& arr) { void print_arrangement(const Arrangement& arr) {
CGAL_precondition(arr.is_valid()); CGAL_precondition(arr.is_valid());
@ -92,9 +98,8 @@ void print_arrangement(const Arrangement& arr) {
print_face<Arrangement>(fit); print_face<Arrangement>(fit);
} }
//----------------------------------------------------------------------------- /*! Print the size of the given arrangement.
// Print the size of the given arrangement. */
//
template <typename Arrangement> template <typename Arrangement>
void print_arrangement_size(const Arrangement& arr) { void print_arrangement_size(const Arrangement& arr) {
std::cout << "The arrangement size:\n" std::cout << "The arrangement size:\n"
@ -103,9 +108,8 @@ void print_arrangement_size(const Arrangement& arr) {
<< ", |F| = " << arr.number_of_faces() << std::endl; << ", |F| = " << arr.number_of_faces() << std::endl;
} }
//----------------------------------------------------------------------------- /*! Print the size of the given unbounded arrangement.
// Print the size of the given unbounded arrangement. */
//
template <typename Arrangement> template <typename Arrangement>
void print_unbounded_arrangement_size(const Arrangement& arr) { void print_unbounded_arrangement_size(const Arrangement& arr) {
std::cout << "The arrangement size:\n" std::cout << "The arrangement size:\n"

View File

@ -1,4 +1,4 @@
// Copyright(c) 2012, 2020 Tel - Aviv University(Israel). // Copyright(c) 2023, 2024 Tel-Aviv University (Israel).
// All rights reserved. // All rights reserved.
// //
// This file is part of CGAL (www.cgal.org). // This file is part of CGAL (www.cgal.org).
@ -15,19 +15,14 @@
#include "Main_widget.h" #include "Main_widget.h"
#endif #endif
int main(int argc, char* argv[]) {
int main(int argc, char* argv[])
{
QApplication app(argc, argv); QApplication app(argc, argv);
auto args = QCoreApplication::arguments(); auto args = QCoreApplication::arguments();
if (2 != args.size()) if (args.size() > 2) {
{ qDebug() << "Usage: earth [<arragement-file.json>]";
qDebug() << "Usage: earth <arragement-file.json>"; return(-1);
exit(1);
} }
QSurfaceFormat format; QSurfaceFormat format;
format.setVersion(3, 3); format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile); format.setProfile(QSurfaceFormat::CoreProfile);
@ -40,7 +35,8 @@ int main(int argc, char* argv[])
app.setApplicationName("Earth"); app.setApplicationName("Earth");
app.setApplicationVersion("0.1"); app.setApplicationVersion("0.1");
#ifndef QT_NO_OPENGL #ifndef QT_NO_OPENGL
auto& file_name = args.at(1); const char* file_name = (argc > 1) ? argv[1] :
"../../../Data/data/arrangements_3/sphere/ne_110m_admin_0_countries.json";
//qDebug() << "file name = " << file_name; //qDebug() << "file name = " << file_name;
Main_widget widget(file_name); Main_widget widget(file_name);
widget.show(); widget.show();