mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'cgal/master' into Triangulation_3-CDT_3-lrineau
This commit is contained in:
commit
b828719c7c
|
|
@ -36,7 +36,7 @@ namespace CGAL
|
|||
std::declval<int>())) reference;
|
||||
// typedef decltype(
|
||||
// typename GeomTraits::Construct_vertex_3()(
|
||||
// *std::declval<key_type&>(), 0)) reference; // fails polyhedron demo!
|
||||
// *std::declval<key_type&>(), 0)) reference; // fails CGAL Lab!
|
||||
typedef boost::readable_property_map_tag category;
|
||||
typedef Point_from_cell_iterator_proprety_map<GeomTraits, Iterator> Self;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,84 @@
|
|||
// 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 AOS_H
|
||||
#define AOS_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <qvector3d.h>
|
||||
|
||||
#include "Kml_reader.h"
|
||||
|
||||
class Aos {
|
||||
public:
|
||||
using Approx_arc = std::vector<QVector3D>;
|
||||
using Approx_arcs = std::vector<Approx_arc>;
|
||||
//using Arr_handle = void*;
|
||||
using Arr_handle = std::shared_ptr<void>;
|
||||
|
||||
static Approx_arc get_approx_identification_curve(double error);
|
||||
|
||||
// this constructs some sample arcs manually (used to check the visual output)
|
||||
static Approx_arcs get_approx_arcs(double error);
|
||||
|
||||
// this is used to construct approximate arcs from KML-Placemark data
|
||||
static Approx_arcs get_approx_arcs(const Kml::Placemark& placemark,
|
||||
double error);
|
||||
|
||||
static void get_curves();
|
||||
|
||||
static void check(const Kml::Placemarks& placemarks);
|
||||
|
||||
// Extended check: here we use the extended version of the DCEL to understand
|
||||
// what is going on with the additional vertices and faces.
|
||||
// INPUT: GIS data
|
||||
// OUTPUT: vertices created during arrangement construction
|
||||
static std::vector<QVector3D> ext_check(const Kml::Placemarks& placemarks);
|
||||
|
||||
// Same as above function but works by identifying the duplicate nodes
|
||||
static std::vector<QVector3D> ext_check_id_based(Kml::Placemarks& placemarks);
|
||||
|
||||
// This function is used to find the newly-created faces during arrangement
|
||||
// construction. It uses the extended DCEL structure (see: above 2 functions).
|
||||
// NOTE: The need for this function arises due to the following observation:
|
||||
// when constructing the arrangement from our data-set I observed a newly
|
||||
// created face which is not defined explicitly in the data-set. My intiution
|
||||
// tells me that this is the Caspian sea, because it is the only land-locked
|
||||
// polygon whose boundaries are not defined in the data-set and its boundaries
|
||||
// are defined indirecly by its surrounding countries.
|
||||
static Approx_arcs find_new_faces(Kml::Placemarks& placemarks);
|
||||
|
||||
// save the arrangement created with EPEC
|
||||
static void save_arr(Kml::Placemarks& placemarks,
|
||||
const std::string& file_name);
|
||||
|
||||
// loads the arrangement created by the save_arr function
|
||||
// NOTE: This one loads the arrangement as "Country_arr" type
|
||||
static Arr_handle load_arr(const std::string& file_name);
|
||||
|
||||
static Arr_handle construct(Kml::Placemarks& placemarks);
|
||||
//static std::vector<QVector3D> get_triangles(Arr_handle arrh);
|
||||
|
||||
//using Country_triangles_map = std::map<std::string, std::vector<QVector3D>>;
|
||||
//static Country_triangles_map get_triangles_by_country(Arr_handle arrh);
|
||||
|
||||
using Country_color_map = std::map<std::string, std::size_t>;
|
||||
static Country_color_map get_color_mapping(Arr_handle arrh);
|
||||
|
||||
static std::string locate_country(Arr_handle arrh, const QVector3D& point);
|
||||
|
||||
// this will get the approximate arcs of face-edges from the arrangement
|
||||
// NOTE: this is similar to "get_approx_arcs(KML::Placemarks&, double)" above!
|
||||
static Approx_arcs get_approx_arcs_from_faces_edges(Arr_handle arrh,
|
||||
double error);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// 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 AOS_DEFS_H
|
||||
#define AOS_DEFS_H
|
||||
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Arrangement_on_surface_2.h>
|
||||
#include <CGAL/Arr_extended_dcel.h>
|
||||
#include <CGAL/Arr_geodesic_arc_on_sphere_traits_2.h>
|
||||
#include <CGAL/Arr_spherical_topology_traits_2.h>
|
||||
#include <CGAL/Vector_3.h>
|
||||
|
||||
//#define USE_EPIC
|
||||
|
||||
#ifdef USE_EPIC
|
||||
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
#else
|
||||
using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
#endif
|
||||
|
||||
using Geom_traits = CGAL::Arr_geodesic_arc_on_sphere_traits_2<Kernel>;
|
||||
using Point = Geom_traits::Point_2;
|
||||
using Curve = Geom_traits::Curve_2;
|
||||
using Topol_traits = CGAL::Arr_spherical_topology_traits_2<Geom_traits>;
|
||||
using Arrangement = CGAL::Arrangement_on_surface_2<Geom_traits, Topol_traits>;
|
||||
|
||||
// the following is from "arr_inexact_construction_segments.h":
|
||||
using Segment = Geom_traits::X_monotone_curve_2;
|
||||
using Vertex_handle = Arrangement::Vertex_handle;
|
||||
|
||||
// COUNTRIES AOS for grouping the faces by the country name
|
||||
using Countries_dcel = CGAL::Arr_face_extended_dcel<Geom_traits, std::string>;
|
||||
using Countries_topol_traits =
|
||||
CGAL::Arr_spherical_topology_traits_2<Geom_traits, Countries_dcel>;
|
||||
using Countries_arr =
|
||||
CGAL::Arrangement_on_surface_2<Geom_traits, Countries_topol_traits>;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,318 @@
|
|||
// 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>
|
||||
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
|
||||
#include <qmath.h>
|
||||
#include <qvector3d.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
||||
// #include <CGAL/draw_triangulation_2.h>
|
||||
#include <CGAL/mark_domain_in_triangulation.h>
|
||||
#include <CGAL/Polygon_2.h>
|
||||
#include <CGAL/point_generators_3.h>
|
||||
#include <CGAL/Arr_batched_point_location.h>
|
||||
|
||||
#include "Aos_defs.h"
|
||||
#include "Aos_triangulator.h"
|
||||
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
namespace {
|
||||
|
||||
// use this traits everytime you construct an arrangment!
|
||||
static Geom_traits s_traits;
|
||||
using Dir3 = Kernel::Direction_3;
|
||||
using Approximate_number_type = Geom_traits::Approximate_number_type;
|
||||
using Approximate_kernel = Geom_traits::Approximate_kernel;
|
||||
using Approximate_Vector_3 = CGAL::Vector_3<Approximate_kernel>;
|
||||
using Approximate_Direction_3 = Approximate_kernel::Direction_3;
|
||||
using Direction_3 = Kernel::Direction_3;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
std::vector<QVector3D> Aos_triangulator::get_all(Aos::Arr_handle arrh) {
|
||||
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using Vb = CGAL::Triangulation_vertex_base_2<K>;
|
||||
using Fb = CGAL::Constrained_triangulation_face_base_2<K>;
|
||||
using TDS = CGAL::Triangulation_data_structure_2<Vb, Fb>;
|
||||
using Itag = CGAL::Exact_predicates_tag;
|
||||
using CDT = CGAL::Constrained_Delaunay_triangulation_2<K, TDS, Itag>;
|
||||
using Face_handle = CDT::Face_handle;
|
||||
using Polygon_2 = CGAL::Polygon_2<K>;
|
||||
|
||||
auto& arr = *reinterpret_cast<Arrangement*>(arrh.get());
|
||||
|
||||
//Geom_traits traits;
|
||||
auto approx = s_traits.approximate_2_object();
|
||||
|
||||
std::vector<std::vector<QVector3D>> all_faces;
|
||||
// loop on all faces of the arrangement
|
||||
for (auto fh : arr.face_handles()) {
|
||||
// skip any face with no OUTER-CCB
|
||||
if (0 == fh->number_of_outer_ccbs()) continue;
|
||||
|
||||
// COMPUTE THE CENTROID OF ALL FACE-POINTS
|
||||
std::vector<QVector3D> face_points;
|
||||
|
||||
// loop on the egdes of the current outer-ccb
|
||||
auto first = fh->outer_ccb();
|
||||
auto curr = first;
|
||||
do {
|
||||
auto ap = approx(curr->source()->point());
|
||||
QVector3D p(ap.dx(), ap.dy(), ap.dz());
|
||||
p.normalize();
|
||||
face_points.push_back(p);
|
||||
} while (++curr != first);
|
||||
|
||||
all_faces.push_back(std::move(face_points));
|
||||
}
|
||||
|
||||
// RESULTING TRIANGLE POINTS (every 3 point => triangle)
|
||||
std::vector<QVector3D> triangles;
|
||||
|
||||
std::cout << "triangulating individual faces\n";
|
||||
|
||||
// loop on all approximated faces
|
||||
for (auto& face_points : all_faces) {
|
||||
std::cout << "num face points = " << face_points.size() << std::endl;
|
||||
// no need to triangulate if the number of points is 3
|
||||
if (face_points.size() == 3) {
|
||||
triangles.insert(triangles.end(), face_points.begin(), face_points.end());
|
||||
continue;
|
||||
}
|
||||
|
||||
// find the centroid of all face-points
|
||||
QVector3D centroid(0, 0, 0);
|
||||
for (const auto& fp : face_points) centroid += fp;
|
||||
centroid /= face_points.size();
|
||||
centroid.normalize();
|
||||
auto normal = centroid;
|
||||
|
||||
K::Point_3 plane_origin(centroid.x(), centroid.y(), centroid.z());
|
||||
K::Vector_3 plane_normal(normal.x(), normal.y(), normal.z());
|
||||
K::Plane_3 plane(plane_origin, plane_normal);
|
||||
|
||||
Polygon_2 polygon;
|
||||
|
||||
// project all points onto the plane
|
||||
K::Point_3 origin(0, 0, 0);
|
||||
for (const auto& fp : face_points) {
|
||||
// define a ray through the origin and the current point
|
||||
K::Point_3 current_point(fp.x(), fp.y(), fp.z());
|
||||
K::Ray_3 ray(origin, current_point);
|
||||
|
||||
auto intersection = CGAL::intersection(plane, ray);
|
||||
if (!intersection.has_value())
|
||||
std::cout << "INTERSECTION ASSERTION ERROR!!!\n";
|
||||
auto ip = std::get<K::Point_3>(intersection.value());
|
||||
auto ip2 = plane.to_2d(ip);
|
||||
|
||||
// add this to the polygon constraint
|
||||
polygon.push_back(ip2);
|
||||
}
|
||||
|
||||
CDT cdt;
|
||||
cdt.insert_constraint(polygon.vertices_begin(), polygon.vertices_end(),
|
||||
true);
|
||||
|
||||
std::unordered_map<Face_handle, bool> in_domain_map;
|
||||
boost::associative_property_map< std::unordered_map<Face_handle, bool>>
|
||||
in_domain(in_domain_map);
|
||||
|
||||
//Mark facets that are inside the domain bounded by the polygon
|
||||
CGAL::mark_domain_in_triangulation(cdt, in_domain);
|
||||
|
||||
// loop on all the triangles ("faces" in triangulation doc)
|
||||
for (Face_handle f : cdt.finite_face_handles()) {
|
||||
// if the current triangles is not inside the polygon -> skip it
|
||||
if (! get(in_domain, f)) continue;
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
auto tp = f->vertex(i)->point();
|
||||
auto tp3 = plane.to_3d(tp);
|
||||
QVector3D p3(tp3.x(), tp3.y(), tp3.z());
|
||||
p3.normalize();
|
||||
triangles.push_back(p3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return triangles;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
Country_triangles_map
|
||||
Aos_triangulator::get_by_country(Aos::Arr_handle arrh, float error,
|
||||
std::size_t num_uniform_points) {
|
||||
|
||||
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using Pnt_2 = typename K::Point_2;
|
||||
using Pnt_3 = typename K::Point_3;
|
||||
using Vb = CGAL::Triangulation_vertex_base_2<K>;
|
||||
using Fb = CGAL::Constrained_triangulation_face_base_2<K>;
|
||||
using TDS = CGAL::Triangulation_data_structure_2<Vb, Fb>;
|
||||
using Itag = CGAL::Exact_predicates_tag;
|
||||
using CDT = CGAL::Constrained_Delaunay_triangulation_2<K, TDS, Itag>;
|
||||
using Face_handle = CDT::Face_handle;
|
||||
using Approximate_point_2 = Geom_traits::Approximate_point_2;
|
||||
using Aos = Countries_arr;
|
||||
using Aos_pnt = Aos::Point_2;
|
||||
|
||||
auto& arr = *reinterpret_cast<Aos*>(arrh.get());
|
||||
auto approx = s_traits.approximate_2_object();
|
||||
|
||||
// group the faces by their country name
|
||||
using Face_const_handle = Countries_arr::Face_const_handle;
|
||||
std::map<std::string, std::vector<Face_const_handle>> country_faces_map;
|
||||
for (auto fh : arr.face_handles()) {
|
||||
const auto& country_name = fh->data();
|
||||
// skipping spherical-face
|
||||
if (country_name.empty()) continue;
|
||||
country_faces_map[country_name].push_back(fh);
|
||||
}
|
||||
|
||||
// Generate random point uniformly distributed
|
||||
std::vector<Pnt_3> rps;
|
||||
rps.reserve(num_uniform_points);
|
||||
CGAL::Random_points_in_sphere_3<Pnt_3> g(1.0);
|
||||
std::copy_n(g, rps.capacity(), std::back_inserter(rps));
|
||||
std::map<Face_const_handle, std::vector<Pnt_3>> face_random_points;
|
||||
using Point_location_result = CGAL::Arr_point_location_result<Aos>;
|
||||
using Query_result = std::pair<Aos_pnt, Point_location_result::Type>;
|
||||
std::vector<Aos_pnt> rqs(rps.size());
|
||||
auto ctr_p = arr.geometry_traits()->construct_point_2_object();
|
||||
std::transform(rps.begin(), rps.end(), rqs.begin(),
|
||||
[&](const Pnt_3& rp) -> Aos_pnt {
|
||||
return ctr_p(rp.x(), rp.y(), rp.z());
|
||||
});
|
||||
std::list<Query_result> results;
|
||||
CGAL::locate(arr, rqs.begin(), rqs.end(), std::back_inserter(results));
|
||||
for (auto& [q, res] : results) {
|
||||
const Aos::Face_const_handle* f;
|
||||
if ((f = std::get_if<Face_const_handle>(&res))) {
|
||||
auto x = CGAL::to_double(q.dx());
|
||||
auto y = CGAL::to_double(q.dy());
|
||||
auto z = CGAL::to_double(q.dz());
|
||||
face_random_points[*f].push_back(Pnt_3(x, y, z));
|
||||
}
|
||||
}
|
||||
|
||||
// Triangulate the faces
|
||||
Country_triangles_map result;
|
||||
for (auto& [country_name, fhs] : country_faces_map) {
|
||||
// std::cout << "processing country " << country_name << std::endl;
|
||||
auto& triangles = result[country_name];
|
||||
// CONVERT the face-points to QVector3D
|
||||
for (auto fh : fhs) {
|
||||
// skip any face with no OUTER-CCB
|
||||
if (0 == fh->number_of_outer_ccbs()) continue;
|
||||
|
||||
std::vector<QVector3D> face_points;
|
||||
// Loop on the egdes of the current outer-ccb
|
||||
auto first = fh->outer_ccb();
|
||||
auto curr = first;
|
||||
do {
|
||||
std::vector<Approximate_point_2> apx_points;
|
||||
const auto& xcv = curr->curve();
|
||||
approx(xcv, error, std::back_insert_iterator(apx_points),
|
||||
curr->direction() == CGAL::ARR_LEFT_TO_RIGHT);
|
||||
for (auto it = apx_points.begin(); it != apx_points.end()-1; ++it) {
|
||||
const auto& apx_p = *it;
|
||||
const QVector3D p(apx_p.dx(), apx_p.dy(), apx_p.dz());
|
||||
face_points.push_back(p);
|
||||
}
|
||||
} while (++curr != first);
|
||||
|
||||
// no need to triangulate if the number of points is 3
|
||||
if (face_points.size() == 3) {
|
||||
triangles.insert(triangles.end(), face_points.begin(),
|
||||
face_points.end());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate the centroid of all face-points
|
||||
QVector3D centroid(0, 0, 0);
|
||||
for (const auto& fp : face_points) centroid += fp;
|
||||
centroid /= face_points.size();
|
||||
centroid.normalize();
|
||||
auto normal = centroid;
|
||||
|
||||
Pnt_3 plane_origin(centroid.x(), centroid.y(), centroid.z());
|
||||
K::Vector_3 plane_normal(normal.x(), normal.y(), normal.z());
|
||||
K::Plane_3 plane(plane_origin, plane_normal);
|
||||
|
||||
// Project all points onto the plane
|
||||
std::vector<Pnt_2> planar_points(face_points.size());
|
||||
std::transform(face_points.begin(), face_points.end(),
|
||||
planar_points.begin(),
|
||||
[&](const QVector3D& fp) -> Pnt_2 {
|
||||
// define a ray through the origin and the current point
|
||||
Pnt_3 p3(fp.x(), fp.y(), fp.z());
|
||||
K::Ray_3 ray(CGAL::ORIGIN, p3);
|
||||
auto intersection = CGAL::intersection(plane, ray);
|
||||
if (! intersection.has_value())
|
||||
std::cout << "INTERSECTION ASSERTION ERROR!!!\n";
|
||||
auto ip = std::get<Pnt_3>(intersection.value());
|
||||
return plane.to_2d(ip);
|
||||
});
|
||||
CDT cdt;
|
||||
|
||||
// Insert points uniformly distributed into the triangulation
|
||||
auto it = face_random_points.find(fh);
|
||||
if (it != face_random_points.end()) {
|
||||
const auto& points = it->second;
|
||||
for (const auto& p3 : points) {
|
||||
K::Ray_3 ray(CGAL::ORIGIN, p3);
|
||||
auto intersection = CGAL::intersection(plane, ray);
|
||||
if (! intersection.has_value())
|
||||
std::cout << "INTERSECTION ASSERTION ERROR!!!\n";
|
||||
auto ip = std::get<Pnt_3>(intersection.value());
|
||||
auto p2 = plane.to_2d(ip);
|
||||
cdt.insert(p2);
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the constraints into the triangulation
|
||||
cdt.insert_constraint(planar_points.begin(), planar_points.end(), true);
|
||||
|
||||
// Mark facets that are inside the domain bounded by the polygon
|
||||
std::unordered_map<Face_handle, bool> in_domain_map;
|
||||
boost::associative_property_map< std::unordered_map<Face_handle, bool>>
|
||||
in_domain(in_domain_map);
|
||||
CGAL::mark_domain_in_triangulation(cdt, in_domain);
|
||||
|
||||
// Loop on all the triangles ("faces" in triangulation doc)
|
||||
for (Face_handle f : cdt.finite_face_handles()) {
|
||||
// If the current triangles is not inside the polygon -> skip it
|
||||
if (! get(in_domain, f)) continue;
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
auto tp = f->vertex(i)->point();
|
||||
auto tp3 = plane.to_3d(tp);
|
||||
QVector3D p3(tp3.x(), tp3.y(), tp3.z());
|
||||
p3.normalize();
|
||||
triangles.push_back(p3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// 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 AOS_TRIANGULATOR_H
|
||||
#define AOS_TRIANGULATOR_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <qvector3d.h>
|
||||
|
||||
#include "Aos.h"
|
||||
|
||||
using Country_triangles_map = std::map<std::string, std::vector<QVector3D>>;
|
||||
|
||||
class Aos_triangulator {
|
||||
public:
|
||||
static std::vector<QVector3D> get_all(Aos::Arr_handle arrh);
|
||||
|
||||
static Country_triangles_map get_by_country(Aos::Arr_handle arrh,
|
||||
float error,
|
||||
std::size_t num_uniform_points);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
# This is the CMake script for compiling a CGAL application.
|
||||
|
||||
cmake_minimum_required(VERSION 3.1...3.23)
|
||||
project(Arrangement_on_surface_2_earth_Demo)
|
||||
|
||||
if(NOT POLICY CMP0070 AND POLICY CMP0053)
|
||||
# Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning.
|
||||
cmake_policy(SET CMP0053 OLD)
|
||||
endif()
|
||||
|
||||
if(POLICY CMP0071)
|
||||
cmake_policy(SET CMP0071 NEW)
|
||||
endif()
|
||||
|
||||
find_package(Qt6 QUIET COMPONENTS Core Gui OpenGL OpenGLWidgets Widgets Xml)
|
||||
find_package(CGAL COMPONENTS Qt6)
|
||||
find_package(nlohmann_json 3.9)
|
||||
|
||||
if (NOT CGAL_FOUND OR NOT CGAL_Qt6_FOUND OR NOT Qt6_FOUND OR NOT Boost_FOUND OR NOT nlohmann_json_FOUND)
|
||||
if (NOT CGAL_FOUND)
|
||||
set(MISSING_DEPS "the CGAL library, ${MISSING_DEPS}")
|
||||
endif()
|
||||
if (NOT CGAL_Qt6_FOUND)
|
||||
set(MISSING_DEPS "the CGAL Qt6 component, ${MISSING_DEPS}")
|
||||
endif()
|
||||
if (NOT Qt6_FOUND)
|
||||
set(MISSING_DEPS "the Qt6 library, ${MISSING_DEPS}")
|
||||
endif()
|
||||
if (NOT Boost_FOUND)
|
||||
set(MISSING_DEPS "the Boost library, ${MISSING_DEPS}")
|
||||
endif()
|
||||
if (NOT nlohmann_json_FOUND)
|
||||
set(MISSING_DEPS "JSON for Modern C++ 3.9+ (know as nlohmann_json), ${MISSING_DEPS}")
|
||||
endif()
|
||||
|
||||
message(STATUS "This project requires ${MISSING_DEPS} and will not be compiled.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
add_definitions(-DQT_NO_VERSION_TAGGING)
|
||||
|
||||
# AOS
|
||||
file(GLOB source_files_aos Aos.h Aos.cpp Aos_defs.h
|
||||
Aos_triangulator.h Aos_triangulator.cpp)
|
||||
source_group("Aos" FILES ${source_files_aos})
|
||||
|
||||
# GIS
|
||||
file(GLOB source_files_gis Kml_reader.h Kml_reader.cpp)
|
||||
source_group("GIS" FILES ${source_files_gis})
|
||||
|
||||
# GRAPHICS
|
||||
file(GLOB source_files_graphics Camera.h Camera.cpp
|
||||
Shader_program.h Shader_program.cpp)
|
||||
source_group("Graphics" FILES ${source_files_graphics})
|
||||
|
||||
# GRAPHICS-GEOMETRY (Graphics-related)
|
||||
file(GLOB source_files_graphics_geometry
|
||||
Line_strips.h Line_strips.cpp
|
||||
Single_vertex.h Single_vertex.cpp
|
||||
Sphere.h Sphere.cpp
|
||||
Triangles.h Triangles.cpp
|
||||
Vertices.h Vertices.cpp
|
||||
World_coordinate_axes.h World_coordinate_axes.cpp)
|
||||
source_group("Graphics_Geometry" FILES ${source_files_graphics_geometry})
|
||||
|
||||
# GUI
|
||||
file(GLOB source_files_gui
|
||||
Camera_manip.h Camera_manip.cpp
|
||||
Camera_manip_rot.h Camera_manip_rot.cpp
|
||||
Camera_manip_rot_bpa.h Camera_manip_rot_bpa.cpp
|
||||
Camera_manip_zoom.h Camera_manip_zoom.cpp
|
||||
GUI_country_pick_handler.h GUI_country_pick_handler.cpp
|
||||
GUI_event_handler.h GUI_event_handler.cpp)
|
||||
source_group("GUI" FILES ${source_files_gui})
|
||||
|
||||
#SOURCE FILES (NOT CATEGORIZED YET)
|
||||
file(GLOB source_files Common_defs.h earth.cpp Timer.h
|
||||
Main_widget.h Main_widget.cpp
|
||||
Message_manager.h Message_manager.cpp
|
||||
Tools.h Tools.cpp
|
||||
Verification.h Verification.cpp)
|
||||
source_group("Source Files" FILES ${source_files})
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
qt_add_executable(earth
|
||||
${source_files_aos}
|
||||
${source_files_gis}
|
||||
${source_files_graphics}
|
||||
${source_files_graphics_geometry}
|
||||
${source_files_gui}
|
||||
${source_files}
|
||||
)
|
||||
|
||||
set_target_properties(earth PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE")
|
||||
endif (MSVC)
|
||||
|
||||
target_link_libraries(earth PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::OpenGL
|
||||
Qt6::OpenGLWidgets
|
||||
Qt6::Widgets
|
||||
Qt6::Xml
|
||||
CGAL::CGAL
|
||||
CGAL::Data
|
||||
nlohmann_json::nlohmann_json)
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/shaders
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# install(TARGETS earth
|
||||
# RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
# BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
# LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
# )
|
||||
|
||||
add_to_cached_list(CGAL_EXECUTABLE_TARGETS earth)
|
||||
include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake)
|
||||
cgal_add_compilation_test(earth)
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
// 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>
|
||||
|
||||
#include "Camera.h"
|
||||
|
||||
//! \brief
|
||||
Camera::Camera() :
|
||||
m_ux(1, 0, 0),
|
||||
m_uy(0, 1, 0),
|
||||
m_uz(0, 0, 1)
|
||||
{}
|
||||
|
||||
//! \brief
|
||||
void Camera::perspective(qreal fov, qreal aspect, qreal z_near, qreal z_far) {
|
||||
m_z_near = z_near;
|
||||
m_z_far = z_far;
|
||||
|
||||
m_projection.setToIdentity();
|
||||
m_projection.perspective(fov, aspect, z_near, z_far);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
QMatrix4x4 Camera::get_view_matrix() const {
|
||||
QMatrix4x4 view;
|
||||
const QVector3D center = m_pos - m_uz;
|
||||
view.lookAt(m_pos, center, m_uy);
|
||||
return view;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Camera::rotate_from_init_config(float theta, float phi) {
|
||||
// TO-DO: use the following logic to eliminate the QT-deprecation warnings!
|
||||
//QMatrix4x4 rot;
|
||||
//rot.rotate(theta, m_ux);
|
||||
//auto pos = m_pos.toVector4D(); pos.setW(1);
|
||||
//auto uy = m_uy.toVector4D(); uy.setW(0);
|
||||
//auto uz = m_uz.toVector4D(); uz.setW(0);
|
||||
|
||||
//pos = pos * rot;
|
||||
//uy = uy * rot;
|
||||
//uz = uz * rot;
|
||||
|
||||
//m_pos = pos.toVector3D();
|
||||
//m_uy = uy.toVector3D();
|
||||
//m_uz = uz.toVector3D();
|
||||
|
||||
QMatrix4x4 r1;
|
||||
QVector3D ey(0, 1, 0);
|
||||
r1.rotate(theta, ey);
|
||||
|
||||
// rx = rotated x axis
|
||||
auto rx = r1.map(QVector3D(1, 0, 0));
|
||||
QMatrix4x4 r2;
|
||||
r2.rotate(phi, rx);
|
||||
|
||||
// total rotation:
|
||||
auto r = r2 * r1;
|
||||
|
||||
const auto dist_cam_to_origin = m_pos.length();
|
||||
m_pos = r.map(QVector3D(0, 0, dist_cam_to_origin));
|
||||
m_ux = r.map(QVector3D(1, 0, 0)); // should be the same as rx (sanity check?)
|
||||
m_uy = r.map(QVector3D(0, 1, 0));
|
||||
m_uz = r.map(QVector3D(0, 0, 1));
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Camera::rotate(QMatrix4x4 rot) {
|
||||
m_pos = rot.map(m_pos);
|
||||
m_ux = rot.map(m_ux);
|
||||
m_uy = rot.map(m_uy);
|
||||
m_uz = rot.map(m_uz);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Camera::save_config() {
|
||||
m_saved_pos = m_pos;
|
||||
m_saved_ux = m_ux;
|
||||
m_saved_uy = m_uy;
|
||||
m_saved_uz = m_uz;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Camera::rotate_from_saved_config(QMatrix4x4 rot) {
|
||||
m_pos = rot.map(m_saved_pos);
|
||||
m_ux = rot.map(m_saved_ux);
|
||||
m_uy = rot.map(m_saved_uy);
|
||||
m_uz = rot.map(m_saved_uz);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Camera::move_forward(float distance) {
|
||||
// recall that in OpenGL camera model, camera's z-axis points always
|
||||
// out of the screen (towards the user).
|
||||
m_pos -= distance * m_uz;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// 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 CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
#include <qvector3d.h>
|
||||
#include <qmatrix4x4.h>
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
Camera();
|
||||
|
||||
void set_pos(const QVector3D& pos) { m_pos = pos; }
|
||||
void set_pos(float x, float y, float z) { m_pos = QVector3D(x,y,z); }
|
||||
const QVector3D& get_pos() const { return m_pos; }
|
||||
|
||||
void perspective(qreal fov, qreal aspect_ratio, qreal z_near, qreal z_far);
|
||||
|
||||
qreal get_z_near() const { return m_z_near; }
|
||||
QMatrix4x4 get_view_matrix() const;
|
||||
QMatrix4x4 get_projection_matrix() const { return m_projection; }
|
||||
|
||||
// theta: angle around y-axis
|
||||
// phi: angle from the xz-plane (= rotated x-axis after the above rotation)
|
||||
void rotate_from_init_config(float theta, float phi);
|
||||
void rotate(QMatrix4x4 rot);
|
||||
|
||||
// save config & rotate from saved config (move to separate class?)
|
||||
void save_config();
|
||||
void rotate_from_saved_config(QMatrix4x4 rot);
|
||||
|
||||
// move the camera forward around its own z-axis
|
||||
void move_forward(float distance);
|
||||
|
||||
private:
|
||||
QVector3D m_pos;
|
||||
QVector3D m_ux;
|
||||
QVector3D m_uy;
|
||||
QVector3D m_uz;
|
||||
|
||||
QVector3D m_saved_pos;
|
||||
QVector3D m_saved_ux;
|
||||
QVector3D m_saved_uy;
|
||||
QVector3D m_saved_uz;
|
||||
|
||||
qreal m_z_near, m_z_far;
|
||||
|
||||
QMatrix4x4 m_projection;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// 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>
|
||||
|
||||
#include "Camera_manip.h"
|
||||
|
||||
Camera_manip::Camera_manip(Camera& camera) : m_camera(camera) {}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// 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 CAMERA_MANIP_H
|
||||
#define CAMERA_MANIP_H
|
||||
|
||||
#include <qevent.h>
|
||||
#include <qvector2d.h>
|
||||
|
||||
#include "Camera.h"
|
||||
#include "GUI_event_handler.h"
|
||||
|
||||
class Camera_manip : public GUI_event_handler {
|
||||
public:
|
||||
Camera_manip(Camera& camera);
|
||||
|
||||
protected:
|
||||
Camera& m_camera;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// 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>
|
||||
|
||||
#include "Camera_manip_rot.h"
|
||||
|
||||
Camera_manip_rot::Camera_manip_rot(Camera& camera) : Camera_manip(camera) {}
|
||||
|
||||
void Camera_manip_rot::mouse_move_event(QMouseEvent* /* e */) {
|
||||
if (m_left_mouse_button_down) {
|
||||
const float rotation_scale_factor = 0.1f;
|
||||
m_theta += rotation_scale_factor * m_diff.x();
|
||||
m_phi += rotation_scale_factor * m_diff.y();
|
||||
m_camera.rotate_from_init_config(-m_theta, -m_phi);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// 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 CAMERA_MANIP_ROT_H
|
||||
#define CAMERA_MANIP_ROT_H
|
||||
|
||||
#include <qevent.h>
|
||||
#include <qvector2d.h>
|
||||
|
||||
#include "Camera_manip.h"
|
||||
|
||||
class Camera_manip_rot : public Camera_manip {
|
||||
public:
|
||||
Camera_manip_rot(Camera& camera);
|
||||
|
||||
protected:
|
||||
virtual void mouse_move_event(QMouseEvent* e) override;
|
||||
|
||||
private:
|
||||
float m_theta = 0;
|
||||
float m_phi = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// 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>
|
||||
|
||||
#include "Camera_manip_rot_bpa.h"
|
||||
|
||||
//! \brief
|
||||
Camera_manip_rot_bpa::Camera_manip_rot_bpa(Camera& 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();
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Camera_manip_rot_bpa::mouse_move_event(QMouseEvent* /* e */) {
|
||||
const float rotation_scale_factor = 0.1f;
|
||||
|
||||
// ROTATION AROUND AN AXIS ORTHOGONAL TO THE BACKPROJECTED DIF-VECTOR
|
||||
//QVector3D p0(m_last_mouse_pos.x(), m_vp_height - m_last_mouse_pos.y(), 0);
|
||||
QVector3D p0(m_mouse_press_pos.x(), m_vp_height - m_mouse_press_pos.y(), 0);
|
||||
QVector3D p1(m_current_mouse_pos.x(), m_vp_height - m_current_mouse_pos.y(), 0);
|
||||
auto dp = p1 - p0; // difference vector in OpenGL window coords.
|
||||
QVector3D rdp(-dp.y(), dp.x(), 0); // rotate diff-vector CCW by 90-deg
|
||||
QVector3D rp = p0 + rdp; // r1 rotated CCW by 90 deg
|
||||
|
||||
QMatrix4x4 model; // this is different from Sphere's model matrix!!!
|
||||
auto proj = m_camera.get_projection_matrix();
|
||||
auto view = m_camera.get_view_matrix();
|
||||
auto model_view = view * model;
|
||||
QRect viewport(0, 0, m_vp_width, m_vp_height);
|
||||
auto wp0 = p0.unproject(model_view, proj, viewport);
|
||||
auto wrp = rp.unproject(model_view, proj, viewport);
|
||||
|
||||
// rotation axis & angle
|
||||
auto rot_axis = wrp - wp0;
|
||||
rot_axis.normalize();
|
||||
const auto rot_angle = rotation_scale_factor * dp.length();
|
||||
|
||||
QMatrix4x4 rot_matrix;
|
||||
rot_matrix.rotate(-rot_angle, rot_axis);
|
||||
|
||||
m_camera.rotate_from_saved_config(rot_matrix);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Camera_manip_rot_bpa::mouse_release_event(QMouseEvent* /* e */) {}
|
||||
|
||||
//! \brief
|
||||
void Camera_manip_rot_bpa::resize(int w, int h) {
|
||||
m_vp_width = w;
|
||||
m_vp_height = h;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 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 CAMERA_MANIP_ROT_BPA_H
|
||||
#define CAMERA_MANIP_ROT_BPA_H
|
||||
|
||||
#include <qevent.h>
|
||||
#include <qvector2d.h>
|
||||
|
||||
#include "Camera_manip.h"
|
||||
|
||||
class Camera_manip_rot_bpa : public Camera_manip {
|
||||
public:
|
||||
Camera_manip_rot_bpa(Camera& camera);
|
||||
|
||||
protected:
|
||||
virtual void mouse_press_event(QMouseEvent* e) override;
|
||||
virtual void mouse_move_event(QMouseEvent* e) override;
|
||||
virtual void mouse_release_event(QMouseEvent* e) override;
|
||||
virtual void resize(int w, int h) override;
|
||||
|
||||
private:
|
||||
int m_vp_width, m_vp_height;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// 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>
|
||||
|
||||
#include "Camera_manip_zoom.h"
|
||||
|
||||
#include "Message_manager.h"
|
||||
|
||||
Camera_manip_zoom::Camera_manip_zoom(Camera& camera) : Camera_manip(camera) {}
|
||||
|
||||
//! \brief
|
||||
void Camera_manip_zoom::mouse_move_event(QMouseEvent* /* e */) {
|
||||
if (m_middle_mouse_button_down) {
|
||||
const float zoom_scale_factor = 0.01f;
|
||||
const auto distance = zoom_scale_factor * m_diff.y();
|
||||
m_camera.move_forward(distance);
|
||||
}
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Camera_manip_zoom::mouse_release_event(QMouseEvent* e) {
|
||||
if (e->button() == Qt::MiddleButton)
|
||||
Message_manager::notify_all("zoom_changed");
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// 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 CAMERA_MANIP_ZOOM_H
|
||||
#define CAMERA_MANIP_ZOOM_H
|
||||
|
||||
#include <qevent.h>
|
||||
#include <qvector2d.h>
|
||||
|
||||
#include "Camera_manip.h"
|
||||
|
||||
class Camera_manip_zoom : public Camera_manip {
|
||||
public:
|
||||
Camera_manip_zoom(Camera& camera);
|
||||
|
||||
protected:
|
||||
virtual void mouse_move_event(QMouseEvent* e) override;
|
||||
virtual void mouse_release_event(QMouseEvent* e) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// 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 COMMON_DEFS_H
|
||||
#define COMMON_DEFS_H
|
||||
|
||||
#include <qopenglfunctions_3_3_core.h>
|
||||
//#include <qopenglfunctions_4_5_core.h>
|
||||
|
||||
using OpenGLFunctionsBase = QOpenGLFunctions_3_3_Core;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
// 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>
|
||||
|
||||
#include "GUI_country_pick_handler.h"
|
||||
|
||||
//#include <qvector3d.h>
|
||||
|
||||
//! \brief
|
||||
GUI_country_pick_handler::GUI_country_pick_handler(Main_widget& main_widget) :
|
||||
m_main_widget(main_widget),
|
||||
m_camera(main_widget.get_camera())
|
||||
{}
|
||||
|
||||
//! \brief
|
||||
void GUI_country_pick_handler::mouse_press_event(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_main_widget.get_model_matrix();
|
||||
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_main_widget.set_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;
|
||||
auto pos = o + ti * u;
|
||||
m_main_widget.set_mouse_pos(pos);
|
||||
static std::string prev_picked_country;
|
||||
auto& arrh = m_main_widget.get_arr_handle();
|
||||
auto picked_country = Aos::locate_country(arrh, pos);
|
||||
|
||||
m_main_widget.hightlight_country(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 (!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;
|
||||
}
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void GUI_country_pick_handler::resize(int w, int h) {
|
||||
m_vp_width = w;
|
||||
m_vp_height = h;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// 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 GUI_COUNTRY_PICK_HANDLER_H
|
||||
#define GUI_COUNTRY_PICK_HANDLER_H
|
||||
|
||||
#include <qevent.h>
|
||||
#include <qvector2d.h>
|
||||
|
||||
#include "GUI_event_handler.h"
|
||||
#include "Main_widget.h"
|
||||
|
||||
class GUI_country_pick_handler : public GUI_event_handler {
|
||||
public:
|
||||
GUI_country_pick_handler(Main_widget& main_widget);
|
||||
|
||||
protected:
|
||||
virtual void mouse_press_event(QMouseEvent* e) override;
|
||||
virtual void resize(int w, int h) override;
|
||||
|
||||
Main_widget& m_main_widget;
|
||||
Camera& m_camera;
|
||||
int m_vp_width;
|
||||
int m_vp_height;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
// 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>
|
||||
|
||||
#include "GUI_event_handler.h"
|
||||
|
||||
//! \brief
|
||||
void
|
||||
GUI_event_handler::set_mouse_button_pressed_flag(QMouseEvent* e, bool flag) {
|
||||
switch (e->button()) {
|
||||
case Qt::LeftButton:
|
||||
m_left_mouse_button_down = flag;
|
||||
break;
|
||||
|
||||
case Qt::MiddleButton:
|
||||
m_middle_mouse_button_down = flag;
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void GUI_event_handler::mousePressEvent(QMouseEvent* e) {
|
||||
set_mouse_button_pressed_flag(e, true);
|
||||
m_mouse_press_pos = m_last_mouse_pos = QVector2D(e->position());
|
||||
|
||||
// call the function overridden by the derived class
|
||||
mouse_press_event(e);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void GUI_event_handler::mouseMoveEvent(QMouseEvent* e) {
|
||||
m_current_mouse_pos = QVector2D(e->position());
|
||||
m_diff = m_current_mouse_pos - m_last_mouse_pos;
|
||||
|
||||
// call the function overridden by the derived class
|
||||
mouse_move_event(e);
|
||||
|
||||
m_last_mouse_pos = m_current_mouse_pos;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void GUI_event_handler::mouseReleaseEvent(QMouseEvent* e) {
|
||||
set_mouse_button_pressed_flag(e, false);
|
||||
|
||||
// call the function overridden by the derived class
|
||||
mouse_release_event(e);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void GUI_event_handler::resizeGL(int w, int h) { resize(w, h); }
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// 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 GUI_EVENT_HANDLER_H
|
||||
#define GUI_EVENT_HANDLER_H
|
||||
|
||||
#include <qevent.h>
|
||||
#include <qvector2d.h>
|
||||
|
||||
class GUI_event_handler {
|
||||
public:
|
||||
virtual ~GUI_event_handler() {};
|
||||
|
||||
void mousePressEvent(QMouseEvent* e);
|
||||
void mouseMoveEvent(QMouseEvent* e);
|
||||
void mouseReleaseEvent(QMouseEvent* e);
|
||||
void resizeGL(int w, int h);
|
||||
|
||||
protected:
|
||||
void set_mouse_button_pressed_flag(QMouseEvent* e, bool flag);
|
||||
|
||||
virtual void mouse_press_event(QMouseEvent* /* e */) {}
|
||||
virtual void mouse_move_event(QMouseEvent* /* e */) {}
|
||||
virtual void mouse_release_event(QMouseEvent* /* e */) {}
|
||||
virtual void resize(int /* w */, int /* h */) {}
|
||||
|
||||
bool m_left_mouse_button_down = false;
|
||||
bool m_middle_mouse_button_down = false;
|
||||
QVector2D m_current_mouse_pos;
|
||||
QVector2D m_last_mouse_pos;
|
||||
QVector2D m_mouse_press_pos;
|
||||
QVector2D m_diff;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
// 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>
|
||||
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#include <qmath.h>
|
||||
#include <qvector3d.h>
|
||||
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Arrangement_on_surface_2.h>
|
||||
#include <CGAL/Arr_geodesic_arc_on_sphere_traits_2.h>
|
||||
#include <CGAL/Arr_spherical_topology_traits_2.h>
|
||||
#include <CGAL/Vector_3.h>
|
||||
|
||||
#include "arr_print.h"
|
||||
#include "Geodesic_arcs.h"
|
||||
|
||||
using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
using Geom_traits = CGAL::Arr_geodesic_arc_on_sphere_traits_2<Kernel>;
|
||||
using Point = Geom_traits::Point_2;
|
||||
using Curve = Geom_traits::Curve_2;
|
||||
using Topol_traits = CGAL::Arr_spherical_topology_traits_2<Geom_traits>;
|
||||
using Arrangement = CGAL::Arrangement_on_surface_2<Geom_traits, Topol_traits>;
|
||||
|
||||
using Dir3 = Kernel::Direction_3;
|
||||
std::ostream& operator << (std::ostream& os, const Dir3& d) {
|
||||
os << d.dx() << ", " << d.dy() << ", " << d.dz();
|
||||
return os;
|
||||
}
|
||||
|
||||
using Approximate_point_2 = Geom_traits::Approximate_point_2;
|
||||
std::ostream& operator << (std::ostream& os, const Approximate_point_2& d) {
|
||||
os << d.dx() << ", " << d.dy() << ", " << d.dz();
|
||||
return os;
|
||||
}
|
||||
|
||||
using Approximate_number_type = Geom_traits::Approximate_number_type;
|
||||
using Approximate_kernel = Geom_traits::Approximate_kernel;
|
||||
using Approximate_Vector_3 = CGAL::Vector_3<Approximate_kernel>;
|
||||
using Approximate_Direction_3 = Approximate_kernel::Direction_3;
|
||||
using Direction_3 = Kernel::Direction_3;
|
||||
|
||||
std::ostream& operator << (std::ostream& os, const Approximate_Vector_3& v) {
|
||||
os << v.x() << ", " << v.y() << ", " << v.z();
|
||||
//os << v.hx() << ", " << v.hy() << ", " << v.hz() << ", " << v.hw();
|
||||
return os;
|
||||
}
|
||||
|
||||
auto Geodesic_arcs::get_approx_arcs(double error) -> Approx_arcs {
|
||||
// Construct the arrangement from 12 geodesic arcs.
|
||||
Geom_traits traits;
|
||||
Arrangement arr(&traits);
|
||||
|
||||
auto ctr_p = traits.construct_point_2_object();
|
||||
auto ctr_cv = traits.construct_curve_2_object();
|
||||
|
||||
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, 0, 1)));
|
||||
xcvs.push_back(ctr_cv(ctr_p(0, 1, 0), ctr_p(0, 0, 1)));
|
||||
//xcvs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, 1, 0), Dir3(0, 0, -1)));
|
||||
//xcvs.push_back(ctr_cv(Dir3(0, 0, -1)));
|
||||
|
||||
auto approx = traits.approximate_2_object();
|
||||
|
||||
std::vector<std::vector<QVector3D>> arcs;
|
||||
for (const auto& xcv : xcvs) {
|
||||
std::vector<Approximate_point_2> v;
|
||||
auto oi2 = approx(xcv, error, std::back_insert_iterator(v));
|
||||
|
||||
std::vector<QVector3D> arc_points;
|
||||
for (const auto& p : v) {
|
||||
const QVector3D arc_point(p.dx(), p.dy(), p.dz());
|
||||
arc_points.push_back(arc_point);
|
||||
}
|
||||
arcs.push_back(std::move(arc_points));
|
||||
}
|
||||
//std::cout << "offset count = " << m_arc_offsets.size() << std::endl;
|
||||
|
||||
return arcs;
|
||||
}
|
||||
|
||||
auto Geodesic_arcs::get_approx_arcs(const Kml::Placemark&
|
||||
placemark, double error) -> Approx_arcs {
|
||||
Geom_traits traits;
|
||||
auto ctr_p = traits.construct_point_2_object();
|
||||
auto ctr_cv = traits.construct_curve_2_object();
|
||||
|
||||
std::vector<Curve> xcvs;
|
||||
for (const auto& polygon : placemark.polygons) {
|
||||
// colect all rings into a single list (FOR NOW!!!)
|
||||
// TO-DO: PROCESS OUTER & INNER BOUNDARIES SEPARATELY!!!
|
||||
Kml::LinearRings linear_rings;
|
||||
linear_rings.push_back(polygon.outer_boundary);
|
||||
for (const auto& inner_boundary : polygon.inner_boundaries)
|
||||
linear_rings.push_back(inner_boundary);
|
||||
|
||||
|
||||
// convert the nodes to points on unit-sphere
|
||||
for (const auto& lring : linear_rings) {
|
||||
std::vector<Approximate_Vector_3> sphere_points;
|
||||
for (const auto& node : lring.nodes) {
|
||||
const auto p = node.get_coords_3d();
|
||||
Approximate_Vector_3 v(p.x, p.y, p.z);
|
||||
sphere_points.push_back(v);
|
||||
}
|
||||
|
||||
// add geodesic arcs for the current LinearRing
|
||||
int num_points = sphere_points.size();
|
||||
for (int i = 0; i < num_points - 1; ++i) {
|
||||
const auto p1 = sphere_points[i];
|
||||
const auto p2 = sphere_points[i + 1];
|
||||
xcvs.push_back(ctr_cv(ctr_p(p1.x(), p1.y(), p1.z()),
|
||||
ctr_p(p2.x(), p2.y(), p2.z())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto approx = traits.approximate_2_object();
|
||||
std::vector<std::vector<QVector3D>> arcs;
|
||||
for (const auto& xcv : xcvs) {
|
||||
std::vector<Approximate_point_2> v;
|
||||
auto oi2 = approx(xcv, error, std::back_insert_iterator(v));
|
||||
|
||||
std::vector<QVector3D> arc_points;
|
||||
for (const auto& p : v) {
|
||||
const QVector3D arc_point(p.dx(), p.dy(), p.dz());
|
||||
arc_points.push_back(arc_point);
|
||||
}
|
||||
arcs.push_back(std::move(arc_points));
|
||||
}
|
||||
//std::cout << "offset count = " << m_arc_offsets.size() << std::endl;
|
||||
|
||||
return arcs;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// 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
|
||||
#define GEODESIC_ARCS_H
|
||||
|
||||
#include <vector>
|
||||
#include <qvector3d.h>
|
||||
|
||||
#include "Kml_reader.h"
|
||||
|
||||
class Geodesic_arcs {
|
||||
public:
|
||||
using Approx_arcs = std::vector<std::vector<QVector3D>>;
|
||||
|
||||
Approx_arcs get_approx_arcs(double error);
|
||||
|
||||
// generate approximate arcs from KML data
|
||||
Approx_arcs get_approx_arcs(const Kml::Placemark& placemark, double error);
|
||||
Approx_arcs get_approx_arcs(const Kml::Placemarks& placemarks, double error);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,404 @@
|
|||
// 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>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <limits>
|
||||
|
||||
#include <qdebug.h>
|
||||
#include <qfile.h>
|
||||
#include <qxmlstream.h>
|
||||
|
||||
#include "Kml_reader.h"
|
||||
|
||||
//! \brief
|
||||
double Kml::Node::distance_to(const Node& r) const {
|
||||
const auto dx = lon - r.lon;
|
||||
const auto dy = lat - r.lat;
|
||||
return sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
bool Kml::Node::operator == (const Node& r) const
|
||||
{ return (lon == r.lon) && (lat == r.lat); }
|
||||
|
||||
//! \brief
|
||||
Kml::Vec3d Kml::Node::get_coords_3d(const double r) const {
|
||||
const long double phi = qDegreesToRadians(lat);
|
||||
const long double theta = qDegreesToRadians(lon);
|
||||
const auto z = r * std::sin(phi);
|
||||
const auto rxy = r * std::cos(phi);
|
||||
const auto x = rxy * std::cos(theta);
|
||||
const auto y = rxy * std::sin(theta);
|
||||
|
||||
return Vec3d{ (double)x, (double)y, (double)z };
|
||||
}
|
||||
|
||||
//! \brief
|
||||
QVector3D Kml::Node::get_coords_3f(const double r) const {
|
||||
const auto v = get_coords_3d(r);
|
||||
return QVector3D(v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
std::ostream& operator << (std::ostream& os, const Kml::Node& n) {
|
||||
os << n.lon << ", " << n.lat;
|
||||
return os;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
std::size_t Kml::get_number_of_polygons(Placemarks& placemarks) {
|
||||
std::size_t total_number_of_polygons = 0;
|
||||
for (auto& placemark : placemarks)
|
||||
total_number_of_polygons += placemark.polygons.size();
|
||||
return total_number_of_polygons;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
Kml::Placemarks Kml::read(const std::string& file_name) {
|
||||
LinearRing lring;
|
||||
Polygon polygon;
|
||||
Placemark placemark;
|
||||
Placemarks placemarks;
|
||||
|
||||
QFile file(file_name.c_str());
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
QXmlStreamReader xmlReader;
|
||||
xmlReader.setDevice(&file);
|
||||
|
||||
xmlReader.readNext();
|
||||
|
||||
// Reading from the file
|
||||
while (!xmlReader.isEndDocument()) {
|
||||
QString name = xmlReader.name().toString();
|
||||
|
||||
if (xmlReader.isStartElement()) {
|
||||
if (name == "Placemark") {
|
||||
placemark = Placemark{};
|
||||
}
|
||||
else if (name == "Polygon") {
|
||||
polygon = Polygon{};
|
||||
}
|
||||
else if (name == "LinearRing") {
|
||||
lring = LinearRing{};
|
||||
}
|
||||
else if (name == "coordinates") {
|
||||
xmlReader.readNext();
|
||||
auto str = xmlReader.text().toString();
|
||||
auto node_strs = str.split(" ");
|
||||
for (const auto& node_str : node_strs) {
|
||||
if (node_str.isEmpty()) continue;
|
||||
|
||||
auto coord_strs = node_str.split(",");
|
||||
const auto lon = coord_strs[0].toDouble();
|
||||
const auto lat = coord_strs[1].toDouble();
|
||||
lring.nodes.push_back(Node{ lon, lat });
|
||||
}
|
||||
}
|
||||
else if (name == "SimpleData") {
|
||||
auto attributes = xmlReader.attributes();
|
||||
auto attr_name = attributes[0].name().toString();
|
||||
auto attr_value = attributes[0].value().toString();
|
||||
if ((attr_name == "name") && (attr_value == "ADMIN"))
|
||||
{
|
||||
xmlReader.readNext();
|
||||
placemark.name = xmlReader.text().toString().toStdString();;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (xmlReader.isEndElement()) {
|
||||
if (name == "Placemark")
|
||||
{
|
||||
placemarks.push_back(std::move(placemark));
|
||||
}
|
||||
else if (name == "Polygon") {
|
||||
placemark.polygons.push_back(std::move(polygon));
|
||||
}
|
||||
else if (name == "outerBoundaryIs") {
|
||||
polygon.outer_boundary = std::move(lring);
|
||||
}
|
||||
else if (name == "innerBoundaryIs") {
|
||||
polygon.inner_boundaries.push_back(std::move(lring));
|
||||
}
|
||||
else if (name == "LinearRing") {
|
||||
// LinearRing is moved to the correct locations via other tags above
|
||||
assert(*lring.nodes.begin() == *(--lring.nodes.end()));
|
||||
}
|
||||
else if (name == "coordinates") {
|
||||
// no need to do anything here: the coordinates are read above!
|
||||
}
|
||||
}
|
||||
|
||||
xmlReader.readNext();
|
||||
}
|
||||
|
||||
if (xmlReader.hasError()) {
|
||||
std::cout << "XML error: " << xmlReader.errorString().data() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return placemarks;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
Kml::Nodes Kml::get_duplicates(const Placemarks& placemarks) {
|
||||
// collect all nodes into a single vector
|
||||
std::size_t polygon_count = 0;
|
||||
std::vector<Kml::Node> nodes;
|
||||
for (const auto& pm : placemarks) {
|
||||
for (const auto& polygon : pm.polygons) {
|
||||
++polygon_count;
|
||||
|
||||
Kml::LinearRings linear_rings;
|
||||
linear_rings.push_back(polygon.outer_boundary);
|
||||
for (const auto& inner_boundary : polygon.inner_boundaries)
|
||||
linear_rings.push_back(inner_boundary);
|
||||
|
||||
for(const auto& lring : linear_rings) {
|
||||
for (const auto& node : lring.nodes) nodes.push_back(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
qDebug() << "polygon count = " << polygon_count;
|
||||
|
||||
auto count = nodes.size();
|
||||
std::vector<std::size_t> num_duplicates(count, 0);
|
||||
qDebug() << "node count (with duplicates) = " << count;
|
||||
std::size_t dup_count = 0;
|
||||
|
||||
// this keeps track of how many nodes there are with certain dup-count
|
||||
std::unordered_map<std::size_t, std::size_t> dup_count_map;
|
||||
|
||||
Nodes duplicate_nodes;
|
||||
for (std::size_t i = 0; i < count; ++i) {
|
||||
// if the current node has been detected as duplicate skip it
|
||||
if (num_duplicates[i] > 0) continue;
|
||||
|
||||
const auto& curr_node = nodes[i];
|
||||
std::vector<std::size_t> curr_dup; // current set of duplicates
|
||||
for (std::size_t j = i + 1; j < count; ++j) {
|
||||
if (curr_node == nodes[j]) curr_dup.push_back(j);
|
||||
}
|
||||
|
||||
// if duplicates found
|
||||
if (!curr_dup.empty()) {
|
||||
++dup_count;
|
||||
std::size_t num_dup = curr_dup.size() + 1; // +1 for the i'th node
|
||||
num_duplicates[i] = num_dup;
|
||||
for (const auto di : curr_dup) num_duplicates[di] = num_dup;
|
||||
|
||||
duplicate_nodes.push_back(curr_node);
|
||||
dup_count_map[num_dup]++;
|
||||
}
|
||||
}
|
||||
qDebug() << "dup count = " << dup_count;
|
||||
for (const auto& p : dup_count_map) {
|
||||
const auto dup_count = p.first;
|
||||
const auto num_nodes_with_this_dup_count = p.second;
|
||||
qDebug() << dup_count << ": " << num_nodes_with_this_dup_count;
|
||||
}
|
||||
|
||||
return duplicate_nodes;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
Kml::Nodes Kml::generate_ids(Placemarks& placemarks) {
|
||||
// collect all nodes into a single vector
|
||||
// std::size_t polygon_count = 0;
|
||||
std::vector<Node> nodes;
|
||||
for (auto& pm : placemarks) {
|
||||
for (auto& polygon : pm.polygons) {
|
||||
// polygon_count++;
|
||||
|
||||
std::vector<LinearRing*> linear_rings;
|
||||
linear_rings.push_back(&polygon.outer_boundary);
|
||||
for (auto& inner_boundary : polygon.inner_boundaries)
|
||||
linear_rings.push_back(&inner_boundary);
|
||||
|
||||
for (auto* lring : linear_rings) {
|
||||
for (const auto& node : lring->nodes) {
|
||||
// check if the node is in the nodes
|
||||
auto it = std::find(nodes.begin(), nodes.end(), node);
|
||||
if (nodes.end() == it) {
|
||||
// insert new node
|
||||
nodes.push_back(node);
|
||||
const std::size_t node_id = nodes.size() - 1;
|
||||
lring->ids.push_back(node_id);
|
||||
}
|
||||
else {
|
||||
// get the existing node
|
||||
const std::size_t node_id = std::distance(nodes.begin(), it);
|
||||
lring->ids.push_back(node_id);
|
||||
assert(nodes[node_id] == node);
|
||||
}
|
||||
}
|
||||
|
||||
assert(lring->nodes.size() == lring->ids.size());
|
||||
for (std::size_t i = 0; i < lring->nodes.size(); ++i)
|
||||
assert(lring->nodes[i] == nodes[lring->ids[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
//! \breif
|
||||
Kml::Nodes Kml::generate_ids_approx(Placemarks& placemarks, const double eps) {
|
||||
// collect all nodes into a single vector
|
||||
// std::size_t polygon_count = 0;
|
||||
std::vector<Node> nodes;
|
||||
for (auto& pm : placemarks) {
|
||||
for (auto& polygon : pm.polygons) {
|
||||
// ++polygon_count;
|
||||
|
||||
std::vector<LinearRing*> linear_rings;
|
||||
linear_rings.push_back(&polygon.outer_boundary);
|
||||
for (auto& inner_boundary : polygon.inner_boundaries)
|
||||
linear_rings.push_back(&inner_boundary);
|
||||
|
||||
for (auto* lring : linear_rings) {
|
||||
lring->ids.clear();
|
||||
|
||||
for (const auto& node : lring->nodes) {
|
||||
// check if there is a node sufficiently close to the current one
|
||||
auto node_index = std::numeric_limits<std::size_t>::max();
|
||||
for (std::size_t i = 0; i < nodes.size(); ++i) {
|
||||
const auto dist = node.distance_to(nodes[i]);
|
||||
if (dist < eps) {
|
||||
node_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (node_index == std::numeric_limits<std::size_t>::max()) {
|
||||
// insert new node
|
||||
nodes.push_back(node);
|
||||
const auto node_id = nodes.size() - 1;
|
||||
lring->ids.push_back(node_id);
|
||||
}
|
||||
else {
|
||||
// get the existing node
|
||||
const auto node_id = node_index;
|
||||
lring->ids.push_back(node_id);
|
||||
}
|
||||
|
||||
auto it = std::unique(lring->ids.begin(), lring->ids.end());
|
||||
std::vector<std::size_t> new_ids(lring->ids.begin(), it);
|
||||
if (new_ids.size() < lring->ids.size())
|
||||
std::cout << "** REDUCED!\n";
|
||||
lring->ids = std::move(new_ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find the pair of closest nodes
|
||||
double min_dist = std::numeric_limits<double>::max();
|
||||
std::size_t ni1 = 0;
|
||||
std::size_t ni2 = 0;
|
||||
std::size_t num_nodes = nodes.size();
|
||||
for (std::size_t i = 0; i < num_nodes - 1; ++i) {
|
||||
for (std::size_t j = i + 1; j < num_nodes; ++j) {
|
||||
const auto dist = nodes[i].distance_to(nodes[j]);
|
||||
if (min_dist > dist) {
|
||||
min_dist = dist;
|
||||
ni1 = i;
|
||||
ni2 = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "min dist = " << min_dist << std::endl;
|
||||
std::cout << "node 1 = " << nodes[ni1] << std::endl;
|
||||
std::cout << "node 2 = " << nodes[ni2] << std::endl;
|
||||
std::cout << "node 1 = " << nodes[ni1].get_coords_3d() << std::endl;
|
||||
std::cout << "node 2 = " << nodes[ni2].get_coords_3d() << std::endl;
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
Kml::Nodes Kml::Polygon::get_all_nodes() const {
|
||||
Nodes all_nodes;
|
||||
auto source_first = outer_boundary.nodes.begin();
|
||||
auto source_last = outer_boundary.nodes.end();
|
||||
all_nodes.insert(all_nodes.begin(), source_first, source_last);
|
||||
|
||||
for (const auto& inner_boundary : inner_boundaries) {
|
||||
auto source_first = inner_boundary.nodes.begin();
|
||||
auto source_last = inner_boundary.nodes.end();
|
||||
all_nodes.insert(all_nodes.begin(), source_first, source_last);
|
||||
}
|
||||
|
||||
return all_nodes;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
std::vector<Kml::LinearRing*> Kml::Polygon::get_all_boundaries() {
|
||||
std::vector<LinearRing*> linear_rings;
|
||||
linear_rings.push_back(&outer_boundary);
|
||||
for (auto& inner_boundary : inner_boundaries)
|
||||
linear_rings.push_back(&inner_boundary);
|
||||
|
||||
return linear_rings;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
Kml::Nodes Kml::Placemark::get_all_nodes() const {
|
||||
Nodes all_nodes;
|
||||
for (const auto& polygon : polygons) {
|
||||
auto polygon_nodes = polygon.get_all_nodes();
|
||||
auto first = std::make_move_iterator(polygon_nodes.begin());
|
||||
auto last = std::make_move_iterator(polygon_nodes.end());
|
||||
all_nodes.insert(all_nodes.end(), first, last);
|
||||
}
|
||||
|
||||
return all_nodes;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
std::size_t Kml::Placemark::get_all_nodes_count() const {
|
||||
std::size_t num_nodes = 0;
|
||||
for (const auto& polygon : polygons) {
|
||||
auto polygon_nodes = polygon.get_all_nodes();
|
||||
num_nodes += polygon_nodes.size();
|
||||
}
|
||||
return num_nodes;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
Kml::Arcs Kml::LinearRing::get_arcs() const {
|
||||
Arcs arcs;
|
||||
const auto num_nodes = nodes.size();
|
||||
for (std::size_t i = 0; i < num_nodes - 1; ++i) {
|
||||
const auto from = nodes[i];
|
||||
const auto to = nodes[i + 1];
|
||||
arcs.push_back(Arc{ from, to });
|
||||
}
|
||||
return arcs;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Kml::LinearRing::get_arcs(Arcs& arcs) const {
|
||||
auto a = get_arcs();
|
||||
arcs.insert(arcs.end(), a.begin(), a.end());
|
||||
}
|
||||
|
||||
Kml::Arcs Kml::Placemark::get_all_arcs() const {
|
||||
Arcs all_arcs;
|
||||
|
||||
for (const auto& polygon : polygons) {
|
||||
polygon.outer_boundary.get_arcs(all_arcs);
|
||||
for (const auto& inner_boundary : polygon.inner_boundaries)
|
||||
inner_boundary.get_arcs(all_arcs);
|
||||
}
|
||||
|
||||
return all_arcs;
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
// 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 KML_READER_H
|
||||
#define KML_READER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <qvector3d.h>
|
||||
|
||||
class Kml {
|
||||
public:
|
||||
// double precision 3D-point (QVector3D has float coordinates)
|
||||
struct Vec3d {
|
||||
double x, y, z;
|
||||
|
||||
friend std::ostream& operator << (std::ostream& os, const Vec3d& v) {
|
||||
os << v.x << ", " << v.y << ", " << v.z;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
struct Node {
|
||||
double lon, lat;
|
||||
|
||||
Node() : lon(-1111), lat(-1111) {};
|
||||
Node(double longitude, double latitude) : lon(longitude), lat(latitude) {};
|
||||
|
||||
double distance_to(const Node& r) const;
|
||||
|
||||
bool operator == (const Node& r) const;
|
||||
Vec3d get_coords_3d(const double r = 1.0) const;
|
||||
QVector3D get_coords_3f(const double r=1.0) const;
|
||||
friend std::ostream& operator << (std::ostream& os, const Node& n);
|
||||
};
|
||||
using Nodes = std::vector<Node>;
|
||||
|
||||
struct Arc {
|
||||
Node from, to;
|
||||
};
|
||||
|
||||
using Arcs = std::vector<Arc>;
|
||||
|
||||
struct LinearRing {
|
||||
std::vector<Node> nodes;
|
||||
std::vector<std::size_t> ids;
|
||||
|
||||
Arcs get_arcs() const;
|
||||
void get_arcs(Arcs& arcs) const;
|
||||
};
|
||||
using LinearRings = std::vector<LinearRing>;
|
||||
|
||||
struct Polygon {
|
||||
LinearRing outer_boundary;
|
||||
LinearRings inner_boundaries;
|
||||
|
||||
// when collecting nodes start from the outer boundary and then get nodes
|
||||
// from individual inner boundaries in the order
|
||||
Nodes get_all_nodes() const;
|
||||
|
||||
std::vector<LinearRing*> get_all_boundaries();
|
||||
};
|
||||
|
||||
struct Placemark {
|
||||
std::vector<Polygon> polygons;
|
||||
std::string name;
|
||||
|
||||
// collects all nodes from all polygons
|
||||
Nodes get_all_nodes() const;
|
||||
std::size_t get_all_nodes_count() const;
|
||||
|
||||
Arcs get_all_arcs() const;
|
||||
};
|
||||
|
||||
using Placemarks = std::vector<Placemark>;
|
||||
|
||||
static std::size_t get_number_of_polygons(Placemarks& placemarks);
|
||||
|
||||
static Placemarks read(const std::string& file_name);
|
||||
|
||||
static Nodes get_duplicates(const Placemarks& placemarks);
|
||||
|
||||
|
||||
// Outputs all used nodes without duplications!
|
||||
// NOTE: this function modifies Placemarks data-structure!
|
||||
static Nodes generate_ids(Placemarks& placemarks);
|
||||
|
||||
// same as above but by collapsing close-by nodes based on distance bound
|
||||
static Nodes generate_ids_approx(Placemarks& placemarks, const double eps);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
// 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>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Line_strips.h"
|
||||
|
||||
//! \brief
|
||||
Line_strips::Line_strips(std::vector<QVector3D>& line_strip_points) {
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
std::vector<QVector3D> vertex_data;
|
||||
m_offsets.push_back(0);
|
||||
for (const auto& p : line_strip_points)
|
||||
vertex_data.push_back(p);
|
||||
|
||||
const auto end_of_current_arc_points = static_cast<GLuint>(vertex_data.size());
|
||||
m_offsets.push_back(end_of_current_arc_points);
|
||||
|
||||
// DEFINE OPENGL BUFFERS
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
// Vertex Buffer
|
||||
glGenBuffers(1, &m_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size();
|
||||
auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data());
|
||||
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
// Position Vertex-Attribute
|
||||
GLint position_attrib_index = 0;
|
||||
const void* position_offset = 0;
|
||||
GLsizei stride = 0;
|
||||
glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
|
||||
position_offset);
|
||||
glEnableVertexAttribArray(position_attrib_index);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
Line_strips::Line_strips(std::vector<std::vector<QVector3D>>& arcs) {
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
std::vector<QVector3D> vertex_data;
|
||||
m_offsets.push_back(0);
|
||||
for (const auto& arc : arcs) {
|
||||
for(const auto& p : arc) vertex_data.push_back(p);
|
||||
|
||||
const auto end_of_current_arc_points = static_cast<GLuint>(vertex_data.size());
|
||||
m_offsets.push_back(end_of_current_arc_points);
|
||||
}
|
||||
|
||||
// DEFINE OPENGL BUFFERS
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
// Vertex Buffer
|
||||
glGenBuffers(1, &m_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size();
|
||||
auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data());
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
vertex_buffer_size,
|
||||
vertex_buffer_data,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
// Position Vertex-Attribute
|
||||
GLint position_attrib_index = 0;
|
||||
const void* position_offset = 0;
|
||||
GLsizei stride = 0;
|
||||
glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
|
||||
position_offset);
|
||||
glEnableVertexAttribArray(position_attrib_index);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
std::size_t Line_strips::get_num_line_strips() const
|
||||
{ return m_offsets.size() - 1; }
|
||||
|
||||
//! \brief
|
||||
void Line_strips::draw(int line_strip_index) {
|
||||
glBindVertexArray(m_vao);
|
||||
const auto first = m_offsets[line_strip_index];
|
||||
const auto count = m_offsets[line_strip_index + 1] - first;
|
||||
glDrawArrays(GL_LINE_STRIP, first, count);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
||||
//! \brief
|
||||
void Line_strips::draw() {
|
||||
glBindVertexArray(m_vao);
|
||||
for (std::size_t i = 1; i < m_offsets.size(); i++) {
|
||||
const auto first = m_offsets[i - 1];
|
||||
const auto count = m_offsets[i] - first;
|
||||
glDrawArrays(GL_LINE_STRIP, first, count);
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// 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 LINE_STRIPS_H
|
||||
#define LINE_STRIPS_H
|
||||
|
||||
#include <vector>
|
||||
#include <qvector3d.h>
|
||||
|
||||
#include "Common_defs.h"
|
||||
|
||||
class Line_strips : protected OpenGLFunctionsBase {
|
||||
public:
|
||||
Line_strips(std::vector<QVector3D>& line_strip_points);
|
||||
Line_strips(std::vector<std::vector<QVector3D>>& arcs);
|
||||
|
||||
std::size_t get_num_line_strips() const;
|
||||
void draw(int line_strip_index);
|
||||
|
||||
void draw();
|
||||
|
||||
private:
|
||||
GLuint m_vao;
|
||||
GLuint m_vbo;
|
||||
std::vector<GLuint> m_offsets;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,394 @@
|
|||
// 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>
|
||||
|
||||
#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 "GUI_country_pick_handler.h"
|
||||
#include "Kml_reader.h"
|
||||
#include "Message_manager.h"
|
||||
#include "Timer.h"
|
||||
#include "Tools.h"
|
||||
#include "Verification.h"
|
||||
|
||||
//! \brief
|
||||
Main_widget::Main_widget(const QString& file_name) : m_file_name(file_name) {}
|
||||
|
||||
//! \brief
|
||||
Main_widget::~Main_widget() {
|
||||
// Make sure the context is current when deleting the texture and the buffers.
|
||||
makeCurrent();
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Main_widget::set_mouse_pos(const QVector3D mouse_pos)
|
||||
{ m_gr_mouse_vertex->set_pos(mouse_pos); }
|
||||
|
||||
//! \brief
|
||||
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_gr_country_triangles[prev_picked_country];
|
||||
auto color = prev_country->get_color();
|
||||
color *= m_dimming_factor;
|
||||
color.setW(1);
|
||||
prev_country->set_color(color);
|
||||
}
|
||||
|
||||
if (! country_name.empty()) {
|
||||
// highlight the current country color
|
||||
auto& curr_country = m_gr_country_triangles[country_name];
|
||||
auto color = curr_country->get_color();
|
||||
color /= m_dimming_factor;
|
||||
color.setW(1);
|
||||
curr_country->set_color(color);
|
||||
qDebug() << "SELECTED COUNTRY: " << country_name.c_str();
|
||||
}
|
||||
|
||||
prev_picked_country = country_name;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
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);
|
||||
update();
|
||||
}
|
||||
|
||||
//! \brief
|
||||
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);
|
||||
update();
|
||||
}
|
||||
|
||||
//! \brief
|
||||
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);
|
||||
update();
|
||||
}
|
||||
|
||||
//! \brief
|
||||
// void Main_widget::timerEvent(QTimerEvent* event) { update(); }
|
||||
|
||||
//! \brief
|
||||
void Main_widget::keyPressEvent(QKeyEvent* /* event */) {}
|
||||
|
||||
//! \brief
|
||||
void Main_widget::initializeGL() {
|
||||
m_pick_handler = std::make_unique<GUI_country_pick_handler>(*this);
|
||||
|
||||
QVector3D initial_mouse_pos(0, -1, 0);
|
||||
m_gr_mouse_vertex = std::make_unique<Single_vertex>(initial_mouse_pos);
|
||||
|
||||
initializeOpenGLFunctions();
|
||||
init_camera();
|
||||
init_geometry();
|
||||
init_shader_programs();
|
||||
|
||||
m_current_approx_error = 0.001f;
|
||||
m_num_uniform_points = 4096;
|
||||
|
||||
qDebug() << "loading arrangement..";
|
||||
m_arrh = Aos::load_arr(m_file_name.toStdString());
|
||||
if (m_arrh == nullptr) {
|
||||
std::string msg("Error: failed to load file ");
|
||||
msg += m_file_name.toStdString();
|
||||
throw std::runtime_error(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
init_country_borders(m_current_approx_error);
|
||||
|
||||
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, m_current_approx_error,
|
||||
m_num_uniform_points);
|
||||
//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); };
|
||||
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 *= m_dimming_factor;
|
||||
color.setW(1);
|
||||
country_triangles->set_color(color);
|
||||
//country_triangles->set_color(colors[color_map[country_name]]);
|
||||
m_gr_country_triangles.emplace(country_name, std::move(country_triangles));
|
||||
}
|
||||
country_triangles_map.clear();
|
||||
|
||||
//qDebug() << "num triangles = " << triangle_points.size() / 3;
|
||||
//m_gr_all_triangles = std::make_unique<Triangles>(triangle_points);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Main_widget::init_geometry() {
|
||||
// SPHERE
|
||||
std::size_t num_slices = 64;
|
||||
std::size_t num_stacks = 64;
|
||||
float r = 1.0f;
|
||||
m_gr_sphere = std::make_unique<Sphere>(num_slices, num_stacks, r);
|
||||
const float c = 0.8f;
|
||||
m_gr_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_gr_identification_curve = std::make_unique<Line_strips>(approx_ident_curve);
|
||||
|
||||
const float axes_length = 2;
|
||||
m_gr_world_coord_axes = std::make_unique<World_coord_axes>(axes_length);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
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");
|
||||
}
|
||||
|
||||
//! \brief
|
||||
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_gr_all_country_borders.reset(nullptr);
|
||||
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_country_borders = std::make_unique<Line_strips>(all_approx_arcs);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
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;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
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;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
template<typename T>
|
||||
void draw_safe(T& ptr) { if (ptr) ptr->draw(); }
|
||||
|
||||
//! \brief
|
||||
void Main_widget::paintGL() {
|
||||
if (m_update_approx_error) {
|
||||
const auto error = compute_backprojected_error(0.5);
|
||||
qDebug() << "current error = " << m_current_approx_error;
|
||||
qDebug() << "new approx error = " << error;
|
||||
if (error < m_current_approx_error) {
|
||||
init_country_borders(error);
|
||||
m_current_approx_error = error;
|
||||
auto ratio = static_cast<double>(m_current_approx_error) / error;
|
||||
m_num_uniform_points *= ratio*ratio;
|
||||
std::cout << "num uniform points = " << m_num_uniform_points
|
||||
<< std::endl;
|
||||
}
|
||||
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().map(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);
|
||||
// SMOTH RENDERING
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
auto& sp = m_sp_smooth;
|
||||
sp.use();
|
||||
|
||||
// SPHERE
|
||||
{
|
||||
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_gr_sphere->draw();
|
||||
}
|
||||
|
||||
// DRAW SOLID FACES
|
||||
{
|
||||
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_gr_all_triangles->draw();
|
||||
for (auto& [country_name, country] : m_gr_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_gr_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_gr_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_gr_identification_curve->draw();
|
||||
|
||||
// draw all countries' borders
|
||||
float a = 0.0;
|
||||
sp.set_uniform("u_color", QVector4D(a, a, a, 1));
|
||||
m_gr_all_country_borders->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_gr_mouse_vertex->set_pos(m_mouse_pos);
|
||||
draw_safe(m_gr_mouse_vertex);
|
||||
}
|
||||
|
||||
sp.unuse();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
// 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 MAIN_WIDGET_H
|
||||
#define MAIN_WIDGET_H
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <QOpenGLWidget>
|
||||
#include <QMatrix4x4>
|
||||
#include <QQuaternion>
|
||||
#include <QVector2D>
|
||||
#include <QBasicTimer>
|
||||
|
||||
#include <qopenglwidget.h>
|
||||
|
||||
#include "Aos.h"
|
||||
#include "Camera.h"
|
||||
#include "Camera_manip.h"
|
||||
#include "Common_defs.h"
|
||||
#include "GUI_event_handler.h"
|
||||
#include "Kml_reader.h"
|
||||
#include "Line_strips.h"
|
||||
#include "Shader_program.h"
|
||||
#include "Single_vertex.h"
|
||||
#include "Sphere.h"
|
||||
#include "Triangles.h"
|
||||
#include "Vertices.h"
|
||||
#include "World_coordinate_axes.h"
|
||||
|
||||
class Main_widget : public QOpenGLWidget, protected OpenGLFunctionsBase {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using QOpenGLWidget::QOpenGLWidget;
|
||||
|
||||
Main_widget(const QString& file_name);
|
||||
~Main_widget();
|
||||
|
||||
auto& get_camera() { return m_camera; }
|
||||
auto& get_model_matrix() { return m_model; }
|
||||
auto& get_arr_handle() { return m_arrh; }
|
||||
|
||||
void set_mouse_pos(const QVector3D mouse_pos);
|
||||
|
||||
void hightlight_country(const std::string& country_name);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent* e) override;
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
// void timerEvent(QTimerEvent* e) override;
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
|
||||
void initializeGL() override;
|
||||
void resizeGL(int w, int h) override;
|
||||
void paintGL() override;
|
||||
|
||||
|
||||
void init_camera();
|
||||
void init_geometry();
|
||||
void init_shader_programs();
|
||||
|
||||
void init_country_borders(float error);
|
||||
|
||||
// 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
|
||||
// zoom-in or increase the window-size this can be called. But once a minimum
|
||||
// approximation error is needed, it will stay there until futher change.
|
||||
// SEE the definition of "m_current_approx_error" member variable below!
|
||||
float compute_backprojected_error(float pixel_error);
|
||||
|
||||
private:
|
||||
// COUNTRY ARRANGEMENT SPECIFIC DATA
|
||||
QString m_file_name;
|
||||
Aos::Arr_handle m_arrh;
|
||||
std::unique_ptr<Line_strips> m_gr_all_country_borders;
|
||||
|
||||
// used when dimming / highlighting selected countries
|
||||
const float m_dimming_factor = 0.4f;
|
||||
|
||||
// GUI: event handler for picking with right mouse button
|
||||
std::unique_ptr<GUI_event_handler> m_pick_handler;
|
||||
|
||||
// These are used to highlight the picked position by right-mouse click
|
||||
std::unique_ptr<Single_vertex> m_gr_mouse_vertex;
|
||||
|
||||
|
||||
// TRIANGLES for rendering the countries in solid
|
||||
std::unique_ptr<Triangles> m_gr_all_triangles;
|
||||
std::map<std::string, std::unique_ptr<Triangles>> m_gr_country_triangles;
|
||||
|
||||
|
||||
// -------------------------------
|
||||
// --> COMMON SETUP FOR ALL SCENES
|
||||
|
||||
// Basic objects in the scene
|
||||
std::unique_ptr<Sphere> m_gr_sphere;
|
||||
std::unique_ptr<World_coord_axes> m_gr_world_coord_axes;
|
||||
std::unique_ptr<Line_strips> m_gr_identification_curve;
|
||||
|
||||
// Shaders
|
||||
Shader_program m_sp_smooth;
|
||||
Shader_program m_sp_per_vertex_color;
|
||||
Shader_program m_sp_arc;
|
||||
|
||||
// Camera & controls
|
||||
Camera m_camera;
|
||||
std::unique_ptr<GUI_event_handler> m_camera_manip_rot;
|
||||
std::unique_ptr<GUI_event_handler> m_camera_manip_zoom;
|
||||
QMatrix4x4 m_model;
|
||||
|
||||
// view-port
|
||||
int m_vp_width = 0;
|
||||
int m_vp_height = 0;
|
||||
|
||||
// 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-
|
||||
// mation error is needed the necessary graphics-side updates need to be made
|
||||
// INSIDE the paintGL (or whereever the OpenGL context is active)!
|
||||
bool m_update_approx_error = false;
|
||||
float m_current_approx_error;
|
||||
std::size_t m_num_uniform_points;
|
||||
|
||||
// Timer for continuous screen-updates
|
||||
// QBasicTimer m_timer;
|
||||
|
||||
// <-- COMMON SETUP FOR ALL SCENES
|
||||
// -------------------------------
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
// 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 MAIN_WIDGET_H
|
||||
#define MAIN_WIDGET_H
|
||||
|
||||
#include <QOpenGLWidget>
|
||||
#include <QMatrix4x4>
|
||||
#include <QQuaternion>
|
||||
#include <QVector2D>
|
||||
#include <QBasicTimer>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <qopenglwidget.h>
|
||||
|
||||
#include "Aos.h"
|
||||
#include "Camera.h"
|
||||
#include "Camera_manip.h"
|
||||
#include "Common_defs.h"
|
||||
#include "GUI_event_handler.h"
|
||||
#include "Kml_reader.h"
|
||||
#include "Line_strips.h"
|
||||
#include "Shader_program.h"
|
||||
#include "SingleVertex.h"
|
||||
#include "Sphere.h"
|
||||
#include "Triangles.h"
|
||||
#include "Vertices.h"
|
||||
#include "World_coordinate_axes.h"
|
||||
|
||||
class Main_widget : public QOpenGLWidget, protected OpenGLFunctionsBase {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using QOpenGLWidget::QOpenGLWidget;
|
||||
~Main_widget();
|
||||
|
||||
auto& get_camera() { return m_camera; }
|
||||
auto& get_model_matrix() { return m_model; }
|
||||
auto& get_arr_handle() { return m_arrh; }
|
||||
|
||||
void set_mouse_pos(const QVector3D mouse_pos) { m_mouse_pos = mouse_pos; }
|
||||
|
||||
void hightlight_country(const std::string& country_name);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent* e) override;
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
void timerEvent(QTimerEvent* e) override;
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
|
||||
void initializeGL() override;
|
||||
void resizeGL(int w, int h) override;
|
||||
void paintGL() override;
|
||||
|
||||
|
||||
void init_camera();
|
||||
void init_geometry();
|
||||
void init_shader_programs();
|
||||
|
||||
void init_country_borders(float error);
|
||||
void init_country_selection();
|
||||
|
||||
void handle_country_picking(QMouseEvent* e);
|
||||
|
||||
// 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
|
||||
// zoom-in or increase the window-size this can be called. But once a minimum
|
||||
// approximation error is needed, it will stay there until futher change.
|
||||
// SEE the definition of "m_current_approx_error" member variable below!
|
||||
float compute_backprojected_error(float pixel_error);
|
||||
|
||||
|
||||
// init problematic vertices: these are the vertices incident to deg-4 vertex
|
||||
void init_problematic_nodes();
|
||||
|
||||
private:
|
||||
// ARRANGEMENT
|
||||
Aos::Arr_handle m_arrh;
|
||||
std::unique_ptr<Line_strips> m_gr_all_approx_arcs;
|
||||
|
||||
// GUI: event handler for picking with right mouse button
|
||||
std::unique_ptr<GUI_event_handler> m_pick_handler;
|
||||
|
||||
// Objects in the scene
|
||||
std::unique_ptr<Sphere> m_sphere;
|
||||
std::unique_ptr<World_coord_axes> m_world_coord_axes;
|
||||
std::unique_ptr<Line_strips> m_geodesic_arcs;
|
||||
std::unique_ptr<Vertices> m_vertices, m_problematic_vertices;
|
||||
std::unique_ptr<Line_strips> m_identification_curve;
|
||||
|
||||
// New faces not in the KML-file but created during arr-construction.
|
||||
// This is used to identify the Caspian Sea!
|
||||
std::unique_ptr<Line_strips> m_new_faces;
|
||||
|
||||
// These are used to highlight the picked position by right-mouse click
|
||||
QVector3D m_mouse_pos;
|
||||
std::unique_ptr<SingleVertex> m_mouse_vertex;
|
||||
|
||||
// COUNTRY DATA
|
||||
Kml::Placemarks m_countries;
|
||||
std::vector<std::string> m_country_names;
|
||||
std::vector<std::unique_ptr<Line_strips>> m_country_borders;
|
||||
|
||||
// boundary-arcs by country
|
||||
int m_selected_country_index;
|
||||
int m_selected_arc_index;
|
||||
Kml::Nodes m_selected_country_nodes;
|
||||
Kml::Arcs m_selected_country_arcs;
|
||||
Kml::Placemark* m_selected_country;
|
||||
|
||||
// TRIANGLES for rendering the countries in solid
|
||||
std::unique_ptr<Triangles> m_all_triangles;
|
||||
std::map<std::string, std::unique_ptr<Triangles>> m_country_triangles;
|
||||
|
||||
// Shaders
|
||||
Shader_program m_sp_smooth;
|
||||
Shader_program m_sp_per_vertex_color;
|
||||
Shader_program m_sp_arc;
|
||||
|
||||
// Camera & controls
|
||||
Camera m_camera;
|
||||
std::unique_ptr<GUI_event_handler> m_camera_manip_rot;
|
||||
std::unique_ptr<Camera_manip> m_camera_manip_zoom;
|
||||
QMatrix4x4 m_model;
|
||||
|
||||
// view-port
|
||||
int m_vp_width = 0;
|
||||
int m_vp_height = 0;
|
||||
|
||||
// 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-
|
||||
// mation error is needed the necessary graphics-side updates need to be made
|
||||
// INSIDE the paintGL (or whereever the OpenGL context is active)!
|
||||
bool m_update_approx_error = false;
|
||||
float m_current_approx_error;
|
||||
|
||||
// Timer for continuous screen-updates
|
||||
QBasicTimer m_timer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// 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>
|
||||
|
||||
#include "Message_manager.h"
|
||||
|
||||
std::map<std::string, Message_manager::Callbacks>
|
||||
Message_manager::s_message_map;
|
||||
|
||||
void Message_manager::add(const std::string& msg_name,
|
||||
std::function<void()> callback)
|
||||
{ s_message_map[msg_name].push_back(callback); }
|
||||
|
||||
void Message_manager::notify_all(const std::string& msg_name) {
|
||||
auto it = s_message_map.find(msg_name);
|
||||
if (s_message_map.cend() != it) {
|
||||
auto& callbacks = it->second;
|
||||
for (auto& cb : callbacks) cb();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// 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
|
||||
#define MESSAGE_MANAGER_H
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Message_manager {
|
||||
public:
|
||||
static void add(const std::string& msg_name, std::function<void()> callback);
|
||||
static void notify_all(const std::string& msg_name);
|
||||
|
||||
protected:
|
||||
using Callbacks = std::vector<std::function<void()>>;
|
||||
static std::map<std::string, Callbacks> s_message_map;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
// 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>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Tools.h"
|
||||
#include "Shader_program.h"
|
||||
|
||||
std::string Shader_program::s_shader_path;
|
||||
|
||||
//! \brief
|
||||
void Shader_program::set_shader_path(const char* path)
|
||||
{ s_shader_path = std::string(path); }
|
||||
|
||||
//! \brief
|
||||
bool Shader_program::init() {
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
m_program = glCreateProgram();
|
||||
if (! m_program) {
|
||||
std::cout << "error creating shader program!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
bool Shader_program::init(const char* vs, const char* gs, const char* fs) {
|
||||
if (! init()) return false;
|
||||
|
||||
add_shader_from_file(vs, GL_VERTEX_SHADER);
|
||||
add_shader_from_file(gs, GL_GEOMETRY_SHADER);
|
||||
add_shader_from_file(fs, GL_FRAGMENT_SHADER);
|
||||
|
||||
link();
|
||||
validate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
bool Shader_program::init(const std::string& vs,
|
||||
const std::string& gs,
|
||||
const std::string& fs)
|
||||
{ return init(vs.c_str(), gs.c_str(), fs.c_str()); }
|
||||
|
||||
//! \brief
|
||||
bool Shader_program::init_with_vs_fs(const char* shader_file_prefix) {
|
||||
std::string prefix(shader_file_prefix);
|
||||
std::string vs = s_shader_path + prefix + "_vs.glsl";
|
||||
std::string fs = s_shader_path + prefix + "_fs.glsl";
|
||||
return init(vs, "", fs);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Shader_program::add_shader(const char* shader_code, GLenum shader_type) {
|
||||
GLuint the_shader = glCreateShader(shader_type);
|
||||
|
||||
const GLchar* the_code[] = { shader_code };
|
||||
GLint code_length[] = { static_cast<GLint>(strlen(shader_code)) };
|
||||
|
||||
glShaderSource(the_shader, 1, the_code, code_length);
|
||||
glCompileShader(the_shader);
|
||||
|
||||
|
||||
GLint result = 0;
|
||||
GLchar elog[1024] = { 0 };
|
||||
glGetShaderiv(the_shader, GL_COMPILE_STATUS, &result);
|
||||
if (! result) {
|
||||
std::string shader_type_name;
|
||||
switch (shader_type) {
|
||||
case GL_VERTEX_SHADER: shader_type_name = "VERTEX"; break;
|
||||
case GL_GEOMETRY_SHADER: shader_type_name = "GEOMETRY"; break;
|
||||
case GL_FRAGMENT_SHADER: shader_type_name = "FRAGMENT"; break;
|
||||
}
|
||||
glGetShaderInfoLog(the_shader, sizeof(elog), NULL, elog);
|
||||
std::cout << "! error compiling the " << shader_type_name <<
|
||||
" shader:\n" << elog << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
glAttachShader(m_program, the_shader);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Shader_program::add_shader_from_file(const char* shader_file,
|
||||
GLenum shader_type) {
|
||||
if (strlen(shader_file) == 0) return;
|
||||
|
||||
auto src = read_file(shader_file);
|
||||
add_shader(src.c_str(), shader_type);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
bool Shader_program::link() {
|
||||
GLint result = 0;
|
||||
GLchar elog[1024] = { 0 };
|
||||
|
||||
glLinkProgram(m_program);
|
||||
glGetProgramiv(m_program, GL_LINK_STATUS, &result);
|
||||
if (! result) {
|
||||
glGetProgramInfoLog(m_program, sizeof(elog), NULL, elog);
|
||||
std::cout << "! error linking program:\n" << elog << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
bool Shader_program::validate() {
|
||||
GLint result = 0;
|
||||
GLchar elog[1024] = { 0 };
|
||||
|
||||
glValidateProgram(m_program);
|
||||
glGetProgramiv(m_program, GL_VALIDATE_STATUS, &result);
|
||||
if (!result)
|
||||
{
|
||||
glGetProgramInfoLog(m_program, sizeof(elog), NULL, elog);
|
||||
std::cout << "! error validating program:\n" << elog << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
GLint Shader_program::get_uniform_location(const GLchar* name) {
|
||||
const auto uniform_loc = glGetUniformLocation(m_program, name);
|
||||
return uniform_loc;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Shader_program::use() { glUseProgram(m_program); }
|
||||
|
||||
//! \brief
|
||||
void Shader_program::unuse() { glUseProgram(0); }
|
||||
|
||||
//! \brief
|
||||
void Shader_program::set_uniform(GLint uniform_loc, const QMatrix4x4& m)
|
||||
{ glUniformMatrix4fv(uniform_loc, 1, GL_FALSE, m.data()); }
|
||||
|
||||
//! \brief
|
||||
void Shader_program::set_uniform(const GLchar* name, const QMatrix4x4& m) {
|
||||
const auto uniform_loc = get_uniform_location(name);
|
||||
set_uniform(uniform_loc, m);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Shader_program::set_uniform(GLint uniform_loc, const QMatrix3x3& m)
|
||||
{ glUniformMatrix3fv(uniform_loc, 1, GL_FALSE, m.data()); }
|
||||
|
||||
//! \brief
|
||||
void Shader_program::set_uniform(const GLchar* name, const QMatrix3x3& m) {
|
||||
const auto uniform_loc = get_uniform_location(name);
|
||||
set_uniform(uniform_loc, m);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Shader_program::set_uniform(GLint uniform_loc, const QVector4D& v)
|
||||
{ glUniform4f(uniform_loc, v.x(), v.y(), v.z(), v.w()); }
|
||||
|
||||
//! \brief
|
||||
void Shader_program::set_uniform(const GLchar* name, const QVector4D& v) {
|
||||
const auto uniform_loc = get_uniform_location(name);
|
||||
set_uniform(uniform_loc, v);
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
// 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 SHADER_PROGRAM_H
|
||||
#define SHADER_PROGRAM_H
|
||||
|
||||
#include <string>
|
||||
#include <qmatrix4x4.h>
|
||||
|
||||
#include "Common_defs.h"
|
||||
|
||||
class Shader_program : protected OpenGLFunctionsBase {
|
||||
public:
|
||||
static void set_shader_path(const char* path);
|
||||
|
||||
bool init();
|
||||
bool init(const char* vs, const char* gs, const char* fs);
|
||||
bool init(const std::string& vs, const std::string& gs,
|
||||
const std::string& fs);
|
||||
|
||||
/*! Initialize with just the vertex and fragment shaders
|
||||
*/
|
||||
bool init_with_vs_fs(const char* shader_file_prefix);
|
||||
|
||||
void add_shader(const char* shader_code, GLenum shader_type);
|
||||
void add_shader_from_file(const char* shader_file, GLenum shader_type);
|
||||
|
||||
bool link();
|
||||
bool validate();
|
||||
|
||||
GLint get_uniform_location(const GLchar* name);
|
||||
|
||||
void use();
|
||||
void unuse();
|
||||
|
||||
void set_uniform(GLint uniform_loc, const QMatrix4x4& m);
|
||||
void set_uniform(const GLchar* name, const QMatrix4x4& m);
|
||||
|
||||
void set_uniform(GLint uniform_loc, const QMatrix3x3& m);
|
||||
void set_uniform(const GLchar* name, const QMatrix3x3& m);
|
||||
|
||||
void set_uniform(GLint uniform_loc, const QVector4D& v);
|
||||
void set_uniform(const GLchar* name, const QVector4D& v);
|
||||
|
||||
private:
|
||||
GLuint m_program;
|
||||
static std::string s_shader_path;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
// 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>
|
||||
|
||||
#include "Single_vertex.h"
|
||||
|
||||
//!\brief
|
||||
Single_vertex::Single_vertex(const QVector3D& pos) {
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
m_pos = pos;
|
||||
m_visible = true;
|
||||
|
||||
// DEFINE OPENGL BUFFERS
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
// Vertex Buffer
|
||||
glGenBuffers(1, &m_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
auto vertex_buffer_size = sizeof(m_pos);
|
||||
auto vertex_buffer_data = reinterpret_cast<const void*>(&m_pos);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
// Position Vertex-Attribute
|
||||
GLint position_attrib_index = 0;
|
||||
const void* position_offset = 0;
|
||||
GLsizei stride = 0;
|
||||
glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
|
||||
position_offset);
|
||||
glEnableVertexAttribArray(position_attrib_index);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
//!\brief
|
||||
void Single_vertex::set_visible(bool flag) { m_visible = flag; }
|
||||
|
||||
//!\brief
|
||||
void Single_vertex::set_pos(const QVector3D& pos) {
|
||||
m_pos = pos;
|
||||
m_update = true;
|
||||
}
|
||||
|
||||
//!\brief
|
||||
const QVector3D& Single_vertex::get_pos() const { return m_pos; }
|
||||
|
||||
//!\brief
|
||||
void Single_vertex::draw() {
|
||||
if (m_visible) {
|
||||
if (m_update) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
auto vertex_buffer_size = sizeof(m_pos);
|
||||
auto vertex_buffer_data = reinterpret_cast<const void*>(&m_pos);
|
||||
auto offset = 0;
|
||||
glBufferSubData(GL_ARRAY_BUFFER, offset, vertex_buffer_size,
|
||||
vertex_buffer_data);
|
||||
m_update = false;
|
||||
}
|
||||
|
||||
glBindVertexArray(m_vao);
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// 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 SINGLE_VERTEX_H
|
||||
#define SINGLE_VERTEX_H
|
||||
|
||||
#include <vector>
|
||||
#include <qvector3d.h>
|
||||
#include "Common_defs.h"
|
||||
|
||||
class Single_vertex : protected OpenGLFunctionsBase {
|
||||
public:
|
||||
Single_vertex(const QVector3D& pos);
|
||||
|
||||
void set_visible(bool flag);
|
||||
void set_pos(const QVector3D& pos);
|
||||
const QVector3D& get_pos() const;
|
||||
|
||||
void draw();
|
||||
|
||||
private:
|
||||
bool m_visible;
|
||||
bool m_update = true; // flag to update the VBO (set_pos sets this)
|
||||
GLuint m_vao;
|
||||
GLuint m_vbo;
|
||||
QVector3D m_pos;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
// 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>
|
||||
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
#include <qvector3d.h>
|
||||
|
||||
#include "Sphere.h"
|
||||
|
||||
//! \brief
|
||||
Sphere::Sphere(std::size_t num_slices, std::size_t num_stacks, float r) {
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
num_stacks = std::max<std::size_t>(2, num_stacks);
|
||||
std::vector<QVector3D> vertices, normals;
|
||||
|
||||
// NORTH POLE
|
||||
vertices.push_back(QVector3D(0, 0, r));
|
||||
normals.push_back(QVector3D(0, 0, 1));
|
||||
|
||||
// SOUTH POLE
|
||||
vertices.push_back(QVector3D(0, 0, -r));
|
||||
normals.push_back(QVector3D(0, 0, -1));
|
||||
auto starting_index_of_middle_vertices = vertices.size();
|
||||
|
||||
for (std::size_t j = 1; j < num_stacks; ++j) {
|
||||
// Calculate the latitude (vertical angle) for the current stack
|
||||
float lat = M_PI * j / num_stacks;
|
||||
float rxy = r * std::sin(lat);
|
||||
float z = r * std::cos(lat);
|
||||
|
||||
for (std::size_t i = 0; i < num_slices; ++i) {
|
||||
// Calculate the longitude (horizontal angle) for the current slice
|
||||
float lon = 2 * M_PI * i / num_slices;
|
||||
|
||||
// Convert spherical coordinates to Cartesian coordinates
|
||||
float x = rxy * std::cos(lon);
|
||||
float y = rxy * std::sin(lon);
|
||||
|
||||
auto p = QVector3D(x, y, z);
|
||||
auto n = p / p.length();
|
||||
vertices.push_back(p);
|
||||
normals.push_back(n);
|
||||
}
|
||||
}
|
||||
|
||||
// strided vertex-data
|
||||
std::vector<QVector3D> vertex_data;
|
||||
for (std::size_t i = 0; i < vertices.size(); ++i) {
|
||||
vertex_data.push_back(vertices[i]);
|
||||
vertex_data.push_back(normals[i]);
|
||||
}
|
||||
|
||||
// add the indices for all triangles
|
||||
std::vector<GLuint> indices;
|
||||
|
||||
// NORTH CAP
|
||||
const GLuint north_vertex_index = 0;
|
||||
const auto north_cap_vertex_index_start = starting_index_of_middle_vertices;
|
||||
for (std::size_t i = 0; i < num_slices; ++i) {
|
||||
indices.push_back(north_vertex_index);
|
||||
indices.push_back(static_cast<GLuint>(north_cap_vertex_index_start + i));
|
||||
indices.push_back(static_cast<GLuint>(north_cap_vertex_index_start + (i + 1) % num_slices));
|
||||
}
|
||||
|
||||
// 0 = NORTH VERTEX
|
||||
// 1 = SOUTH VERTEX
|
||||
// [2, 2 + (numSlices-1)] = bottom vertices of the stack #1
|
||||
// [2+numSlices, 2 + (2*numSlices - 1)] = bottom vertices of the stack #2
|
||||
// ...
|
||||
// [2+(k-1)*numSlices, 2 + (k*numSlices -1)] = bottom vertices of the stack #k
|
||||
// ..
|
||||
// [2+(numStacks-1)*numSlices, 2+(numStacks*numSlices-1)] = bottom vertices of
|
||||
// the last stack (# numStacks)
|
||||
|
||||
// SOUTH CAP
|
||||
const GLuint south_vertex_index = 1;
|
||||
const std::size_t south_cap_index_start = starting_index_of_middle_vertices +
|
||||
(num_stacks - 2) * num_slices;
|
||||
for (std::size_t i = 0; i < num_slices; ++i) {
|
||||
const auto vi0 = south_vertex_index;
|
||||
const auto vi1 = static_cast<GLuint>(south_cap_index_start + i);
|
||||
const auto vi2 = static_cast<GLuint>(south_cap_index_start + (i + 1) % num_slices);
|
||||
indices.push_back(vi2);
|
||||
indices.push_back(vi1);
|
||||
indices.push_back(vi0);
|
||||
}
|
||||
|
||||
// MIDDLE TRIANGLES
|
||||
for (std::size_t k = 0; k < num_stacks - 2; ++k) {
|
||||
const std::size_t stack_start_index =
|
||||
starting_index_of_middle_vertices + k * num_slices;
|
||||
const std::size_t next_stack_start_index = stack_start_index + num_slices;
|
||||
for (std::size_t i = 0; i < num_slices; ++i) {
|
||||
// check why the following code snippet does not work (winding order?)
|
||||
//std::size_t vi0 = stackStartIndex + i;
|
||||
//std::size_t vi1 = nextStackStartIndex + i;
|
||||
//std::size_t vi2 = nextStackStartIndex + (i + 1) % numSlices;
|
||||
//std::size_t vi3 = stackStartIndex + (i + 1) % numSlices;
|
||||
auto vi0 = static_cast<GLuint>(stack_start_index + i);
|
||||
auto vi1 = static_cast<GLuint>(stack_start_index + (i + 1) % num_slices);
|
||||
auto vi2 = static_cast<GLuint>(next_stack_start_index + i);
|
||||
auto vi3 = static_cast<GLuint>(next_stack_start_index + (i + 1) % num_slices);
|
||||
|
||||
indices.push_back(vi0);
|
||||
indices.push_back(vi2);
|
||||
indices.push_back(vi1);
|
||||
//
|
||||
indices.push_back(vi2);
|
||||
indices.push_back(vi3);
|
||||
indices.push_back(vi1);
|
||||
}
|
||||
}
|
||||
m_num_indices = static_cast<GLuint>(indices.size());
|
||||
|
||||
// DEFINE OPENGL BUFFERS
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
// Index buffer
|
||||
glGenBuffers(1, &m_ibo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
|
||||
auto indices_size = sizeof(GLuint) * indices.size();
|
||||
auto indices_data = reinterpret_cast<const void*>(indices.data());
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_size, indices_data,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
// Vertex Buffer
|
||||
glGenBuffers(1, &m_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size();
|
||||
auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data());
|
||||
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
// Position Vertex-Attribute
|
||||
GLint position_attrib_index = 0;
|
||||
const void* position_offset = 0;
|
||||
GLsizei stride = 6 * sizeof(float);
|
||||
glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
|
||||
position_offset);
|
||||
glEnableVertexAttribArray(position_attrib_index);
|
||||
|
||||
// Normal Vertex-Attribute
|
||||
GLint normal_attrib_index = 1;
|
||||
auto* normal_offset = reinterpret_cast<const void*>(3 * sizeof(float));
|
||||
glVertexAttribPointer(normal_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
|
||||
normal_offset);
|
||||
glEnableVertexAttribArray(normal_attrib_index);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
// Note: calling this before glBindVertexArray(0) results in no output!
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Sphere::set_color(float r, float g, float b, float a)
|
||||
{ m_color = QVector4D(r, g, b, a); }
|
||||
|
||||
//! \brief
|
||||
void Sphere::draw() {
|
||||
// DRAW TRIANGLES
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
//glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
|
||||
glDrawElements(GL_TRIANGLES, m_num_indices, GL_UNSIGNED_INT, 0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// 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 SPHERE_H
|
||||
#define SPHERE_H
|
||||
|
||||
#include "Common_defs.h"
|
||||
#include <qvector4d.h>
|
||||
|
||||
class Sphere : protected OpenGLFunctionsBase {
|
||||
public:
|
||||
Sphere(std::size_t num_slices, std::size_t num_stacks, float r);
|
||||
|
||||
void set_color(float r, float g, float b, float a);
|
||||
const QVector4D& get_color() { return m_color; }
|
||||
|
||||
void draw();
|
||||
|
||||
private:
|
||||
GLuint m_vao;
|
||||
GLuint m_vbo;
|
||||
GLuint m_ibo;
|
||||
GLuint m_num_indices;
|
||||
QVector4D m_color;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// 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 TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
class Timer {
|
||||
public:
|
||||
Timer() { reset(); }
|
||||
|
||||
void reset() { m_Start = std::chrono::high_resolution_clock::now(); }
|
||||
|
||||
double elapsed() {
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
std::chrono::high_resolution_clock::now() - m_Start).count() *
|
||||
0.001 * 0.001 * 0.001;
|
||||
}
|
||||
|
||||
double elapsed_millis() { return elapsed() * 1000.0f; }
|
||||
|
||||
private:
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> m_Start;
|
||||
};
|
||||
|
||||
class ScopedTimer {
|
||||
public:
|
||||
ScopedTimer(const std::string& name) : m_name(name) {}
|
||||
|
||||
~ScopedTimer() {
|
||||
double time = m_timer.elapsed_millis();
|
||||
std::cout << "[TIMER] " << m_name << " - " << time << "ms\n";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
Timer m_timer;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// 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>
|
||||
|
||||
#include "Tools.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
//! \brief
|
||||
std::string read_file(const std::string& file_name) {
|
||||
const auto flags = std::ios::in | std::ios::binary | std::ios::ate;
|
||||
std::ifstream ifs(file_name.c_str(), flags);
|
||||
|
||||
if (! ifs.is_open()) {
|
||||
std::cout << "could not open file: " << file_name << std::endl;
|
||||
return "";
|
||||
}
|
||||
|
||||
std::ifstream::pos_type file_size = ifs.tellg();
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
|
||||
std::vector<char> bytes(file_size);
|
||||
ifs.read(&bytes[0], file_size);
|
||||
|
||||
return std::string(&bytes[0], file_size);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
std::ostream& operator << (std::ostream& os, const QVector2D& v) {
|
||||
os << v.x() << ", " << v.y();
|
||||
return os;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
std::ostream& operator << (std::ostream& os, const QVector3D& v) {
|
||||
os << v.x() << ", " << v.y() << ", " << v.z();
|
||||
return os;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
std::ostream& operator << (std::ostream& os, const QVector4D& v) {
|
||||
os << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w();
|
||||
return os;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// 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 TOOLS_H
|
||||
#define TOOLS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
|
||||
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 QVector3D& v);
|
||||
std::ostream& operator << (std::ostream& os, const QVector4D& v);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
// 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>
|
||||
|
||||
#include "Triangles.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
//! \brief
|
||||
Triangles::Triangles(std::vector<QVector3D>& vertices) {
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
// computer the normals of each vertex
|
||||
std::vector<QVector3D> normals;
|
||||
for(const auto& p : vertices) {
|
||||
auto n = p;
|
||||
n.normalize();
|
||||
normals.push_back(n);
|
||||
}
|
||||
|
||||
// std::size_t num_triangles = vertices.size() / 3;
|
||||
|
||||
// strided vertex-data
|
||||
std::vector<QVector3D> vertex_data;
|
||||
for (std::size_t i = 0; i < vertices.size(); ++i) {
|
||||
vertex_data.push_back(vertices[i]);
|
||||
vertex_data.push_back(normals[i]);
|
||||
}
|
||||
|
||||
// DEFINE OPENGL BUFFERS
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
m_num_vertices = static_cast<GLsizei>(vertices.size());
|
||||
|
||||
// Vertex Buffer
|
||||
glGenBuffers(1, &m_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size();
|
||||
auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data());
|
||||
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
// Position Vertex-Attribute
|
||||
GLint position_attrib_index = 0;
|
||||
const void* position_offset = 0;
|
||||
GLsizei stride = 6 * sizeof(float);
|
||||
glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
|
||||
position_offset);
|
||||
glEnableVertexAttribArray(position_attrib_index);
|
||||
|
||||
// Normal Vertex-Attribute
|
||||
GLint normal_attrib_index = 1;
|
||||
auto* normal_offset = reinterpret_cast<const void*>(3 * sizeof(float));
|
||||
glVertexAttribPointer(normal_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
|
||||
normal_offset);
|
||||
glEnableVertexAttribArray(normal_attrib_index);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Triangles::set_color(const QVector4D& rgba)
|
||||
{ m_color = rgba; }
|
||||
|
||||
//! \brief
|
||||
const QVector4D& Triangles::get_color() const { return m_color; }
|
||||
|
||||
//! \brief
|
||||
void Triangles::draw() {
|
||||
// DRAW TRIANGLES
|
||||
glBindVertexArray(m_vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, m_num_vertices);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// 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 TRIANGLES_H
|
||||
#define TRIANGLES_H
|
||||
|
||||
#include <vector>
|
||||
#include <qvector3d.h>
|
||||
#include "Common_defs.h"
|
||||
|
||||
class Triangles : protected OpenGLFunctionsBase {
|
||||
public:
|
||||
// IMPORTANT: we assume that the triangles are on the sphere!
|
||||
// this means that all vertex-normals are actually the normal vector on the
|
||||
// sphere at the point of projection of the current vertex on the sphere.
|
||||
Triangles(std::vector<QVector3D>& vertices);
|
||||
|
||||
int get_num_triangles() const;
|
||||
void set_color(const QVector4D& rgba);
|
||||
const QVector4D& get_color() const;
|
||||
|
||||
void draw();
|
||||
|
||||
private:
|
||||
GLuint m_vao;
|
||||
GLuint m_vbo;
|
||||
GLsizei m_num_vertices;
|
||||
QVector4D m_color;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
// 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>
|
||||
|
||||
#include "Verification.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Kml_reader.h"
|
||||
|
||||
void Verification::find_minimum_projected_error_on_sphere(float we,
|
||||
Camera& cam,
|
||||
int vp_width,
|
||||
int vp_height) {
|
||||
QRect vp(0, 0, vp_width, vp_height);
|
||||
auto proj = cam.get_projection_matrix();
|
||||
auto view = cam.get_view_matrix();
|
||||
QMatrix4x4 model;
|
||||
auto model_view = view * model;
|
||||
|
||||
float max_err = 0;
|
||||
float max_theta = -1;
|
||||
float max_phi = -1;
|
||||
|
||||
int num_divs = 200;
|
||||
const float dtheta = M_PI_2 / num_divs;
|
||||
const float dphi = M_PI_2 / num_divs;
|
||||
|
||||
const float r1 = 1.f;
|
||||
const float r2 = r1 - we;
|
||||
for (int i = 0; i <= num_divs; ++i) {
|
||||
const float theta = dtheta * i;
|
||||
const float cos_theta = std::cos(theta);
|
||||
const float sin_theta = std::sin(theta);
|
||||
|
||||
for (int j = 0; j <= num_divs; ++j) {
|
||||
QVector3D p1, p2;
|
||||
const float phi = dphi * j;
|
||||
const float cos_phi = std::cos(phi);
|
||||
const float sin_phi = std::sin(phi);
|
||||
|
||||
// p1
|
||||
const float r1xz = r1 * sin_phi;
|
||||
p1.setY(r1 * cos_phi);
|
||||
p1.setX(r1xz * cos_theta);
|
||||
p1.setZ(r1xz * sin_theta);
|
||||
|
||||
// p2
|
||||
const float r2xz = r2 * sin_phi;
|
||||
p2.setY(r2 * cos_phi);
|
||||
p2.setX(r2xz * cos_theta);
|
||||
p2.setZ(r2xz * sin_theta);
|
||||
|
||||
auto wp1 = p1.project(model_view, proj, vp);
|
||||
auto wp2 = p2.project(model_view, proj, vp);
|
||||
|
||||
const auto pe = wp1.distanceToPoint(wp2);
|
||||
if (max_err < pe) {
|
||||
max_err = pe;
|
||||
max_theta = theta;
|
||||
max_phi = phi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "max err = " << max_err << std::endl;
|
||||
std::cout << "max phi = " << max_phi * 180 / M_PI << std::endl;
|
||||
std::cout << "max theta = " << max_theta * 180 / M_PI << std::endl;
|
||||
|
||||
auto wp1 = QVector3D(0, r1, 0).project(model_view, proj, vp);
|
||||
auto wp2 = QVector3D(0, r2, 0).project(model_view, proj, vp);
|
||||
auto pe = wp1.distanceToPoint(wp2);
|
||||
std::cout << "polar err = " << pe << std::endl;
|
||||
|
||||
wp1 = QVector3D(r1, 0, 0).project(model_view, proj, vp);
|
||||
wp2 = QVector3D(r2, 0, 0).project(model_view, proj, vp);
|
||||
pe = wp1.distanceToPoint(wp2);
|
||||
std::cout << "x-axis err = " << pe << std::endl;
|
||||
|
||||
wp1 = QVector3D(0, 0, 1).project(model_view, proj, vp);
|
||||
wp2 = QVector3D(we, 0, 1).project(model_view, proj, vp);
|
||||
pe = wp1.distanceToPoint(wp2);
|
||||
std::cout << "nearest proj err = " << pe << std::endl;
|
||||
|
||||
wp1 = QVector3D(0, 0, -1).project(model_view, proj, vp);
|
||||
wp2 = QVector3D(we, 0, -1).project(model_view, proj, vp);
|
||||
pe = wp1.distanceToPoint(wp2);
|
||||
std::cout << "farthest proj err = " << pe << std::endl;
|
||||
|
||||
// project the origin on the screen (to check if it projects to the mid-vp)
|
||||
//std::cout << QVector3D(0, 0, 0).project(model_view, proj, vp) << std::endl;
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void Verification::verify_antarctica_node_is_redundant() {
|
||||
Kml::Node n1(178.277211542064, -84.4725179992025),
|
||||
n2(180.0, -84.71338),
|
||||
n3(-179.942499356179, -84.7214433735525);
|
||||
|
||||
// 1) check if it is collinear with its neighboring nodes:
|
||||
// all of the vectors in 3D must lie in the same plane
|
||||
auto v1 = n1.get_coords_3f();
|
||||
auto v2 = n2.get_coords_3f();
|
||||
auto v3 = n3.get_coords_3f();
|
||||
auto n = QVector3D::crossProduct(v1, v3);
|
||||
n.normalize();
|
||||
std::cout << "** DOT PRODUCT = " << QVector3D::dotProduct(n, v2) << std::endl;
|
||||
|
||||
// 2) check if it is between its neighbors (check if r,s > 0)
|
||||
auto det = [](float ax, float ay, float bx, float by)
|
||||
{ return ax * by - ay * bx; };
|
||||
auto D = det(v1.x(), v1.y(), v3.x(), v3.y());
|
||||
auto Dr = det(v2.x(), v2.y(), v3.x(), v3.y());
|
||||
auto Ds = det(v1.x(), v1.y(), v2.x(), v2.y());
|
||||
auto r = Dr / D;
|
||||
auto s = Ds / D;
|
||||
std::cout << "r = " << r << "\ns=" << s << std::endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 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 VERIFICATION_H
|
||||
#define VERIFICATION_H
|
||||
|
||||
#include <qvector3d.h>
|
||||
#include <qmatrix4x4.h>
|
||||
|
||||
#include "Camera.h"
|
||||
|
||||
// This class contains code to verify or compute certain hypotheses
|
||||
//
|
||||
class Verification {
|
||||
public:
|
||||
// Use this to find the approximate of the true minimum projected error.
|
||||
// we are ot using this complicated method, but provide it for completeness.
|
||||
static void find_minimum_projected_error_on_sphere(float we, Camera& cam,
|
||||
int vp_width,
|
||||
int vp_height);
|
||||
|
||||
// verify that the node (180.0, -84.71338) in Antarctica is redundant
|
||||
static void verify_antarctica_node_is_redundant();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// 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>
|
||||
|
||||
#include "Vertices.h"
|
||||
|
||||
//! brief
|
||||
Vertices::Vertices(const std::vector<QVector3D>& vertices) {
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
auto& vertex_data = vertices;
|
||||
m_num_indices = static_cast<GLsizei>(vertices.size());
|
||||
|
||||
// DEFINE OPENGL BUFFERS
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
// Vertex Buffer
|
||||
glGenBuffers(1, &m_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size();
|
||||
auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data());
|
||||
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
// Position Vertex-Attribute
|
||||
GLint position_attrib_index = 0;
|
||||
const void* position_offset = 0;
|
||||
GLsizei stride = 0;
|
||||
glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
|
||||
position_offset);
|
||||
glEnableVertexAttribArray(position_attrib_index);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
//! brief
|
||||
void Vertices::draw() {
|
||||
glBindVertexArray(m_vao);
|
||||
glDrawArrays(GL_POINTS, 0, m_num_indices);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// 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 VERTICES_H
|
||||
#define VERTICES_H
|
||||
|
||||
#include <vector>
|
||||
#include <qvector3d.h>
|
||||
|
||||
#include "Common_defs.h"
|
||||
|
||||
class Vertices : protected OpenGLFunctionsBase {
|
||||
public:
|
||||
Vertices(const std::vector<QVector3D>& vertices);
|
||||
|
||||
void draw();
|
||||
|
||||
private:
|
||||
GLuint m_vao;
|
||||
GLuint m_vbo;
|
||||
GLsizei m_num_indices;
|
||||
std::vector<GLuint> m_offsets;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
// 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>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <qvector3d.h>
|
||||
|
||||
#include "World_coordinate_axes.h"
|
||||
|
||||
//! \brief
|
||||
World_coord_axes::World_coord_axes(float length) {
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
const auto a = length;
|
||||
const float c = 0.0f;
|
||||
std::vector<QVector3D> vertex_data {
|
||||
QVector3D(0, 0, 0), QVector3D(1, 0, 0),
|
||||
QVector3D(a, 0, 0), QVector3D(1, 0, 0),
|
||||
|
||||
QVector3D(0, 0, 0), QVector3D(0, 1, 0),
|
||||
QVector3D(0, a, 0), QVector3D(0, 1, 0),
|
||||
|
||||
QVector3D(0, 0, 0), QVector3D(c, c, 1),
|
||||
QVector3D(0, 0, a), QVector3D(c, c, 1)
|
||||
};
|
||||
|
||||
// DEFINE OPENGL BUFFERS
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
// Vertex Buffer
|
||||
glGenBuffers(1, &m_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
auto vertex_buffer_size = sizeof(QVector3D) * vertex_data.size();
|
||||
auto vertex_buffer_data = reinterpret_cast<const void*>(vertex_data.data());
|
||||
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, vertex_buffer_data,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
// Position Vertex-Attribute
|
||||
GLint position_attrib_index = 0;
|
||||
const void* position_offset = 0;
|
||||
GLsizei stride = 6 * sizeof(float);
|
||||
glVertexAttribPointer(position_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
|
||||
position_offset);
|
||||
glEnableVertexAttribArray(position_attrib_index);
|
||||
|
||||
// Color Vertex-Attribute
|
||||
GLint color_attrib_index = 1;
|
||||
auto* color_offset = reinterpret_cast<const void*>(3 * sizeof(float));
|
||||
glVertexAttribPointer(color_attrib_index, 3, GL_FLOAT, GL_FALSE, stride,
|
||||
color_offset);
|
||||
glEnableVertexAttribArray(color_attrib_index);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
//! \brief
|
||||
void World_coord_axes::draw() {
|
||||
glBindVertexArray(m_vao);
|
||||
const GLsizei count = 2 * 3; // = 2 * number of lines
|
||||
glDrawArrays(GL_LINES, 0, count);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// 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 WORLD_COORD_AXES_H
|
||||
#define WORLD_COORD_AXES_H
|
||||
|
||||
#include <qvector4d.h>
|
||||
|
||||
#include "Common_defs.h"
|
||||
|
||||
class World_coord_axes : protected OpenGLFunctionsBase {
|
||||
public:
|
||||
World_coord_axes(float length);
|
||||
|
||||
void draw();
|
||||
|
||||
private:
|
||||
GLuint m_vao;
|
||||
GLuint m_vbo;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
// 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>
|
||||
// : 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) {
|
||||
if (v->is_isolated()) {
|
||||
std::cout << "The vertex (" << v->point() << ") is isolated\n";
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "The neighbors of the vertex (" << v->point() << ") are:";
|
||||
typename Arrangement::Halfedge_around_vertex_const_circulator first, curr;
|
||||
first = curr = v->incident_halfedges();
|
||||
do std::cout << " (" << curr->source()->point() << ")";
|
||||
while (++curr != first);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
/*! Print all vertices (points) and edges (curves) along a connected component
|
||||
* boundary.
|
||||
*/
|
||||
template <typename Arrangement>
|
||||
void print_ccb(typename Arrangement::Ccb_halfedge_const_circulator circ) {
|
||||
std::cout << "(" << circ->source()->point() << ")";
|
||||
typename Arrangement::Ccb_halfedge_const_circulator curr = circ;
|
||||
do {
|
||||
typename Arrangement::Halfedge_const_handle e = curr;
|
||||
std::cout << " [" << e->curve() << "] "
|
||||
<< "(" << e->target()->point() << ")";
|
||||
} while (++curr != circ);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
/*! Print the boundary description of an arrangement face.
|
||||
*/
|
||||
template <typename Arrangement>
|
||||
void print_face(typename Arrangement::Face_const_handle f) {
|
||||
// Print the outer boundary.
|
||||
if (f->is_unbounded()) std::cout << "Unbounded face.\n";
|
||||
else {
|
||||
std::cout << "Outer boundary: ";
|
||||
print_ccb<Arrangement>(f->outer_ccb());
|
||||
}
|
||||
|
||||
// Print the boundary of each of the holes.
|
||||
size_t index = 1;
|
||||
for (auto hole = f->holes_begin(); hole != f->holes_end(); ++hole, ++index) {
|
||||
std::cout << " Hole #" << index << ": ";
|
||||
// The following statement pacifies msvc.
|
||||
typename Arrangement::Ccb_halfedge_const_circulator circ = *hole;
|
||||
print_ccb<Arrangement>(circ);
|
||||
}
|
||||
|
||||
// Print the isolated vertices.
|
||||
index = 1;
|
||||
for (auto iv = f->isolated_vertices_begin();
|
||||
iv != f->isolated_vertices_end(); ++iv, ++index)
|
||||
{
|
||||
std::cout << " Isolated vertex #" << index << ": "
|
||||
<< "(" << iv->point() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/*! Print the given arrangement.
|
||||
*/
|
||||
template <typename Arrangement>
|
||||
void print_arrangement(const Arrangement& arr) {
|
||||
CGAL_precondition(arr.is_valid());
|
||||
|
||||
// Print the arrangement vertices.
|
||||
std::cout << arr.number_of_vertices() << " vertices:\n";
|
||||
for (auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) {
|
||||
std::cout << "(" << vit->point() << ")";
|
||||
if (vit->is_isolated()) std::cout << " - Isolated.\n";
|
||||
else std::cout << " - degree " << vit->degree() << std::endl;
|
||||
}
|
||||
|
||||
// Print the arrangement edges.
|
||||
std::cout << arr.number_of_edges() << " edges:\n";
|
||||
for (auto eit = arr.edges_begin(); eit != arr.edges_end(); ++eit)
|
||||
std::cout << "[" << eit->curve() << "]\n";
|
||||
|
||||
// Print the arrangement faces.
|
||||
std::cout << arr.number_of_faces() << " faces:\n";
|
||||
for (auto fit = arr.faces_begin(); fit != arr.faces_end(); ++fit)
|
||||
print_face<Arrangement>(fit);
|
||||
}
|
||||
|
||||
/*! Print the size of the given arrangement.
|
||||
*/
|
||||
template <typename Arrangement>
|
||||
void print_arrangement_size(const Arrangement& arr) {
|
||||
std::cout << "The arrangement size:\n"
|
||||
<< " |V| = " << arr.number_of_vertices()
|
||||
<< ", |E| = " << arr.number_of_edges()
|
||||
<< ", |F| = " << arr.number_of_faces() << std::endl;
|
||||
}
|
||||
|
||||
/*! Print the size of the given unbounded arrangement.
|
||||
*/
|
||||
template <typename Arrangement>
|
||||
void print_unbounded_arrangement_size(const Arrangement& arr) {
|
||||
std::cout << "The arrangement size:\n"
|
||||
<< " |V| = " << arr.number_of_vertices()
|
||||
<< " (plus " << arr.number_of_vertices_at_infinity()
|
||||
<< " at infinity)"
|
||||
<< ", |E| = " << arr.number_of_edges()
|
||||
<< ", |F| = " << arr.number_of_faces()
|
||||
<< " (" << arr.number_of_unbounded_faces() << " unbounded)\n\n";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// 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>
|
||||
#include <CGAL/config.h>
|
||||
#include <QApplication>
|
||||
#include <QLabel>
|
||||
#include <QSurfaceFormat>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#ifndef QT_NO_OPENGL
|
||||
#include "Main_widget.h"
|
||||
#endif
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
QApplication app(argc, argv);
|
||||
auto args = QCoreApplication::arguments();
|
||||
if (args.size() > 2) {
|
||||
qDebug() << "Usage: earth [<arragement-file.json>]";
|
||||
return(-1);
|
||||
}
|
||||
std::string file_name = (argc > 1) ? argv[1] :
|
||||
CGAL::data_file_path("geometry_on_sphere/ne_110m_admin_0_countries.json");
|
||||
|
||||
if (!std::ifstream(file_name).good()) {
|
||||
std::cerr << "Error: failed to find file " << file_name << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
QSurfaceFormat format;
|
||||
format.setVersion(3, 3);
|
||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
//format.setProfile(QSurfaceFormat::CompatibilityProfile);
|
||||
//format.setOptions(QSurfaceFormat::DeprecatedFunctions);
|
||||
//QSurfaceFormat::setDefaultFormat(format);
|
||||
format.setDepthBufferSize(24);
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
|
||||
app.setApplicationName("Earth");
|
||||
app.setApplicationVersion("0.1");
|
||||
try {
|
||||
#ifndef QT_NO_OPENGL
|
||||
Main_widget widget(file_name.c_str());
|
||||
widget.show();
|
||||
#else
|
||||
QLabel note("OpenGL Support required");
|
||||
note.show();
|
||||
#endif
|
||||
return app.exec();
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << "Try `" << argv[0] << " --help' for more information."
|
||||
<< std::endl;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#version 330
|
||||
|
||||
uniform vec4 u_color;
|
||||
uniform vec4 u_plane;
|
||||
|
||||
in vec3 v_pos;
|
||||
out vec4 out_color;
|
||||
|
||||
void main() {
|
||||
if (dot(u_plane, vec4(v_pos, 1)) < 0) discard;
|
||||
|
||||
out_color = u_color;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#version 330
|
||||
|
||||
layout (location = 0) in vec3 a_pos;
|
||||
|
||||
uniform mat4 u_mvp;
|
||||
|
||||
out vec3 v_pos;
|
||||
|
||||
void main() {
|
||||
v_pos = a_pos;
|
||||
gl_Position = u_mvp * vec4(a_pos.xyz, 1);
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
#version 330
|
||||
|
||||
in vec3 vpos[];
|
||||
out vec4 vCol;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main() {
|
||||
const vec3 lightDir = normalize(vec3(1,.5,.5));
|
||||
|
||||
// compute the normal for the current triangle
|
||||
vec3 triNormal = normalize(cross(vpos[1]-vpos[0], vpos[2]-vpos[0]));
|
||||
//float c = clamp(dot(lightDir,triNormal), 0, 1);
|
||||
float c = abs(dot(lightDir,triNormal));
|
||||
vCol = vec4(.2, .2,0,1) + vec4(c,c,0,1);
|
||||
|
||||
gl_Position = gl_in[0].gl_Position; EmitVertex();
|
||||
gl_Position = gl_in[1].gl_Position; EmitVertex();
|
||||
gl_Position = gl_in[2].gl_Position; EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#version 330
|
||||
|
||||
uniform vec4 u_plane;
|
||||
|
||||
in vec3 v_color;
|
||||
out vec4 out_color;
|
||||
|
||||
void main() {out_color = vec4(v_color, 1); }
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#version 330
|
||||
|
||||
layout (location = 0) in vec3 a_pos;
|
||||
layout (location = 1) in vec3 a_color;
|
||||
|
||||
uniform mat4 u_mvp;
|
||||
|
||||
out vec3 v_color;
|
||||
|
||||
void main() {
|
||||
v_color = a_color;
|
||||
gl_Position = u_mvp * vec4(a_pos.xyz, 1);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
#version 330
|
||||
|
||||
uniform vec4 u_color;
|
||||
uniform vec4 u_plane;
|
||||
|
||||
in vec3 v_pos;
|
||||
in vec3 v_normal;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main() {
|
||||
if (dot(u_plane, vec4(v_pos, 1)) < 0) discard;
|
||||
|
||||
const vec3 lightDir = normalize(vec3(0,0,-1));
|
||||
|
||||
//float c = clamp(dot(lightDir,triNormal), 0, 1);
|
||||
vec3 n = normalize(v_normal);
|
||||
float c = abs(dot(lightDir, n) );
|
||||
out_color = u_color * (vec4(.2, .2,.2,1) + 0.8 * vec4(c,c,c,1));
|
||||
|
||||
//color = vec4(1,1,0,1);
|
||||
//color = vCol;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#version 330
|
||||
|
||||
layout (location = 0) in vec3 a_pos;
|
||||
layout (location = 1) in vec3 a_normal;
|
||||
|
||||
//out vec4 v_col;
|
||||
out vec3 v_pos;
|
||||
out vec3 v_normal;
|
||||
|
||||
uniform mat4 u_mvp;
|
||||
uniform mat3 u_normal_matrix;
|
||||
|
||||
void main() {
|
||||
v_pos = a_pos;
|
||||
v_normal = u_normal_matrix * a_normal;
|
||||
gl_Position = u_mvp * vec4(a_pos.xyz, 1);
|
||||
//gl_Position = vec4(pos.xyz, 1);
|
||||
}
|
||||
|
|
@ -1,16 +1,19 @@
|
|||
\documentclass[12pt]{standalone}
|
||||
\input{header}
|
||||
\usepackage[edges]{forest}
|
||||
\usetikzlibrary{shadows.blur,arrows.meta}
|
||||
\pagestyle{empty}
|
||||
\def\name#1{\textsf{\it #1}}
|
||||
\tikzset{concept/.style={rectangle split,rectangle split parts=1,draw,
|
||||
fill=white,blur shadow,rounded corners,align=center}}
|
||||
\begin{document}
|
||||
\psset{treevshift=0,unit=1em,xunit=2em,yunit=1em,everytree={},
|
||||
etcratio=.75,triratio=.5}
|
||||
\jtree[everylabel=\sl,xunit=70pt,arrows=->]
|
||||
\! = {\psframebox{\concept{ArrangementBasicTraits\_2}}}
|
||||
<vert>[scaleby=0 1.6]{\psframebox{\concept{ArrangementXMonotoneTraits\_2}}}@axmt !axmt
|
||||
.
|
||||
\!axmt = <vert>[scaleby=0 1.6]{\psframebox{\concept{ArrangementTraits\_2}}}@at !at
|
||||
.
|
||||
\endjtree
|
||||
\psset{treevshift=0,unit=1cm,xunit=1cm,yunit=1cm,everytree={},
|
||||
etcratio=.75,triratio=.5}
|
||||
\begin{forest}
|
||||
[\name{ArrangementBasicTraits\_2},
|
||||
forked edges,
|
||||
for tree={concept,edge={-latex}}
|
||||
[\name{ArrangementXMonotoneTraits\_2}
|
||||
[\name{ArrangementTraits\_2}]
|
||||
]
|
||||
]
|
||||
\end{forest}
|
||||
\end{document}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,22 @@
|
|||
\documentclass[12pt]{standalone}
|
||||
\input{header}
|
||||
\usepackage[edges]{forest}
|
||||
\usetikzlibrary{shadows.blur,arrows.meta}
|
||||
\pagestyle{empty}
|
||||
\def\name#1{\textsf{\it #1}}
|
||||
\tikzset{concept/.style={rectangle split,rectangle split parts=1,draw,
|
||||
fill=white,blur shadow,rounded corners,align=center}}
|
||||
\begin{document}
|
||||
\psset{treevshift=0,unit=1em,xunit=2em,yunit=1em,everytree={},
|
||||
etcratio=.75,triratio=.5}
|
||||
\jtree[everylabel=\sl,xunit=70pt,arrows=->]
|
||||
\! = {\psframebox{\concept{ArrangementBasicTraits\_2}}}
|
||||
<left>[scaleby=1.2 1.6]{\psframebox{\concept{ArrangementApproximateTraits\_2}}}@aat !aat
|
||||
^<right>[scaleby=1.8 1.6]{\psframebox{\concept{ArrangementConstructXMonotoneCurveTraits\_2}}}@acxmct !acxmct
|
||||
.
|
||||
\!aat = <right>[scaleby=1.2 1.6]{\psframebox{\concept{ArrangementLandmarkTraits\_2}}}@alt !alt
|
||||
.
|
||||
\ncline{acxmct:b}{alt:t}
|
||||
\endjtree
|
||||
\psset{treevshift=0,unit=1cm,xunit=1cm,yunit=1cm,everytree={},
|
||||
etcratio=.75,triratio=.5}
|
||||
\begin{forest}
|
||||
[\name{ArrangementBasicTraits\_2},name=abt,
|
||||
% forked edges,
|
||||
for tree={concept,edge={-latex}}
|
||||
[\name{ArrangementApproximateTraits\_2}
|
||||
[,phantom]
|
||||
[\name{ArrangementLandmarkTraits\_2},name=alt,before drawing tree={x=0}]
|
||||
]
|
||||
[\name{ArrangementConstructXMonotoneCurveTraits\_2},name=acxmt]
|
||||
]
|
||||
\draw[-latex] (acxmt) to (alt);
|
||||
\end{forest}
|
||||
\end{document}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ if(CGAL_Qt6_FOUND)
|
|||
target_link_libraries(polylines PUBLIC CGAL::CGAL_Basic_viewer)
|
||||
target_link_libraries(circles PUBLIC CGAL::CGAL_Basic_viewer)
|
||||
target_link_libraries(circular_arcs PUBLIC CGAL::CGAL_Basic_viewer)
|
||||
target_link_libraries(spherical_insert PUBLIC CGAL::CGAL_Basic_viewer)
|
||||
else()
|
||||
message(
|
||||
STATUS
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef ARR_GEODESIC_H
|
||||
#define ARR_GEODESIC_H
|
||||
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Arrangement_on_surface_2.h>
|
||||
#include <CGAL/Arr_geodesic_arc_on_sphere_traits_2.h>
|
||||
#include <CGAL/Arr_spherical_topology_traits_2.h>
|
||||
|
||||
using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
using Geom_traits = CGAL::Arr_geodesic_arc_on_sphere_traits_2<Kernel>;
|
||||
using Point = Geom_traits::Point_2;
|
||||
using Curve = Geom_traits::Curve_2;
|
||||
using Topol_traits = CGAL::Arr_spherical_topology_traits_2<Geom_traits>;
|
||||
using Arrangement = CGAL::Arrangement_on_surface_2<Geom_traits, Topol_traits>;
|
||||
|
||||
#endif
|
||||
|
|
@ -2,50 +2,30 @@
|
|||
// Constructing an arrangement of arcs of great circles.
|
||||
|
||||
#include <list>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Arrangement_on_surface_2.h>
|
||||
#include <CGAL/Arr_geodesic_arc_on_sphere_traits_2.h>
|
||||
#include <CGAL/Arr_spherical_topology_traits_2.h>
|
||||
|
||||
#include "arr_geodesic.h"
|
||||
#include "arr_print.h"
|
||||
|
||||
using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
|
||||
using Geom_traits = CGAL::Arr_geodesic_arc_on_sphere_traits_2<Kernel>;
|
||||
using Point = Geom_traits::Point_2;
|
||||
using Curve = Geom_traits::Curve_2;
|
||||
using Topol_traits = CGAL::Arr_spherical_topology_traits_2<Geom_traits>;
|
||||
using Arrangement = CGAL::Arrangement_on_surface_2<Geom_traits, Topol_traits>;
|
||||
|
||||
int main() {
|
||||
// Construct the arrangement from 12 geodesic arcs.
|
||||
Geom_traits traits;
|
||||
Arrangement arr(&traits);
|
||||
|
||||
auto ctr_p = traits.construct_point_2_object();
|
||||
auto ctr_cv = traits.construct_curve_2_object();
|
||||
Arrangement arr(&traits);
|
||||
|
||||
// Observe that the identification curve is a meridian that contains the
|
||||
// point (-11, 7, 0). The curve (-1,0,0),(0,1,0) intersects the identification
|
||||
// curve.
|
||||
|
||||
std::list<Curve> arcs;
|
||||
|
||||
arcs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, 0, -1)));
|
||||
arcs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, 0, 1)));
|
||||
arcs.push_back(ctr_cv(ctr_p(0, 1, 0), ctr_p(0, 0, -1)));
|
||||
arcs.push_back(ctr_cv(ctr_p(0, 1, 0), ctr_p(0, 0, 1)));
|
||||
arcs.push_back(ctr_cv(ctr_p(-1, 0, 0), ctr_p(0, 0, -1)));
|
||||
arcs.push_back(ctr_cv(ctr_p(-1, 0, 0), ctr_p(0, 0, 1)));
|
||||
arcs.push_back(ctr_cv(ctr_p(0, -1, 0), ctr_p(0, 0, -1)));
|
||||
arcs.push_back(ctr_cv(ctr_p(0, -1, 0), ctr_p(0, 0, 1)));
|
||||
arcs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, 1, 0)));
|
||||
arcs.push_back(ctr_cv(ctr_p(1, 0, 0), ctr_p(0, -1, 0)));
|
||||
arcs.push_back(ctr_cv(ctr_p(-1, 0, 0), ctr_p(0, 1, 0)));
|
||||
arcs.push_back(ctr_cv(ctr_p(-1, 0, 0), ctr_p(0, -1, 0)));
|
||||
|
||||
CGAL::insert(arr, arcs.begin(), arcs.end());
|
||||
print_arrangement_size(arr); // print the arrangement size
|
||||
|
||||
Point p1 = ctr_p(0, 0, -1), p3 = ctr_p(0, -1, 0), p5 = ctr_p(-1, 0, 0);
|
||||
Point p2 = ctr_p(0, 0, 1), p4 = ctr_p(0, 1, 0), p6 = ctr_p( 1, 0, 0);
|
||||
Curve arcs[] = {
|
||||
ctr_cv(p6, p1), ctr_cv(p6, p2), ctr_cv(p4, p1), ctr_cv(p4, p2),
|
||||
ctr_cv(p5, p1), ctr_cv(p5, p2), ctr_cv(p3, p1), ctr_cv(p3, p2),
|
||||
ctr_cv(p6, p4), ctr_cv(p6, p3), ctr_cv(p5, p4), ctr_cv(p5, p3) };
|
||||
CGAL::insert(arr, arcs, arcs + sizeof(arcs)/sizeof(Curve));
|
||||
print_arrangement_size(arr);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2939,9 +2939,9 @@ public:
|
|||
}
|
||||
|
||||
// compute the number of divisions given the requested error
|
||||
const Approximate_number_type R = 1.0; // radius is always 1
|
||||
Approximate_number_type dtheta = 2.0 * std::acos(1 - error / R);
|
||||
int num_segs = std::ceil(theta / dtheta);
|
||||
const Approximate_number_type radius = 1.0; // radius is always 1
|
||||
Approximate_number_type dtheta = 2.0 * std::acos(1 - error / radius);
|
||||
auto num_segs = std::ceil(theta / dtheta);
|
||||
dtheta = theta / num_segs;
|
||||
|
||||
// generate the points approximating the curve
|
||||
|
|
|
|||
|
|
@ -1106,32 +1106,7 @@ public:
|
|||
// Generic implementation
|
||||
using Approximate_number_type = void;
|
||||
using Approximate_point_2 = void;
|
||||
|
||||
struct Approximate_2 {
|
||||
/*! Obtain an approximation of a point coordinate.
|
||||
* \param p the exact point.
|
||||
* \param i the coordinate index (either 0 or 1).
|
||||
* \pre i is either 0 or 1.
|
||||
* \return An approximation of p's x-coordinate (if i == 0), or an
|
||||
* approximation of p's y-coordinate (if i == 1).
|
||||
*/
|
||||
Approximate_number_type operator()(const Point_2&, int) const
|
||||
{ CGAL_error_msg("The subtraits does not define Approximate_2!"); }
|
||||
|
||||
/*! Obtain an approximation of a point.
|
||||
*/
|
||||
Approximate_point_2 operator()(const Point_2&) const
|
||||
{ CGAL_error_msg("The subtraits does not define Approximate_2!"); }
|
||||
|
||||
/*! Obtain an approximation of an \f$x\f$-monotone curve.
|
||||
*/
|
||||
template <typename OutputIterator>
|
||||
OutputIterator operator()(const X_monotone_curve_2&, double,
|
||||
OutputIterator oi, bool = true) const {
|
||||
CGAL_error_msg("The subtraits does not define Approximate_2!");
|
||||
return oi;
|
||||
}
|
||||
};
|
||||
using Approximate_2 = void;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
|
|
|||
|
|
@ -1070,7 +1070,7 @@ public:
|
|||
/*!
|
||||
returns a const range (model of `ConstRange`) over handles of the arrangement vertices .
|
||||
*/
|
||||
Iterator_range<Prevent_deref<Vertex_iterator> >
|
||||
Iterator_range<Prevent_deref<Vertex_const_iterator> >
|
||||
vertex_handles() const
|
||||
{
|
||||
return make_prevent_deref_range(vertices_begin(), vertices_end());
|
||||
|
|
@ -1124,7 +1124,7 @@ public:
|
|||
/*!
|
||||
returns a const range (model of `ConstRange`) over handles of the arrangement halfedges .
|
||||
*/
|
||||
Iterator_range<Prevent_deref<Halfedge_iterator> >
|
||||
Iterator_range<Prevent_deref<Halfedge_const_iterator> >
|
||||
halfedge_handles() const
|
||||
{
|
||||
return make_prevent_deref_range(halfedges_begin(), halfedges_end());
|
||||
|
|
@ -1174,7 +1174,7 @@ public:
|
|||
/*!
|
||||
returns a const range (model of `ConstRange`) over handles of the arrangement edges .
|
||||
*/
|
||||
Iterator_range<Prevent_deref<Edge_iterator> >
|
||||
Iterator_range<Prevent_deref<Edge_const_iterator> >
|
||||
edge_handles() const
|
||||
{
|
||||
return make_prevent_deref_range(edges_begin(), edges_end());
|
||||
|
|
@ -1223,11 +1223,12 @@ public:
|
|||
/*!
|
||||
returns a const range (model of `ConstRange`) over handles of the arrangement faces .
|
||||
*/
|
||||
Iterator_range<Prevent_deref<Face_iterator> >
|
||||
Iterator_range<Prevent_deref<Face_const_iterator> >
|
||||
face_handles() const
|
||||
{
|
||||
return make_prevent_deref_range(faces_begin(), faces_end());
|
||||
}
|
||||
|
||||
//! reference_face (const version).
|
||||
/*! The function returns a reference face of the arrangement.
|
||||
* All reference faces of arrangements of the same type have a common
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s): Efi Fogel <efifogel@gmail.com>
|
||||
|
||||
#ifndef CGAL_DRAW_ARRANGEMENT_2_H
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@
|
|||
#include "Traits_base_test.h"
|
||||
|
||||
/*! Traits test */
|
||||
template <typename Geom_traits_T>
|
||||
class Traits_test : public Traits_base_test<Geom_traits_T> {
|
||||
template <typename GeomTraits>
|
||||
class Traits_test : public Traits_base_test<GeomTraits> {
|
||||
private:
|
||||
Traits_test<Geom_traits_T>& operator=(const Traits_test<Geom_traits_T>&);
|
||||
typedef Geom_traits_T Traits;
|
||||
Traits_test<GeomTraits>& operator=(const Traits_test<GeomTraits>&);
|
||||
typedef GeomTraits Traits;
|
||||
typedef Traits_base_test<Traits> Base;
|
||||
typedef typename Base::Enum_type Enum_type;
|
||||
|
||||
|
|
@ -51,8 +51,7 @@ private:
|
|||
|
||||
virtual bool exec(std::istringstream& str_stream,
|
||||
const std::string& str_command,
|
||||
bool& result)
|
||||
{
|
||||
bool& result) {
|
||||
// str_stream is the input file object.
|
||||
// Get the appropriate functor. "str_command" consist of the appropriate
|
||||
// functor string.
|
||||
|
|
@ -170,6 +169,47 @@ private:
|
|||
/*! Tests Approximate_2.
|
||||
* Return an approximation of a point coordinate.
|
||||
*/
|
||||
|
||||
/*! Fall threw implementation to handle the case where the
|
||||
* Approximate_2::operator()(const X_monotone_curve_2& xcv,
|
||||
* Approximate_number_type error,
|
||||
* OutputIterator oi,
|
||||
* bool l2r)
|
||||
* is not supported.
|
||||
*/
|
||||
template <typename GT>
|
||||
bool approximate_wrapper_impl2(std::istringstream& is, long);
|
||||
|
||||
/*! Specialized instance to handle the case where the
|
||||
* Approximate_2::operator()(const X_monotone_curve_2& xcv,
|
||||
* Approximate_number_type error,
|
||||
* OutputIterator oi,
|
||||
* bool l2r)
|
||||
* is supported.
|
||||
*/
|
||||
template <typename GT,
|
||||
typename T =
|
||||
decltype(std::declval<GT>().approximate_2_object().operator()
|
||||
(std::declval<typename GT::X_monotone_curve_2>(),
|
||||
0,
|
||||
(std::declval<int*>())))>
|
||||
bool approximate_wrapper_impl2(std::istringstream& is, int);
|
||||
|
||||
/*! Fall threw implementation to handle the case where the type
|
||||
* Traits::Approximate_2 does not exist.
|
||||
*/
|
||||
template <typename GT>
|
||||
bool approximate_wrapper_impl1(std::istringstream& is, long);
|
||||
|
||||
/*! Specialized instance to handle the case where the type
|
||||
* Traits::Approximate_2 exists.
|
||||
*/
|
||||
template <typename GT,
|
||||
typename T = decltype(std::declval<GT>().approximate_2_object())>
|
||||
bool approximate_wrapper_impl1(std::istringstream& is, int);
|
||||
|
||||
/*!
|
||||
*/
|
||||
bool approximate_wrapper(std::istringstream& line);
|
||||
|
||||
/*! tests Construct_x_monotone_curve_2.
|
||||
|
|
@ -260,11 +300,9 @@ public:
|
|||
/*! Constructor.
|
||||
* Accepts test data file name.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
Traits_test<Geom_traits_T>::Traits_test(const Geom_traits_T& traits) :
|
||||
Base(traits)
|
||||
{
|
||||
typedef Geom_traits_T Traits;
|
||||
template <typename GeomTraits>
|
||||
Traits_test<GeomTraits>::Traits_test(const GeomTraits& traits) : Base(traits) {
|
||||
using Traits = GeomTraits;
|
||||
|
||||
m_wrappers[std::string("compare_x")] =
|
||||
&Traits_test<Traits>::compare_x_wrapper;
|
||||
|
|
@ -344,8 +382,8 @@ Base(traits)
|
|||
|
||||
/*! Destructor.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
Traits_test<Geom_traits_T>::~Traits_test() {}
|
||||
template <typename GeomTraits>
|
||||
Traits_test<GeomTraits>::~Traits_test() {}
|
||||
|
||||
// some polycurve functors needs Segment and x-monotone segment to be defined
|
||||
// which are normally not found in other geom_traits.
|
||||
|
|
@ -354,9 +392,8 @@ Traits_test<Geom_traits_T>::~Traits_test() {}
|
|||
TEST_GEOM_TRAITS == POLYCURVE_BEZIER_GEOM_TRAITS || \
|
||||
TEST_GEOM_TRAITS == POLYLINE_GEOM_TRAITS
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::trim_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::trim_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int x_curve_id, xcv_trimmed, src_id, tgt_id;
|
||||
|
||||
// Read the ID's of the x-curve, source and target points
|
||||
|
|
@ -386,9 +423,8 @@ bool Traits_test<Geom_traits_T>::trim_wrapper(std::istringstream& str_stream)
|
|||
|
||||
/* Test Push_back
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
push_back_wrapper(std::istringstream& str_stream)
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::push_back_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
//type: 0 for pushing a segment into curve.
|
||||
// 1 for pushing x-monotone segment into x-monotone curve.
|
||||
|
|
@ -459,10 +495,9 @@ push_back_wrapper(std::istringstream& str_stream)
|
|||
/*
|
||||
* Test Push_front
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
push_front_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
push_front_wrapper(std::istringstream& str_stream) {
|
||||
//type: 0 for pushing a segment into curve.
|
||||
// 1 for pushing x-monotone segment into x-monotone curve.
|
||||
unsigned int type;
|
||||
|
|
@ -535,10 +570,9 @@ push_front_wrapper(std::istringstream& str_stream)
|
|||
* This wrapper will only test for the x-monotone segments. For testing the
|
||||
* points, compare_x_wrapper can be used.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
compare_x_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_x_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id1, id2;
|
||||
unsigned int expected_answer;
|
||||
unsigned int real_answer;
|
||||
|
|
@ -581,10 +615,9 @@ compare_x_wrapper(std::istringstream& str_stream)
|
|||
return this->compare(expected_answer, real_answer);
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
compare_xy_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_xy_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id1, id2;
|
||||
unsigned int expected_answer;
|
||||
unsigned int real_answer;
|
||||
|
|
@ -629,12 +662,11 @@ compare_xy_wrapper(std::istringstream& str_stream)
|
|||
return this->compare(expected_answer, real_answer);
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
number_of_points_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
typedef Geom_traits_T Geom_traits;
|
||||
typedef typename Geom_traits::size_type size_type;
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
number_of_points_wrapper(std::istringstream& str_stream) {
|
||||
using Geom_traits = GeomTraits;
|
||||
using size_type = typename Geom_traits::size_type;
|
||||
|
||||
unsigned int id;
|
||||
size_type expected_result;
|
||||
|
|
@ -645,10 +677,9 @@ number_of_points_wrapper(std::istringstream& str_stream)
|
|||
return this->compare(expected_result, real_answer);
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
compare_endpoints_xy_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_endpoints_xy_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id;
|
||||
str_stream >> id;
|
||||
|
||||
|
|
@ -662,10 +693,9 @@ compare_endpoints_xy_wrapper(std::istringstream& str_stream)
|
|||
return this->compare(expected_answer, real_answer);
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
construct_opposite_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
construct_opposite_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id1, id2;
|
||||
str_stream >> id1 >> id2;
|
||||
|
||||
|
|
@ -687,10 +717,9 @@ construct_opposite_wrapper(std::istringstream& str_stream)
|
|||
TEST_GEOM_TRAITS != POLYLINE_GEOM_TRAITS
|
||||
/*! Test Compare_x_2
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
compare_x_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_x_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id1, id2;
|
||||
str_stream >> id1 >> id2;
|
||||
unsigned int exp_answer = this->get_expected_enum(str_stream);
|
||||
|
|
@ -705,10 +734,9 @@ compare_x_wrapper(std::istringstream& str_stream)
|
|||
|
||||
/*! Test Compare_xy_2
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
compare_xy_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_xy_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id1, id2;
|
||||
str_stream >> id1 >> id2;
|
||||
unsigned int exp_answer = this->get_expected_enum(str_stream);
|
||||
|
|
@ -726,10 +754,9 @@ compare_xy_wrapper(std::istringstream& str_stream)
|
|||
/*! Tests Construct_min_vertex_2.
|
||||
* Degenerate case: vertical curve.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
min_vertex_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
min_vertex_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id1, id2;
|
||||
str_stream >> id1 >> id2;
|
||||
Point_2& exp_answer = this->m_points[id2];
|
||||
|
|
@ -744,10 +771,9 @@ min_vertex_wrapper(std::istringstream& str_stream)
|
|||
/*! Tests Construct_max_vertex_2.
|
||||
* Degenerate case: vertical curve.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
max_vertex_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
max_vertex_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id1, id2;
|
||||
str_stream >> id1 >> id2;
|
||||
Point_2& exp_answer = this->m_points[id2];
|
||||
|
|
@ -759,11 +785,10 @@ max_vertex_wrapper(std::istringstream& str_stream)
|
|||
return this->compare_points(exp_answer, real_answer);
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
template <typename GeomTraits>
|
||||
bool
|
||||
Traits_test<Geom_traits_T>::
|
||||
is_vertical_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
Traits_test<GeomTraits>::
|
||||
is_vertical_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id;
|
||||
str_stream >> id;
|
||||
bool exp_answer = this->get_expected_boolean(str_stream);
|
||||
|
|
@ -780,11 +805,10 @@ is_vertical_wrapper(std::istringstream& str_stream)
|
|||
* Degenerate cases: The point is an endpoint of the curve.
|
||||
* The curve is vertical.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
template <typename GeomTraits>
|
||||
bool
|
||||
Traits_test<Geom_traits_T>::
|
||||
compare_y_at_x_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
Traits_test<GeomTraits>::
|
||||
compare_y_at_x_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id1, id2;
|
||||
str_stream >> id1 >> id2;
|
||||
unsigned int exp_answer = this->get_expected_enum(str_stream);
|
||||
|
|
@ -804,29 +828,26 @@ compare_y_at_x_wrapper(std::istringstream& str_stream)
|
|||
* The curves coincide and vertical.
|
||||
* One of the curves is vertical.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
template <typename GeomTraits>
|
||||
bool
|
||||
Traits_test<Geom_traits_T>::
|
||||
compare_y_at_x_left_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
typedef typename Geom_traits_T::Has_left_category Has_left_category;
|
||||
Traits_test<GeomTraits>::
|
||||
compare_y_at_x_left_wrapper(std::istringstream& str_stream) {
|
||||
using Has_left_category = typename GeomTraits::Has_left_category;
|
||||
return compare_y_at_x_left_wrapper_imp(str_stream, Has_left_category());
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
template <typename GeomTraits>
|
||||
bool
|
||||
Traits_test<Geom_traits_T>::
|
||||
compare_y_at_x_left_wrapper_imp(std::istringstream&, CGAL::Tag_false)
|
||||
{
|
||||
Traits_test<GeomTraits>::
|
||||
compare_y_at_x_left_wrapper_imp(std::istringstream&, CGAL::Tag_false) {
|
||||
CGAL_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
template <typename GeomTraits>
|
||||
bool
|
||||
Traits_test<Geom_traits_T>::
|
||||
compare_y_at_x_left_wrapper_imp(std::istringstream& str_stream, CGAL::Tag_true)
|
||||
{
|
||||
Traits_test<GeomTraits>::
|
||||
compare_y_at_x_left_wrapper_imp(std::istringstream& str_stream, CGAL::Tag_true) {
|
||||
unsigned int id1, id2, id3;
|
||||
str_stream >> id1 >> id2 >> id3;
|
||||
unsigned int exp_answer = this->get_expected_enum(str_stream);
|
||||
|
|
@ -846,10 +867,9 @@ compare_y_at_x_left_wrapper_imp(std::istringstream& str_stream, CGAL::Tag_true)
|
|||
* The curves coincide and vertical.
|
||||
* One of the curves is vertical.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
compare_y_at_x_right_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_y_at_x_right_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id1, id2, id3;
|
||||
str_stream >> id1 >> id2 >> id3;
|
||||
unsigned int exp_answer = this->get_expected_enum(str_stream);
|
||||
|
|
@ -866,10 +886,9 @@ compare_y_at_x_right_wrapper(std::istringstream& str_stream)
|
|||
/*! Tests Equal_2::operator()(Point_2, Point_2).
|
||||
* Check whether two points are the same.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
equal_points_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
equal_points_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id1, id2;
|
||||
str_stream >> id1 >> id2;
|
||||
bool exp_answer = this->get_expected_boolean(str_stream);
|
||||
|
|
@ -884,10 +903,9 @@ equal_points_wrapper(std::istringstream& str_stream)
|
|||
/*! Tests Equal_2::operator()(X_monotone_curve_2, X_monotone_curve_2).
|
||||
* Check whether two x-monotone curves are the same.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
equal_curves_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
equal_curves_wrapper(std::istringstream& str_stream) {
|
||||
unsigned int id1, id2;
|
||||
str_stream >> id1 >> id2;
|
||||
bool exp_answer = this->get_expected_boolean(str_stream);
|
||||
|
|
@ -906,11 +924,11 @@ equal_curves_wrapper(std::istringstream& str_stream)
|
|||
* segment is vertical. Both first and last are vertical. An internal segment
|
||||
* is vertical.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
make_x_monotone_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
typedef Geom_traits_T Traits;
|
||||
typedef GeomTraits Traits;
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
|
||||
typedef std::variant<Point_2, X_monotone_curve_2> Make_x_monotone_result;
|
||||
|
|
@ -958,12 +976,11 @@ make_x_monotone_wrapper(std::istringstream& str_stream)
|
|||
* left) endpoint of one curve and the first (resp. last) segment of the
|
||||
* other coincide.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
intersect_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
|
||||
typedef Geom_traits_T Traits;
|
||||
typedef GeomTraits Traits;
|
||||
typedef typename Traits::Point_2 Point_2;
|
||||
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
|
||||
typedef typename Traits::Multiplicity Multiplicity;
|
||||
|
|
@ -971,7 +988,6 @@ intersect_wrapper(std::istringstream& str_stream)
|
|||
typedef std::pair<Point_2, Multiplicity> Intersection_point;
|
||||
typedef std::variant<Intersection_point, X_monotone_curve_2>
|
||||
Intersection_result;
|
||||
|
||||
unsigned int id1, id2;
|
||||
str_stream >> id1 >> id2;
|
||||
std::vector<Intersection_result> xections;
|
||||
|
|
@ -1022,10 +1038,9 @@ intersect_wrapper(std::istringstream& str_stream)
|
|||
* Degenerate cases for polylines: the point and a polyline internal point
|
||||
* coincides.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::split_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
typedef Geom_traits_T Traits;
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::split_wrapper(std::istringstream& str_stream) {
|
||||
typedef GeomTraits Traits;
|
||||
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
|
||||
|
||||
unsigned int id1, id2, id3, id4;
|
||||
|
|
@ -1043,29 +1058,25 @@ bool Traits_test<Geom_traits_T>::split_wrapper(std::istringstream& str_stream)
|
|||
/*! Tests Are_mergeable_2.
|
||||
* Check whether it is possible to merge two given x-monotone curves.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
are_mergeable_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
typedef typename Geom_traits_T::Has_merge_category Has_merge_category;
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
are_mergeable_wrapper(std::istringstream& str_stream) {
|
||||
using Has_merge_category = typename GeomTraits::Has_merge_category;
|
||||
return are_mergeable_wrapper_imp(str_stream, Has_merge_category());
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
template <typename GeomTraits>
|
||||
bool
|
||||
Traits_test<Geom_traits_T>::
|
||||
are_mergeable_wrapper_imp(std::istringstream&, CGAL::Tag_false)
|
||||
{
|
||||
//waqar
|
||||
Traits_test<GeomTraits>::
|
||||
are_mergeable_wrapper_imp(std::istringstream&, CGAL::Tag_false) {
|
||||
std::cout << "I am at the wrong place" << std::endl;
|
||||
CGAL_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
are_mergeable_wrapper_imp(std::istringstream& str_stream, CGAL::Tag_true)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
are_mergeable_wrapper_imp(std::istringstream& str_stream, CGAL::Tag_true) {
|
||||
unsigned int id1, id2;
|
||||
str_stream >> id1 >> id2;
|
||||
bool exp_answer = this->get_expected_boolean(str_stream);
|
||||
|
|
@ -1081,28 +1092,24 @@ are_mergeable_wrapper_imp(std::istringstream& str_stream, CGAL::Tag_true)
|
|||
/*! Tests Merge_2.
|
||||
* Merge two given x-monotone curves into a single curve.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::merge_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
typedef typename Geom_traits_T::Has_merge_category Has_merge_category;
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::merge_wrapper(std::istringstream& str_stream) {
|
||||
typedef typename GeomTraits::Has_merge_category Has_merge_category;
|
||||
return merge_wrapper_imp(str_stream, Has_merge_category());
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::merge_wrapper_imp(std::istringstream&,
|
||||
CGAL::Tag_false)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
merge_wrapper_imp(std::istringstream&, CGAL::Tag_false) {
|
||||
CGAL_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool
|
||||
Traits_test<Geom_traits_T>::merge_wrapper_imp(std::istringstream& str_stream,
|
||||
CGAL::Tag_true)
|
||||
{
|
||||
typedef Geom_traits_T Traits;
|
||||
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
merge_wrapper_imp(std::istringstream& str_stream, CGAL::Tag_true) {
|
||||
using Traits = GeomTraits ;
|
||||
using X_monotone_curve_2 = typename Traits::X_monotone_curve_2;
|
||||
|
||||
unsigned int id1, id2, id;
|
||||
str_stream >> id1 >> id2 >> id;
|
||||
|
|
@ -1115,25 +1122,70 @@ Traits_test<Geom_traits_T>::merge_wrapper_imp(std::istringstream& str_stream,
|
|||
return this->compare_curves(this->m_xcurves[id], cv);
|
||||
}
|
||||
|
||||
//! Fall threw instance
|
||||
template <typename GeomTraits>
|
||||
template <typename GT>
|
||||
bool Traits_test<GeomTraits>::
|
||||
approximate_wrapper_impl2(std::istringstream&, long) { return false; }
|
||||
|
||||
//! Specialized instance
|
||||
template <typename GeomTraits>
|
||||
template <typename GT, typename T>
|
||||
bool Traits_test<GeomTraits>::
|
||||
approximate_wrapper_impl2(std::istringstream& is, int) {
|
||||
std::size_t id;
|
||||
typename GeomTraits::Approximate_number_type error;
|
||||
bool l2r;
|
||||
is >> id >> error >> l2r;
|
||||
const auto& xcv = this->m_xcurves[id];
|
||||
using Ap2 = typename GeomTraits::Approximate_point_2;
|
||||
std::vector<Ap2> apoints;
|
||||
|
||||
auto approx = this->m_geom_traits.approximate_2_object();
|
||||
approx(xcv, error, std::back_inserter(apoints), l2r);
|
||||
|
||||
std::size_t exp_num_apoints;
|
||||
is >> exp_num_apoints;
|
||||
if (apoints.size() != exp_num_apoints) {
|
||||
std::cout << "xcv: " << xcv << std::endl;
|
||||
std::cout << "error: " << error << std::endl;
|
||||
for (const auto& pt : apoints) {
|
||||
std::cout << pt << std::endl;
|
||||
}
|
||||
std::cerr << "Error: no. of inexact points does not match ("
|
||||
<< apoints.size() << ", " << exp_num_apoints
|
||||
<< ")!\n";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Fall threw instance
|
||||
template <typename GeomTraits>
|
||||
template <typename GT>
|
||||
bool Traits_test<GeomTraits>::
|
||||
approximate_wrapper_impl1(std::istringstream&, long) { return false; }
|
||||
|
||||
//! Specialized instance
|
||||
template <typename GeomTraits>
|
||||
template <typename GT, typename T>
|
||||
bool Traits_test<GeomTraits>::
|
||||
approximate_wrapper_impl1(std::istringstream& is, int)
|
||||
{ return approximate_wrapper_impl2<GeomTraits>(is, 0); }
|
||||
|
||||
/*! Tests Approximate_2.
|
||||
* Return an approximation of a point coordinate.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool
|
||||
Traits_test<Geom_traits_T>::approximate_wrapper(std::istringstream& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::approximate_wrapper(std::istringstream& is)
|
||||
{ return approximate_wrapper_impl1<GeomTraits>(is, 0); }
|
||||
|
||||
/*! tests Construct_x_monotone_curve_2.
|
||||
* Return an x-monotone curve connecting the two given endpoints.
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
construct_x_monotone_curve_wrapper(std::istringstream& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
construct_x_monotone_curve_wrapper(std::istringstream&) { return false; }
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////
|
||||
// boundary-specific functors
|
||||
|
|
@ -1143,35 +1195,30 @@ construct_x_monotone_curve_wrapper(std::istringstream& )
|
|||
|
||||
/*! Test Parameter_space_in_x_2
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
parameter_space_in_x_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
typedef typename
|
||||
CGAL::internal::Arr_complete_left_side_category< Geom_traits_T >::Category
|
||||
Left_side_category;
|
||||
typedef typename
|
||||
CGAL::internal::Arr_complete_right_side_category< Geom_traits_T >::Category
|
||||
Right_side_category;
|
||||
typedef CGAL::internal::Arr_left_right_implementation_dispatch
|
||||
<Left_side_category, Right_side_category> LR;
|
||||
typedef typename LR::Parameter_space_in_x_2_curve_end_tag Psx_tag;
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
parameter_space_in_x_wrapper(std::istringstream& str_stream) {
|
||||
using Left_side_category = typename
|
||||
CGAL::internal::Arr_complete_left_side_category<GeomTraits>::Category;
|
||||
using Right_side_category = typename
|
||||
CGAL::internal::Arr_complete_right_side_category<GeomTraits>::Category;
|
||||
using LR = CGAL::internal::Arr_left_right_implementation_dispatch
|
||||
<Left_side_category, Right_side_category>;
|
||||
using Psx_tag = typename LR::Parameter_space_in_x_2_curve_end_tag;
|
||||
return parameter_space_in_x_wrapper_imp(str_stream, Psx_tag());
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
parameter_space_in_x_wrapper_imp(std::istringstream&, CGAL::Arr_use_dummy_tag)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
parameter_space_in_x_wrapper_imp(std::istringstream&, CGAL::Arr_use_dummy_tag) {
|
||||
CGAL_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
parameter_space_in_x_wrapper_imp(std::istringstream& str_stream,
|
||||
CGAL::Arr_use_traits_tag)
|
||||
{
|
||||
CGAL::Arr_use_traits_tag) {
|
||||
CGAL::Arr_parameter_space exp_answer, real_answer;
|
||||
unsigned int id;
|
||||
str_stream >> id;
|
||||
|
|
@ -1211,36 +1258,31 @@ parameter_space_in_x_wrapper_imp(std::istringstream& str_stream,
|
|||
|
||||
/*! Test Compare_y_near_boundary_2
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
compare_y_near_boundary_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
typedef typename
|
||||
CGAL::internal::Arr_complete_left_side_category<Geom_traits_T >::Category
|
||||
Left_side_category;
|
||||
typedef typename
|
||||
CGAL::internal::Arr_complete_right_side_category<Geom_traits_T >::Category
|
||||
Right_side_category;
|
||||
typedef CGAL::internal::Arr_left_right_implementation_dispatch
|
||||
<Left_side_category, Right_side_category> LR;
|
||||
typedef typename LR::Compare_y_near_boundary_2_curve_ends_tag Cmp_tag;
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_y_near_boundary_wrapper(std::istringstream& str_stream) {
|
||||
using Left_side_category = typename
|
||||
CGAL::internal::Arr_complete_left_side_category<GeomTraits >::Category;
|
||||
using Right_side_category = typename
|
||||
CGAL::internal::Arr_complete_right_side_category<GeomTraits >::Category;
|
||||
using LR = CGAL::internal::Arr_left_right_implementation_dispatch
|
||||
<Left_side_category, Right_side_category>;
|
||||
using Cmp_tag = typename LR::Compare_y_near_boundary_2_curve_ends_tag;
|
||||
return compare_y_near_boundary_wrapper_imp(str_stream, Cmp_tag());
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_y_near_boundary_wrapper_imp(std::istringstream&,
|
||||
CGAL::Arr_use_dummy_tag)
|
||||
{
|
||||
CGAL::Arr_use_dummy_tag) {
|
||||
CGAL_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_y_near_boundary_wrapper_imp(std::istringstream& str_stream,
|
||||
CGAL::Arr_use_traits_tag)
|
||||
{
|
||||
CGAL::Arr_use_traits_tag) {
|
||||
unsigned int id1, id2;
|
||||
str_stream >> id1 >> id2;
|
||||
std::pair<Enum_type, unsigned int> next_input =
|
||||
|
|
@ -1272,35 +1314,30 @@ compare_y_near_boundary_wrapper_imp(std::istringstream& str_stream,
|
|||
|
||||
/*! Test Parameter_space_in_y_2
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
parameter_space_in_y_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
typedef typename
|
||||
CGAL::internal::Arr_complete_bottom_side_category<Geom_traits_T>::Category
|
||||
Bottom_side_category;
|
||||
typedef typename
|
||||
CGAL::internal::Arr_complete_top_side_category<Geom_traits_T>::Category
|
||||
Top_side_category;
|
||||
typedef CGAL::internal::Arr_bottom_top_implementation_dispatch
|
||||
<Bottom_side_category, Top_side_category> BT;
|
||||
typedef typename BT::Parameter_space_in_y_2_curve_end_tag Psy_tag;
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
parameter_space_in_y_wrapper(std::istringstream& str_stream) {
|
||||
using Bottom_side_category = typename
|
||||
CGAL::internal::Arr_complete_bottom_side_category<GeomTraits>::Category;
|
||||
using Top_side_category = typename
|
||||
CGAL::internal::Arr_complete_top_side_category<GeomTraits>::Category;
|
||||
using BT = CGAL::internal::Arr_bottom_top_implementation_dispatch
|
||||
<Bottom_side_category, Top_side_category>;
|
||||
using Psy_tag = typename BT::Parameter_space_in_y_2_curve_end_tag;
|
||||
return parameter_space_in_y_wrapper_imp(str_stream, Psy_tag());
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
parameter_space_in_y_wrapper_imp(std::istringstream&, CGAL::Arr_use_dummy_tag)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
parameter_space_in_y_wrapper_imp(std::istringstream&, CGAL::Arr_use_dummy_tag) {
|
||||
CGAL_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
parameter_space_in_y_wrapper_imp(std::istringstream& str_stream,
|
||||
CGAL::Arr_use_traits_tag)
|
||||
{
|
||||
CGAL::Arr_use_traits_tag) {
|
||||
unsigned int id;
|
||||
str_stream >> id;
|
||||
std::pair<Enum_type, unsigned int> next_input =
|
||||
|
|
@ -1340,36 +1377,31 @@ parameter_space_in_y_wrapper_imp(std::istringstream& str_stream,
|
|||
|
||||
/* Compare_x_near_boundary_2
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
compare_x_near_boundary_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
typedef typename
|
||||
CGAL::internal::Arr_complete_bottom_side_category<Geom_traits_T>::Category
|
||||
Bottom_side_category;
|
||||
typedef typename
|
||||
CGAL::internal::Arr_complete_top_side_category<Geom_traits_T>::Category
|
||||
Top_side_category;
|
||||
typedef CGAL::internal::Arr_bottom_top_implementation_dispatch
|
||||
<Bottom_side_category, Top_side_category> BT;
|
||||
typedef typename BT::Compare_x_near_boundary_2_curve_ends_tag Cmp_tag;
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_x_near_boundary_wrapper(std::istringstream& str_stream) {
|
||||
using Bottom_side_category = typename
|
||||
CGAL::internal::Arr_complete_bottom_side_category<GeomTraits>::Category;
|
||||
using Top_side_category = typename
|
||||
CGAL::internal::Arr_complete_top_side_category<GeomTraits>::Category;
|
||||
using BT = CGAL::internal::Arr_bottom_top_implementation_dispatch
|
||||
<Bottom_side_category, Top_side_category>;
|
||||
using Cmp_tag = typename BT::Compare_x_near_boundary_2_curve_ends_tag;
|
||||
return compare_x_near_boundary_wrapper_imp(str_stream, Cmp_tag());
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_x_near_boundary_wrapper_imp(std::istringstream&,
|
||||
CGAL::Arr_use_dummy_tag)
|
||||
{
|
||||
CGAL::Arr_use_dummy_tag) {
|
||||
CGAL_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_x_near_boundary_wrapper_imp(std::istringstream& str_stream,
|
||||
CGAL::Arr_use_traits_tag)
|
||||
{
|
||||
CGAL::Arr_use_traits_tag) {
|
||||
std::cout << "Test: compare_x_near_boundary( ";
|
||||
|
||||
unsigned int id1, id2;
|
||||
|
|
@ -1400,42 +1432,34 @@ compare_x_near_boundary_wrapper_imp(std::istringstream& str_stream,
|
|||
|
||||
/* Compare_x_on_boundary
|
||||
*/
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
compare_x_on_boundary_wrapper(std::istringstream& str_stream)
|
||||
{
|
||||
typedef typename
|
||||
CGAL::internal::Arr_complete_bottom_side_category<Geom_traits_T>::Category
|
||||
Bottom_side_category;
|
||||
typedef typename
|
||||
CGAL::internal::Arr_complete_top_side_category<Geom_traits_T>::Category
|
||||
Top_side_category;
|
||||
typedef CGAL::internal::Arr_bottom_top_implementation_dispatch
|
||||
<Bottom_side_category, Top_side_category> BT;
|
||||
typedef typename BT::Compare_x_on_boundary_2_points_tag Cmp_tag1;
|
||||
typedef typename BT::Compare_x_on_boundary_2_point_curve_end_tag Cmp_tag2;
|
||||
typedef typename BT::Compare_x_on_boundary_2_curve_ends_tag Cmp_tag3;
|
||||
typedef typename CGAL::internal::Or_traits<Cmp_tag1, Cmp_tag2>::type
|
||||
Cmp_tag12;
|
||||
typedef typename CGAL::internal::Or_traits<Cmp_tag12, Cmp_tag3>::type
|
||||
Cmp_tag;
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_x_on_boundary_wrapper(std::istringstream& str_stream) {
|
||||
using Bottom_side_category = typename
|
||||
CGAL::internal::Arr_complete_bottom_side_category<GeomTraits>::Category;
|
||||
using Top_side_category = typename
|
||||
CGAL::internal::Arr_complete_top_side_category<GeomTraits>::Category;
|
||||
using BT = CGAL::internal::Arr_bottom_top_implementation_dispatch
|
||||
<Bottom_side_category, Top_side_category>;
|
||||
using Cmp_tag1 = typename BT::Compare_x_on_boundary_2_points_tag;
|
||||
using Cmp_tag2 = typename BT::Compare_x_on_boundary_2_point_curve_end_tag;
|
||||
using Cmp_tag3 = typename BT::Compare_x_on_boundary_2_curve_ends_tag;
|
||||
using Cmp_tag12 = typename CGAL::internal::Or_traits<Cmp_tag1, Cmp_tag2>::type;
|
||||
using Cmp_tag = typename CGAL::internal::Or_traits<Cmp_tag12, Cmp_tag3>::type;
|
||||
return compare_x_on_boundary_wrapper_imp(str_stream, Cmp_tag());
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
compare_x_on_boundary_wrapper_imp(std::istringstream&,
|
||||
CGAL::Arr_use_dummy_tag)
|
||||
{
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_x_on_boundary_wrapper_imp(std::istringstream&, CGAL::Arr_use_dummy_tag) {
|
||||
CGAL_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Geom_traits_T>
|
||||
bool Traits_test<Geom_traits_T>::
|
||||
template <typename GeomTraits>
|
||||
bool Traits_test<GeomTraits>::
|
||||
compare_x_on_boundary_wrapper_imp(std::istringstream& str_stream,
|
||||
CGAL::Arr_use_traits_tag)
|
||||
{
|
||||
CGAL::Arr_use_traits_tag) {
|
||||
// TBD: points
|
||||
std::cout << "Test: compare_x_on_boundary( ";
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ set(IS_BETWEEN_CW 26)
|
|||
set(COMPARE_CW_AROUND_POINT 27)
|
||||
set(PUSH_BACK 28)
|
||||
set(PUSH_FRONT 29)
|
||||
set(APPROXIMATE 30)
|
||||
set(NUMBER_OF_POINTS 32)
|
||||
set(COMPARE_ENDPOINTS_XY 33)
|
||||
set(CONSTRUCT_OPPOSITE 34)
|
||||
|
|
@ -240,22 +241,30 @@ function(execute_commands_old_structure data_dir traits_type_name)
|
|||
# the old structure is default, so this function executes all commands
|
||||
# except the commands that are given as arguments
|
||||
|
||||
set(commands_indicator_APPROXIMATE 1)
|
||||
set(commands_indicator_ARE_MERGEABLE 1)
|
||||
set(commands_indicator_ASSERTIONS 1)
|
||||
set(commands_indicator_COMPARE 1)
|
||||
set(commands_indicator_VERTEX 1)
|
||||
set(commands_indicator_IS_VERTICAL 1)
|
||||
set(commands_indicator_COMPARE_Y_AT_X 1)
|
||||
set(commands_indicator_COMPARE_Y_AT_X_LEFT 1)
|
||||
set(commands_indicator_COMPARE_Y_AT_X_RIGHT 1)
|
||||
set(commands_indicator_MAKE_X_MONOTONE 1)
|
||||
set(commands_indicator_INTERSECT 1)
|
||||
set(commands_indicator_SPLIT 1)
|
||||
set(commands_indicator_ARE_MERGEABLE 1)
|
||||
set(commands_indicator_MERGE 1)
|
||||
set(commands_indicator_ASSERTIONS 1)
|
||||
set(commands_indicator_CONSTRUCTOR 1)
|
||||
set(commands_indicator_INTERSECT 1)
|
||||
set(commands_indicator_IS_VERTICAL 1)
|
||||
set(commands_indicator_MAKE_X_MONOTONE 1)
|
||||
set(commands_indicator_MERGE 1)
|
||||
set(commands_indicator_SPLIT 1)
|
||||
set(commands_indicator_VERTEX 1)
|
||||
|
||||
foreach(arg ${ARGN})
|
||||
set(commands_indicator_${arg} 0)
|
||||
endforeach()
|
||||
|
||||
if(commands_indicator_APPROXIMATE)
|
||||
run_trapped_test(test_traits
|
||||
data/empty.zero data/${data_dir}/approximate.xcv
|
||||
data/empty.zero data/${data_dir}/approximate ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_COMPARE)
|
||||
run_trapped_test(test_traits
|
||||
data/compare.pt data/empty.zero
|
||||
|
|
@ -278,18 +287,21 @@ function(execute_commands_old_structure data_dir traits_type_name)
|
|||
endif()
|
||||
if(commands_indicator_COMPARE_Y_AT_X_LEFT)
|
||||
run_trapped_test(test_traits
|
||||
data/${data_dir}/compare_y_at_x_left.pt data/${data_dir}/compare_y_at_x_left.xcv
|
||||
data/${data_dir}/compare_y_at_x_left.pt
|
||||
data/${data_dir}/compare_y_at_x_left.xcv
|
||||
data/empty.zero data/${data_dir}/compare_y_at_x_left ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_COMPARE_Y_AT_X_RIGHT)
|
||||
run_trapped_test(test_traits
|
||||
data/${data_dir}/compare_y_at_x_right.pt data/${data_dir}/compare_y_at_x_right.xcv
|
||||
data/${data_dir}/compare_y_at_x_right.pt
|
||||
data/${data_dir}/compare_y_at_x_right.xcv
|
||||
data/empty.zero data/${data_dir}/compare_y_at_x_right ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_MAKE_X_MONOTONE)
|
||||
run_trapped_test(test_traits
|
||||
data/empty.zero data/${data_dir}/make_x_monotone.xcv
|
||||
data/${data_dir}/make_x_monotone.cv data/${data_dir}/make_x_monotone ${traits_type_name})
|
||||
data/${data_dir}/make_x_monotone.cv
|
||||
data/${data_dir}/make_x_monotone ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_INTERSECT)
|
||||
run_trapped_test(test_traits
|
||||
|
|
@ -319,7 +331,8 @@ function(execute_commands_old_structure data_dir traits_type_name)
|
|||
if(commands_indicator_CONSTRUCTOR)
|
||||
run_trapped_test(test_traits
|
||||
data/empty.zero data/${data_dir}/constructor.xcv
|
||||
data/${data_dir}/constructor.cv data/${data_dir}/constructor ${traits_type_name})
|
||||
data/${data_dir}/constructor.cv data/${data_dir}/constructor
|
||||
${traits_type_name})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
|
@ -332,133 +345,166 @@ function(execute_commands_new_structure data_dir traits_type_name)
|
|||
# the new structure is not default, so this function executes only
|
||||
# commands that are given as arguments
|
||||
|
||||
set(commands_indicator_APPROXIMATE 0)
|
||||
set(commands_indicator_ARE_MERGEABLE 0)
|
||||
set(commands_indicator_ASSERTIONS 0)
|
||||
set(commands_indicator_COMPARE 0)
|
||||
set(commands_indicator_VERTEX 0)
|
||||
set(commands_indicator_IS_VERTICAL 0)
|
||||
set(commands_indicator_COMPARE_X_ON_BOUNDARY 0)
|
||||
set(commands_indicator_COMPARE_ENDPOINTS_XY 0)
|
||||
set(commands_indicator_COMPARE_X_NEAR_BOUNDARY 0)
|
||||
set(commands_indicator_COMPARE_Y_NEAR_BOUNDARY 0)
|
||||
set(commands_indicator_PARAMETER_SPACE_X 0)
|
||||
set(commands_indicator_PARAMETER_SPACE_Y 0)
|
||||
set(commands_indicator_COMPARE_X_ON_BOUNDARY 0)
|
||||
set(commands_indicator_COMPARE_Y_AT_X 0)
|
||||
set(commands_indicator_COMPARE_Y_AT_X_LEFT 0)
|
||||
set(commands_indicator_COMPARE_Y_AT_X_RIGHT 0)
|
||||
set(commands_indicator_MAKE_X_MONOTONE 0)
|
||||
set(commands_indicator_INTERSECT 0)
|
||||
set(commands_indicator_SPLIT 0)
|
||||
set(commands_indicator_ARE_MERGEABLE 0)
|
||||
set(commands_indicator_MERGE 0)
|
||||
set(commands_indicator_ASSERTIONS 0)
|
||||
set(commands_indicator_COMPARE_Y_NEAR_BOUNDARY 0)
|
||||
set(commands_indicator_CONSTRUCTOR 0)
|
||||
set(commands_indicator_CONSTRUCT_OPPOSITE 0)
|
||||
set(commands_indicator_EQUAL 0)
|
||||
set(commands_indicator_INTERSECT 0)
|
||||
set(commands_indicator_IS_VERTICAL 0)
|
||||
set(commands_indicator_MAKE_X_MONOTONE 0)
|
||||
set(commands_indicator_MERGE 0)
|
||||
set(commands_indicator_NUMBER_OF_POINTS 0)
|
||||
set(commands_indicator_PARAMETER_SPACE_X 0)
|
||||
set(commands_indicator_PARAMETER_SPACE_Y 0)
|
||||
set(commands_indicator_PUSH_BACK 0)
|
||||
set(commands_indicator_PUSH_FRONT 0)
|
||||
set(commands_indicator_NUMBER_OF_POINTS 0)
|
||||
set(commands_indicator_COMPARE_ENDPOINTS_XY 0)
|
||||
set(commands_indicator_CONSTRUCT_OPPOSITE 0)
|
||||
set(commands_indicator_SPLIT 0)
|
||||
set(commands_indicator_TRIM 0)
|
||||
set(commands_indicator_VERTEX 0)
|
||||
|
||||
foreach(arg ${ARGN})
|
||||
set(commands_indicator_${arg} 1)
|
||||
endforeach()
|
||||
|
||||
if(commands_indicator_APPROXIMATE)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/approximate ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_COMPARE)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/compare ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/compare ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_VERTEX)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/vertex ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/vertex ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_IS_VERTICAL)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/is_vertical ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/is_vertical ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_COMPARE_X_ON_BOUNDARY)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/compare_x_on_boundary ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/compare_x_on_boundary ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_COMPARE_X_NEAR_BOUNDARY)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/compare_x_near_boundary ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/compare_x_near_boundary ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_COMPARE_Y_NEAR_BOUNDARY)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/compare_y_near_boundary ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/compare_y_near_boundary ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_PARAMETER_SPACE_X)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/parameter_space_x ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/parameter_space_x ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_PARAMETER_SPACE_Y)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/parameter_space_y ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/parameter_space_y ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_COMPARE_Y_AT_X)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/compare_y_at_x ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/compare_y_at_x ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_COMPARE_Y_AT_X_LEFT)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/compare_y_at_x_left ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/compare_y_at_x_left ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_COMPARE_Y_AT_X_RIGHT)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/compare_y_at_x_right ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/compare_y_at_x_right ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_MAKE_X_MONOTONE)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/make_x_monotone ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/make_x_monotone ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_INTERSECT)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/intersect ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/intersect ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_SPLIT)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/split ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/split ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_ARE_MERGEABLE)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/are_mergeable ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/are_mergeable ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_MERGE)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/merge ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/merge ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_ASSERTIONS)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/assertions ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/assertions ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_CONSTRUCTOR)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/constructor ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/constructor ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_EQUAL)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/equal ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/equal ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_PUSH_BACK)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/push_back ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/push_back ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_PUSH_FRONT)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/push_front ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/push_front ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_NUMBER_OF_POINTS)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/number_of_points ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/number_of_points ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_COMPARE_ENDPOINTS_XY)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/compare_endpoints_xy ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/compare_endpoints_xy ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_CONSTRUCT_OPPOSITE)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/construct_opposite ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/construct_opposite ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_TRIM)
|
||||
run_trapped_test(test_traits data/${data_dir}/points
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves data/${data_dir}/trim ${traits_type_name})
|
||||
data/${data_dir}/xcurves data/${data_dir}/curves
|
||||
data/${data_dir}/trim ${traits_type_name})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
|
@ -467,26 +513,32 @@ function(execute_commands_traits_adaptor data_dir traits_type_name)
|
|||
# the new structure is not default, so this function executes only
|
||||
# commands that are given as arguments
|
||||
|
||||
set(commands_indicator_PARAMETER_SPACE_X 0)
|
||||
set(commands_indicator_PARAMETER_SPACE_Y 0)
|
||||
set(commands_indicator_ARE_MERGEABLE 0)
|
||||
set(commands_indicator_COMPARE_CW_AROUND_POINT 0)
|
||||
set(commands_indicator_COMPARE_XY 0)
|
||||
set(commands_indicator_COMPARE_X_ON_BOUNDARY 0)
|
||||
set(commands_indicator_COMPARE_Y_AT_X_LEFT 0)
|
||||
set(commands_indicator_COMPARE_X_NEAR_BOUNDARY 0)
|
||||
set(commands_indicator_COMPARE_Y_NEAR_BOUNDARY 0)
|
||||
set(commands_indicator_COMPARE_Y_AT_X_LEFT 0)
|
||||
set(commands_indicator_ARE_MERGEABLE 0)
|
||||
set(commands_indicator_MERGE 0)
|
||||
set(commands_indicator_X_ON_IDENTIFICATION 0)
|
||||
set(commands_indicator_Y_ON_IDENTIFICATION 0)
|
||||
set(commands_indicator_IS_BOUNDED 0)
|
||||
set(commands_indicator_IS_IN_X_RANGE 0)
|
||||
set(commands_indicator_COMPARE_X_ON_BOUNDARY 0)
|
||||
set(commands_indicator_COMPARE_Y_POSITION 0)
|
||||
set(commands_indicator_IS_BETWEEN_CW 0)
|
||||
set(commands_indicator_COMPARE_CW_AROUND_POINT 0)
|
||||
set(commands_indicator_IS_BOUNDED 0)
|
||||
set(commands_indicator_IS_IN_X_RANGE 0)
|
||||
set(commands_indicator_MERGE 0)
|
||||
set(commands_indicator_PARAMETER_SPACE_X 0)
|
||||
set(commands_indicator_PARAMETER_SPACE_Y 0)
|
||||
set(commands_indicator_X_ON_IDENTIFICATION 0)
|
||||
set(commands_indicator_Y_ON_IDENTIFICATION 0)
|
||||
|
||||
foreach(arg ${ARGN})
|
||||
set(commands_indicator_${arg} 1)
|
||||
endforeach()
|
||||
|
||||
if(commands_indicator_ARE_MERGEABLE)
|
||||
run_trapped_test(test_traits_adaptor data/test_adaptor/${data_dir}/points
|
||||
data/test_adaptor/${data_dir}/xcurves data/test_adaptor/${data_dir}/curves
|
||||
data/test_adaptor/${data_dir}/are_mergeable ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_PARAMETER_SPACE_X)
|
||||
run_trapped_test(test_traits_adaptor data/test_adaptor/${data_dir}/points
|
||||
data/test_adaptor/${data_dir}/xcurves data/test_adaptor/${data_dir}/curves
|
||||
|
|
@ -524,11 +576,6 @@ function(execute_commands_traits_adaptor data_dir traits_type_name)
|
|||
data/test_adaptor/${data_dir}/xcurves data/test_adaptor/${data_dir}/curves
|
||||
data/test_adaptor/${data_dir}/compare_y_at_x_left ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_ARE_MERGEABLE)
|
||||
run_trapped_test(test_traits_adaptor data/test_adaptor/${data_dir}/points
|
||||
data/test_adaptor/${data_dir}/xcurves data/test_adaptor/${data_dir}/curves
|
||||
data/test_adaptor/${data_dir}/are_mergeable ${traits_type_name})
|
||||
endif()
|
||||
if(commands_indicator_MERGE)
|
||||
run_trapped_test(test_traits_adaptor data/test_adaptor/${data_dir}/points
|
||||
data/test_adaptor/${data_dir}/xcurves data/test_adaptor/${data_dir}/curves
|
||||
|
|
@ -582,7 +629,7 @@ function(test_segment_traits_adaptor)
|
|||
|
||||
compile_test_with_flags(test_traits_adaptor segments "${flags}")
|
||||
# if [ -n "${SUCCESS}" ] ; then
|
||||
execute_commands_traits_adaptor( segments segments_traits_adaptor
|
||||
execute_commands_traits_adaptor(segments segments_traits_adaptor
|
||||
COMPARE_XY COMPARE_Y_POSITION COMPARE_CW_AROUND_POINT COMPARE_Y_AT_X_LEFT
|
||||
ARE_MERGEABLE MERGE IS_IN_X_RANGE IS_BETWEEN_CW)
|
||||
endfunction()
|
||||
|
|
@ -598,7 +645,7 @@ function(test_linear_traits_adaptor)
|
|||
|
||||
compile_test_with_flags( test_traits_adaptor linear "${flags}")
|
||||
|
||||
execute_commands_traits_adaptor( linear linear_traits_adaptor
|
||||
execute_commands_traits_adaptor(linear linear_traits_adaptor
|
||||
COMPARE_XY COMPARE_Y_AT_X_LEFT ARE_MERGEABLE MERGE IS_IN_X_RANGE
|
||||
COMPARE_Y_POSITION IS_BETWEEN_CW COMPARE_CW_AROUND_POINT)
|
||||
endfunction()
|
||||
|
|
@ -615,7 +662,7 @@ function(test_spherical_arcs_traits_adaptor)
|
|||
|
||||
compile_test_with_flags( test_traits_adaptor geodesic_arcs_on_sphere "${flags}")
|
||||
|
||||
execute_commands_traits_adaptor( spherical_arcs spherical_arcs_traits_adaptor
|
||||
execute_commands_traits_adaptor(spherical_arcs spherical_arcs_traits_adaptor
|
||||
COMPARE_XY COMPARE_Y_AT_X_LEFT ARE_MERGEABLE MERGE IS_IN_X_RANGE
|
||||
COMPARE_Y_POSITION IS_BETWEEN_CW COMPARE_CW_AROUND_POINT)
|
||||
endfunction()
|
||||
|
|
@ -643,7 +690,7 @@ function(test_construction_segments)
|
|||
set(kernel ${CARTESIAN_KERNEL})
|
||||
set(geom_traits ${SEGMENT_GEOM_TRAITS})
|
||||
set(flags "-DTEST_NT=${nt} -DTEST_KERNEL=${kernel} -DTEST_GEOM_TRAITS=${geom_traits}")
|
||||
compile_and_run_with_flags( test_construction segments "${flags}")
|
||||
compile_and_run_with_flags(test_construction segments "${flags}")
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -655,7 +702,7 @@ function(test_construction_linear_curves)
|
|||
set(geom_traits ${LINEAR_GEOM_TRAITS})
|
||||
set(topol_traits ${PLANAR_UNBOUNDED_TOPOL_TRAITS})
|
||||
set(flags "-DTEST_NT=${nt} -DTEST_KERNEL=${kernel} -DTEST_GEOM_TRAITS=${geom_traits} -DTEST_TOPOL_TRAITS=${topol_traits}")
|
||||
compile_and_run_with_flags( test_construction linear "${flags}")
|
||||
compile_and_run_with_flags(test_construction linear "${flags}")
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -667,7 +714,7 @@ function(test_construction_spherical_arcs)
|
|||
set(geom_traits ${GEODESIC_ARC_ON_SPHERE_GEOM_TRAITS})
|
||||
set(topol_traits ${SPHERICAL_TOPOL_TRAITS})
|
||||
set(flags "-DTEST_NT=${nt} -DTEST_KERNEL=${kernel} -DTEST_GEOM_TRAITS=${geom_traits} -DTEST_TOPOL_TRAITS=${topol_traits}")
|
||||
compile_and_run_with_flags( test_construction geodesic_arcs_on_sphere "${flags}")
|
||||
compile_and_run_with_flags(test_construction geodesic_arcs_on_sphere "${flags}")
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -678,7 +725,7 @@ function(test_construction_polylines)
|
|||
set(kernel ${CARTESIAN_KERNEL})
|
||||
set(geom_traits ${POLYLINE_GEOM_TRAITS})
|
||||
set(flags "-DTEST_NT=${nt} -DTEST_KERNEL=${kernel} -DTEST_GEOM_TRAITS=${geom_traits}")
|
||||
compile_and_run_with_flags( test_construction polylines "${flags}")
|
||||
compile_and_run_with_flags(test_construction polylines "${flags}")
|
||||
endfunction()
|
||||
|
||||
|
||||
|
|
@ -837,14 +884,16 @@ function(test_segment_traits)
|
|||
|
||||
compile_test_with_flags(test_traits segments "${flags}")
|
||||
|
||||
execute_commands_old_structure( segments segment_traits
|
||||
VERTEX IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT CONSTRUCTOR
|
||||
COMPARE_Y_AT_X_RIGHT ARE_MERGEABLE)
|
||||
execute_commands_old_structure(segments segment_traits
|
||||
APPROXIMATE ARE_MERGEABLE COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
COMPARE_Y_AT_X_RIGHT CONSTRUCTOR IS_VERTICAL VERTEX)
|
||||
|
||||
execute_commands_new_structure( segments segment_traits
|
||||
IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT ARE_MERGEABLE)
|
||||
ARE_MERGEABLE
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
IS_VERTICAL)
|
||||
|
||||
run_trapped_test( test_traits
|
||||
run_trapped_test(test_traits
|
||||
data/segments/vertex.pt data/segments/xcurves
|
||||
data/empty.zero data/segments/vertex segment_traits)
|
||||
endfunction()
|
||||
|
|
@ -861,11 +910,13 @@ function(test_non_caching_segment_traits)
|
|||
compile_test_with_flags(test_traits non_caching_segments "${flags}")
|
||||
|
||||
execute_commands_old_structure(segments non_caching_segment_traits
|
||||
VERTEX IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT CONSTRUCTOR
|
||||
COMPARE_Y_AT_X_RIGHT ARE_MERGEABLE ASSERTIONS)
|
||||
APPROXIMATE ARE_MERGEABLE ASSERTIONS
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT CONSTRUCTOR COMPARE_Y_AT_X_RIGHT
|
||||
IS_VERTICAL VERTEX)
|
||||
|
||||
execute_commands_new_structure(segments segment_traits
|
||||
IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT)
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
IS_VERTICAL)
|
||||
|
||||
run_trapped_test(test_traits
|
||||
data/segments/vertex.pt data/segments/xcurves
|
||||
|
|
@ -894,23 +945,20 @@ function(test_polycurve_conic_traits)
|
|||
# Execute_command_new_structure will only run the test on functors provided as the third, fourth and so on arguments.
|
||||
# To see how the input data directory should be structured for each functor, check the execute_commands_new_structure function in this file.
|
||||
execute_commands_new_structure(polycurves_conics polycurve_conic_traits
|
||||
COMPARE_Y_AT_X
|
||||
INTERSECT
|
||||
EQUAL
|
||||
IS_VERTICAL
|
||||
SPLIT
|
||||
ARE_MERGEABLE
|
||||
COMPARE_Y_AT_X_LEFT
|
||||
COMPARE_Y_AT_X_RIGHT
|
||||
COMPARE_ENDPOINTS_XY COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT
|
||||
CONSTRUCT_OPPOSITE
|
||||
EQUAL
|
||||
INTERSECT
|
||||
IS_VERTICAL
|
||||
MAKE_X_MONOTONE
|
||||
MERGE
|
||||
NUMBER_OF_POINTS
|
||||
SPLIT
|
||||
PUSH_BACK
|
||||
PUSH_FRONT
|
||||
NUMBER_OF_POINTS
|
||||
VERTEX
|
||||
CONSTRUCT_OPPOSITE
|
||||
MERGE
|
||||
COMPARE_ENDPOINTS_XY
|
||||
TRIM)
|
||||
TRIM
|
||||
VERTEX)
|
||||
|
||||
endfunction()
|
||||
|
||||
|
|
@ -925,23 +973,21 @@ function(test_polycurve_circular_arc_traits)
|
|||
|
||||
compile_test_with_flags(test_traits circular_arc_polycurve "${flags}")
|
||||
|
||||
execute_commands_new_structure(polycurves_circular_arcs polycurve_circular_arc_traits
|
||||
COMPARE_Y_AT_X
|
||||
EQUAL
|
||||
IS_VERTICAL
|
||||
SPLIT
|
||||
execute_commands_new_structure(polycurves_circular_arcs
|
||||
polycurve_circular_arc_traits
|
||||
ARE_MERGEABLE
|
||||
COMPARE_Y_AT_X_LEFT
|
||||
COMPARE_Y_AT_X_RIGHT
|
||||
COMPARE_ENDPOINTS_XY COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT
|
||||
CONSTRUCT_OPPOSITE
|
||||
EQUAL
|
||||
INTERSECT
|
||||
IS_VERTICAL
|
||||
MAKE_X_MONOTONE
|
||||
MERGE
|
||||
NUMBER_OF_POINTS
|
||||
PUSH_BACK
|
||||
PUSH_FRONT
|
||||
NUMBER_OF_POINTS
|
||||
VERTEX
|
||||
CONSTRUCT_OPPOSITE
|
||||
MERGE
|
||||
COMPARE_ENDPOINTS_XY
|
||||
INTERSECT)
|
||||
SPLIT
|
||||
VERTEX)
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -960,15 +1006,15 @@ function(test_polycurve_bezier_traits)
|
|||
compile_test_with_flags(test_traits bezier_polycurve "${flags}")
|
||||
|
||||
execute_commands_new_structure(polycurves_bezier test_polycurve_bezier_traits
|
||||
MERGE
|
||||
ARE_MERGEABLE
|
||||
COMPARE_ENDPOINTS_XY
|
||||
EQUAL
|
||||
IS_VERTICAL
|
||||
NUMBER_OF_POINTS
|
||||
MERGE
|
||||
PUSH_BACK
|
||||
PUSH_FRONT
|
||||
VERTEX
|
||||
ARE_MERGEABLE
|
||||
COMPARE_ENDPOINTS_XY
|
||||
# TODO (add data for these tests)
|
||||
# COMPARE_Y_AT_X
|
||||
# SPLIT
|
||||
|
|
@ -993,8 +1039,8 @@ function(test_polyline_traits)
|
|||
compile_test_with_flags(test_traits test_polylines "${flags}")
|
||||
|
||||
execute_commands_old_structure(polylines polyline_traits
|
||||
CONSTRUCTOR COMPARE_Y_AT_X_LEFT
|
||||
COMPARE_Y_AT_X_RIGHT ARE_MERGEABLE)
|
||||
APPROXIMATE ARE_MERGEABLE
|
||||
COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT CONSTRUCTOR)
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -1009,8 +1055,8 @@ function(test_non_caching_polyline_traits)
|
|||
compile_test_with_flags(test_traits non_caching_polylines "${flags}")
|
||||
|
||||
execute_commands_old_structure(polylines non_caching_polyline_traits
|
||||
CONSTRUCTOR COMPARE_Y_AT_X_LEFT
|
||||
COMPARE_Y_AT_X_RIGHT ARE_MERGEABLE)
|
||||
APPROXIMATE ARE_MERGEABLE
|
||||
COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT CONSTRUCTOR)
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -1025,32 +1071,39 @@ function(test_linear_traits)
|
|||
compile_test_with_flags(test_traits linear "${flags}")
|
||||
|
||||
execute_commands_old_structure(linear/segments linear_traits.segments
|
||||
VERTEX IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
COMPARE_Y_AT_X_RIGHT CONSTRUCTOR ARE_MERGEABLE)
|
||||
APPROXIMATE ARE_MERGEABLE
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT CONSTRUCTOR
|
||||
IS_VERTICAL VERTEX)
|
||||
|
||||
execute_commands_new_structure(linear/segments linear_traits.segments
|
||||
IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT)
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
IS_VERTICAL)
|
||||
|
||||
run_trapped_test(test_traits
|
||||
data/linear/segments/vertex.pt data/linear/segments/xcurves
|
||||
data/empty.zero data/linear/segments/vertex linear_traits.segments)
|
||||
|
||||
execute_commands_old_structure(linear/rays linear_traits.rays
|
||||
VERTEX IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
COMPARE_Y_AT_X_RIGHT CONSTRUCTOR ARE_MERGEABLE)
|
||||
APPROXIMATE ARE_MERGEABLE
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT CONSTRUCTOR
|
||||
IS_VERTICAL VERTEX)
|
||||
|
||||
execute_commands_new_structure(linear/rays linear_traits.rays
|
||||
IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT)
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
IS_VERTICAL)
|
||||
|
||||
run_trapped_test(test_traits
|
||||
data/linear/rays/vertex.pt data/linear/rays/xcurves
|
||||
data/empty.zero data/linear/rays/vertex linear_traits.rays)
|
||||
|
||||
execute_commands_new_structure(linear/lines linear_traits.lines
|
||||
IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT INTERSECT
|
||||
SPLIT MERGE
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
COMPARE_X_ON_BOUNDARY COMPARE_X_NEAR_BOUNDARY COMPARE_Y_NEAR_BOUNDARY
|
||||
IS_VERTICAL
|
||||
INTERSECT
|
||||
MERGE
|
||||
PARAMETER_SPACE_X PARAMETER_SPACE_Y
|
||||
COMPARE_X_ON_BOUNDARY COMPARE_X_NEAR_BOUNDARY COMPARE_Y_NEAR_BOUNDARY)
|
||||
SPLIT)
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -1069,11 +1122,13 @@ function(test_conic_traits)
|
|||
compile_test_with_flags(test_traits conics "${flags}")
|
||||
|
||||
execute_commands_old_structure(conics conic_traits
|
||||
INTERSECT SPLIT MERGE COMPARE_Y_AT_X_LEFT
|
||||
COMPARE_Y_AT_X_RIGHT ARE_MERGEABLE)
|
||||
APPROXIMATE ARE_MERGEABLE COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT
|
||||
INTERSECT SPLIT MERGE)
|
||||
|
||||
execute_commands_new_structure(conics conic_traits
|
||||
INTERSECT SPLIT MERGE)
|
||||
INTERSECT
|
||||
MERGE
|
||||
SPLIT)
|
||||
|
||||
run_trapped_test(test_traits
|
||||
data/conics/compare.pt data/empty.zero
|
||||
|
|
@ -1092,11 +1147,13 @@ function(test_line_arc_traits)
|
|||
compile_test_with_flags(test_traits line_arcs "${flags}")
|
||||
|
||||
execute_commands_old_structure(circular_lines line_arc_traits
|
||||
VERTEX IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
ASSERTIONS COMPARE_Y_AT_X_RIGHT MERGE ARE_MERGEABLE)
|
||||
APPROXIMATE ARE_MERGEABLE ASSERTIONS
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT
|
||||
IS_VERTICAL MERGE VERTEX)
|
||||
|
||||
execute_commands_new_structure(circular_lines line_arc_traits
|
||||
IS_VERTICAL COMPARE_Y_AT_X)
|
||||
COMPARE_Y_AT_X
|
||||
IS_VERTICAL)
|
||||
|
||||
run_trapped_test(test_traits
|
||||
data/circular_lines/compare.pt data/empty.zero
|
||||
|
|
@ -1119,11 +1176,14 @@ function(test_circular_arc_traits)
|
|||
compile_test_with_flags(test_traits circular_arcs "${flags}")
|
||||
|
||||
execute_commands_old_structure(circular_arcs circular_arc_traits
|
||||
VERTEX IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
ASSERTIONS COMPARE_Y_AT_X_RIGHT MERGE ARE_MERGEABLE)
|
||||
APPROXIMATE ARE_MERGEABLE ASSERTIONS
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT
|
||||
IS_VERTICAL MERGE VERTEX)
|
||||
|
||||
execute_commands_new_structure(circular_arcs circular_arc_traits
|
||||
VERTEX IS_VERTICAL COMPARE_Y_AT_X)
|
||||
COMPARE_Y_AT_X
|
||||
IS_VERTICAL
|
||||
VERTEX)
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -1138,11 +1198,13 @@ function(test_circular_line_arc_traits)
|
|||
compile_test_with_flags(test_traits circular_line_arcs "${flags}")
|
||||
|
||||
execute_commands_old_structure(circular_line_arcs circular_line_arc_traits
|
||||
VERTEX IS_VERTICAL CONSTRUCTOR COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
ASSERTIONS COMPARE_Y_AT_X_RIGHT MERGE ARE_MERGEABLE)
|
||||
APPROXIMATE ARE_MERGEABLE ASSERTIONS
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT CONSTRUCTOR
|
||||
IS_VERTICAL MERGE VERTEX)
|
||||
|
||||
execute_commands_new_structure(circular_line_arcs circular_line_arc_traits
|
||||
IS_VERTICAL COMPARE_Y_AT_X)
|
||||
COMPARE_Y_AT_X
|
||||
IS_VERTICAL)
|
||||
|
||||
run_trapped_test(test_traits
|
||||
data/circular_line_arcs/vertex.pt data/circular_line_arcs/xcurves
|
||||
|
|
@ -1161,8 +1223,12 @@ function(test_circle_segments_traits)
|
|||
compile_test_with_flags(test_traits circle_segments "${flags}")
|
||||
|
||||
execute_commands_old_structure(circle_segments circle_segments_traits
|
||||
VERTEX IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
COMPARE_Y_AT_X_RIGHT CONSTRUCTOR ARE_MERGEABLE)
|
||||
APPROXIMATE ARE_MERGEABLE
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT CONSTRUCTOR
|
||||
IS_VERTICAL VERTEX)
|
||||
|
||||
execute_commands_new_structure(circle_segments circle_segments_traits
|
||||
APPROXIMATE)
|
||||
|
||||
run_trapped_test(test_traits
|
||||
data/circle_segments/points data/circle_segments/xcurves.8
|
||||
|
|
@ -1200,8 +1266,8 @@ function(test_bezier_traits)
|
|||
compile_test_with_flags(test_traits Bezier "${flags}")
|
||||
|
||||
execute_commands_old_structure(bezier bezier_traits
|
||||
COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT SPLIT
|
||||
CONSTRUCTOR ASSERTIONS ARE_MERGEABLE)
|
||||
APPROXIMATE ARE_MERGEABLE ASSERTIONS
|
||||
COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT CONSTRUCTOR SPLIT)
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -1217,14 +1283,14 @@ function(test_spherical_arc_traits)
|
|||
compile_test_with_flags(test_traits geodesic_arcs_on_sphere "${flags}")
|
||||
|
||||
execute_commands_old_structure(spherical_arcs spherical_arc_traits
|
||||
COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT INTERSECT
|
||||
CONSTRUCTOR
|
||||
COMPARE MAKE_X_MONOTONE SPLIT MERGE ASSERTIONS ARE_MERGEABLE)
|
||||
APPROXIMATE ARE_MERGEABLE ASSERTIONS
|
||||
COMPARE COMPARE_Y_AT_X_LEFT COMPARE_Y_AT_X_RIGHT INTERSECT CONSTRUCTOR
|
||||
MAKE_X_MONOTONE MERGE SPLIT)
|
||||
|
||||
execute_commands_new_structure(spherical_arcs spherical_arc_traits
|
||||
INTERSECT
|
||||
COMPARE_X_ON_BOUNDARY COMPARE_X_NEAR_BOUNDARY
|
||||
COMPARE_Y_NEAR_BOUNDARY)
|
||||
APPROXIMATE
|
||||
COMPARE_X_ON_BOUNDARY COMPARE_X_NEAR_BOUNDARY COMPARE_Y_NEAR_BOUNDARY
|
||||
INTERSECT)
|
||||
|
||||
run_trapped_test(test_traits
|
||||
data/spherical_arcs/compare.pt data/spherical_arcs/compare.xcv
|
||||
|
|
@ -1251,8 +1317,12 @@ function(test_rational_arc_traits)
|
|||
data/empty.zero data/compare rational_arc_traits)
|
||||
|
||||
execute_commands_new_structure(rational_arcs rational_arc_traits
|
||||
VERTEX IS_VERTICAL COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT SPLIT MERGE
|
||||
COMPARE_X_ON_BOUNDARY COMPARE_X_NEAR_BOUNDARY COMPARE_Y_NEAR_BOUNDARY)
|
||||
COMPARE_Y_AT_X COMPARE_Y_AT_X_LEFT
|
||||
COMPARE_X_ON_BOUNDARY COMPARE_X_NEAR_BOUNDARY COMPARE_Y_NEAR_BOUNDARY
|
||||
IS_VERTICAL
|
||||
MERGE
|
||||
SPLIT
|
||||
VERTEX)
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -1273,8 +1343,13 @@ function(test_algebraic_traits_gmp)
|
|||
|
||||
execute_commands_new_structure(algebraic algebraic_traits_gmp
|
||||
COMPARE COMPARE_Y_AT_X COMPARE_Y_AT_X_RIGHT COMPARE_Y_AT_X_LEFT
|
||||
MAKE_X_MONOTONE IS_VERTICAL VERTEX SPLIT MERGE INTERSECT
|
||||
PARAMETER_SPACE_X PARAMETER_SPACE_Y)
|
||||
IS_VERTICAL
|
||||
INTERSECT
|
||||
MAKE_X_MONOTONE
|
||||
MERGE
|
||||
PARAMETER_SPACE_X PARAMETER_SPACE_Y
|
||||
SPLIT
|
||||
VERTEX)
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
@ -1292,8 +1367,13 @@ function(test_algebraic_traits_leda)
|
|||
|
||||
execute_commands_new_structure(algebraic algebraic_traits_leda
|
||||
COMPARE COMPARE_Y_AT_X COMPARE_Y_AT_X_RIGHT COMPARE_Y_AT_X_LEFT
|
||||
MAKE_X_MONOTONE IS_VERTICAL VERTEX SPLIT MERGE INTERSECT
|
||||
PARAMETER_SPACE_X PARAMETER_SPACE_Y)
|
||||
IS_VERTICAL
|
||||
INTERSECT
|
||||
MAKE_X_MONOTONE
|
||||
MERGE
|
||||
PARAMETER_SPACE_X PARAMETER_SPACE_Y
|
||||
SPLIT
|
||||
VERTEX)
|
||||
endfunction()
|
||||
|
||||
|
||||
|
|
@ -1315,8 +1395,13 @@ function(test_algebraic_traits_core)
|
|||
|
||||
execute_commands_new_structure(algebraic algebraic_traits_core
|
||||
COMPARE COMPARE_Y_AT_X COMPARE_Y_AT_X_RIGHT COMPARE_Y_AT_X_LEFT
|
||||
MAKE_X_MONOTONE IS_VERTICAL VERTEX SPLIT MERGE INTERSECT
|
||||
PARAMETER_SPACE_X PARAMETER_SPACE_Y)
|
||||
IS_VERTICAL
|
||||
INTERSECT
|
||||
MAKE_X_MONOTONE
|
||||
MERGE
|
||||
PARAMETER_SPACE_X PARAMETER_SPACE_Y
|
||||
SPLIT
|
||||
VERTEX)
|
||||
endfunction()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
approximate 0 0.01 1 9
|
||||
|
|
@ -0,0 +1 @@
|
|||
x 0 0 1 1 1 1 1 0 1 0 1 1
|
||||
|
|
@ -0,0 +1 @@
|
|||
approximate 108 0.01 1 7
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
0 1 0 0 3/4 1/4 0
|
||||
0 3/4 1/4 0 1/2 1/2 0
|
||||
0 7/8 1/8 0 5/8 3/8 0
|
||||
# xz plane
|
||||
# xz plane 32
|
||||
0 0 0 -1 1/2 0 -1/2
|
||||
0 0 0 -1 1/4 0 -3/4
|
||||
0 1/4 0 -3/4 1/2 0 -1/2
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
0 0 0 -1 -1/4 0 -3/4
|
||||
0 -1/4 0 -3/4 -1/2 0 -1/2
|
||||
0 -1/8 0 -7/8 -1/8 0 -5/8
|
||||
# yz plane
|
||||
# yz plane 64
|
||||
0 0 0 -1 0 1/2 -1/2
|
||||
0 0 0 -1 0 1/4 -3/4
|
||||
0 0 1/4 -3/4 0 1/2 -1/2
|
||||
|
|
@ -97,18 +97,20 @@
|
|||
0 0 0 -1 0 -1/4 -3/4
|
||||
0 0 -1/4 -3/4 0 -1/2 -1/2
|
||||
0 0 -1/8 -7/8 0 -1/8 -5/8
|
||||
#
|
||||
# 96
|
||||
1 -1 0 0 1 0 0 0 1 1
|
||||
1 -1 0 0 1 0 0 0 -1 1
|
||||
1 1 0 0 -1 0 0 0 1 1
|
||||
1 1 0 0 -1 0 0 0 -1 1
|
||||
#
|
||||
# 100
|
||||
1 -1 0 0 1 0 0 0 -1 -1
|
||||
1 -1 0 0 1 0 0 0 1 -1
|
||||
1 1 0 0 -1 0 0 0 -1 -1
|
||||
1 1 0 0 -1 0 0 0 1 -1
|
||||
#
|
||||
# 104
|
||||
0 -1 0 0 0 -1 1
|
||||
0 -1 0 0 0 -1 -1
|
||||
0 -1 0 0 0 1 1
|
||||
0 -1 0 0 0 1 -1
|
||||
# 108
|
||||
0 -1 0 0 0 -1 0
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ aforementioned free functions is actually realized by a set overriding
|
|||
member function.
|
||||
|
||||
member functions of the `Polygon_set_2`
|
||||
(resp. `General_polygon_set_2`) that perform Boolean set-operations
|
||||
(respectively `General_polygon_set_2`) that perform Boolean set-operations
|
||||
come in two flavors: for example, `S.join(P, Q)` computes the union of
|
||||
\f$ P\f$ and \f$ Q\f$ and assigned the result to \f$ S\f$, while
|
||||
`S.join(P)` performs the operation \f$ S \longleftarrow S \cup P\f$.
|
||||
|
|
@ -579,8 +579,8 @@ template, as described above, an instance of the
|
|||
`Arr_polyline_traits_2` class template; see Section \ref
|
||||
arr_ssectr_polylines in the 2D Arrangements package.
|
||||
|
||||
<li>Each input linear polygon (resp. linear polygon with holes) is
|
||||
converted into a general polygon (resp. general polygon with holes)
|
||||
<li>Each input linear polygon (respectively linear polygon with holes) is
|
||||
converted into a general polygon (respectively general polygon with holes)
|
||||
bounded by \f$x\f$-monotone polylines. Then, the resulting generl
|
||||
polygons, which are also bounded by \f$x\f$-monotone polylines, are
|
||||
converted back to standard polygons.
|
||||
|
|
|
|||
|
|
@ -900,26 +900,26 @@ template <typename Polygon>
|
|||
bool do_intersect(const General_polygon_with_holes_2<Polygon>& pgn1,
|
||||
const General_polygon_with_holes_2<Polygon>& pgn2);
|
||||
|
||||
/*! Given a range of polygons or a range of polygons with holes (resp. a range
|
||||
/*! Given a range of polygons or a range of polygons with holes (respectively a range
|
||||
* of general polygons or a range of general polygons with holes) determines
|
||||
* whether the open polygons (resp. general polygons) in the range have a common
|
||||
* whether the open polygons (respectively general polygons) in the range have a common
|
||||
* point.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return `true` if the pairwise intersections of all open polygons or polygons
|
||||
* with holes (resp. general polygons or general polygons with holes) in
|
||||
* with holes (respectively general polygons or general polygons with holes) in
|
||||
* the range [*begin,*end) overlap, and `false` otherwise.
|
||||
*/
|
||||
template <typename InputIterator>
|
||||
bool do_intersect(InputIterator begin, InputIterator end);
|
||||
|
||||
/*! Given a range of polygons or a range of polygons with holes (resp. a range
|
||||
/*! Given a range of polygons or a range of polygons with holes (respectively a range
|
||||
* of general polygons or a range of general polygons with holes) determines
|
||||
* whether the open polygons (resp. general polygons) in the range have a common
|
||||
* whether the open polygons (respectively general polygons) in the range have a common
|
||||
* point.
|
||||
* \tparam UsePolylines determines whether the boundaries of the polygons in the
|
||||
* input range are treated as cyclic sequences of single
|
||||
|
|
@ -931,32 +931,32 @@ bool do_intersect(InputIterator begin, InputIterator end);
|
|||
* `pgn2` are used as is. Refer to \ref bso_ssectraits_sel for more
|
||||
* information.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return `true` if the pairwise intersections of all open polygons or polygons
|
||||
* with holes (resp. general polygons or general polygons with holes) in
|
||||
* with holes (respectively general polygons or general polygons with holes) in
|
||||
* the range [*begin,*end) overlap, and `false` otherwise.
|
||||
*/
|
||||
template <typename InputIterator, typename UsePolylines>
|
||||
bool do_intersect(InputIterator begin, InputIterator end,
|
||||
UsePolylines = Tag_true());
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of polygons
|
||||
* with holes (resp. general polygons with holes) determines whether the open
|
||||
* polygons (resp. general polygons) in the two ranges have a common point.
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of polygons
|
||||
* with holes (respectively general polygons with holes) determines whether the open
|
||||
* polygons (respectively general polygons) in the two ranges have a common point.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* \return `true` if the pairwise intersections of all open polygons (resp.
|
||||
* general polygons) and polygons with holes (resp. general polygons with
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return `true` if the pairwise intersections of all open polygons (respectively
|
||||
* general polygons) and polygons with holes (respectively general polygons with
|
||||
* holes) in the ranges [*begin1,*end1) and [*begin2,*end2),
|
||||
* respectively, overlap, and `false` otherwise.
|
||||
*/
|
||||
|
|
@ -964,9 +964,9 @@ template <typename InputIterator1, typename InputIterator2>
|
|||
bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
||||
InputIterator2 begin2, InputIterator2 end2);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of polygons
|
||||
* with holes (resp. general polygons with holes) determines whether the open
|
||||
* polygons (resp. general polygons) in the two ranges have a common point.
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of polygons
|
||||
* with holes (respectively general polygons with holes) determines whether the open
|
||||
* polygons (respectively general polygons) in the two ranges have a common point.
|
||||
* \tparam UsePolylines determines whether the boundaries of the polygons in the
|
||||
* input ranges are treated as cyclic sequences of single
|
||||
* (\f$x\f$-monotone) segments or as a cyclic sequences of
|
||||
|
|
@ -977,15 +977,15 @@ bool do_intersect(InputIterator1 begin1, InputIterator1 end1,
|
|||
* `pgn2` are used as is. Refer to \ref bso_ssectraits_sel for more
|
||||
* information.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* \return `true` if the pairwise intersections of all open polygons (resp.
|
||||
* general polygons) and polygons with holes (resp. general polygons with
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return `true` if the pairwise intersections of all open polygons (respectively
|
||||
* general polygons) and polygons with holes (respectively general polygons with
|
||||
* holes) in the ranges [*begin1,*end1) and [*begin2,*end2),
|
||||
* respectively, overlap, and `false` otherwise.
|
||||
*/
|
||||
|
|
@ -1112,19 +1112,19 @@ bool do_intersect(const General_polygon_with_holes_2<Polygon>& pgn1,
|
|||
const General_polygon_with_holes_2<Polygon>& pgn2,
|
||||
const GpsTraits& traits);
|
||||
|
||||
/*! Given a range of polygons or a range of polygons with holes (resp. a range
|
||||
/*! Given a range of polygons or a range of polygons with holes (respectively a range
|
||||
* of general polygons or a range of general polygons with holes) determines
|
||||
* whether the open polygons (resp. general polygons) in the range have a common
|
||||
* whether the open polygons (respectively general polygons) in the range have a common
|
||||
* point.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param traits a traits object.
|
||||
* \return `true` if the pairwise intersections of all open polygons or polygons
|
||||
* with holes (resp. general polygons or general polygons with holes) in
|
||||
* with holes (respectively general polygons or general polygons with holes) in
|
||||
* the range [*begin,*end) overlap, and `false` otherwise.
|
||||
* \pre `GpsTraits` must be a model of the concept `GeneralPolygonSetTraits_2`.
|
||||
*/
|
||||
|
|
@ -1132,20 +1132,20 @@ template <typename InputIterator, typename GpsTraits>
|
|||
bool do_intersect(InputIterator begin, InputIterator end,
|
||||
const GpsTraits& traits);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of polygons
|
||||
* with holes (resp. general polygons with holes) determines whether the open
|
||||
* polygons (resp. general polygons) in the two ranges have a common point.
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of polygons
|
||||
* with holes (respectively general polygons with holes) determines whether the open
|
||||
* polygons (respectively general polygons) in the two ranges have a common point.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param traits a traits object.
|
||||
* \return `true` if the pairwise intersections of all open polygons (resp.
|
||||
* general polygons) and polygons with holes (resp. general polygons with
|
||||
* \return `true` if the pairwise intersections of all open polygons (respectively
|
||||
* general polygons) and polygons with holes (respectively general polygons with
|
||||
* holes) in the ranges [*begin1,*end1) and [*begin2,*end2),
|
||||
* respectively, overlap, and `false` otherwise.
|
||||
*/
|
||||
|
|
@ -1471,30 +1471,30 @@ OutputIterator intersection(const General_polygon_with_holes_2<Polygon>& pgn1,
|
|||
OutputIterator oi);
|
||||
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) or a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) or a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* intersection of all polygons in the range and inserts the resulting polygons
|
||||
* with holes (resp. general polygons with holes) into a container via an output
|
||||
* with holes (respectively general polygons with holes) into a container via an output
|
||||
* iterator.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or `Polygon_with_holes_2`
|
||||
* (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or `Polygon_with_holes_2`
|
||||
* (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or `Polygon_with_holes_2`
|
||||
* (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or `Polygon_with_holes_2`
|
||||
* (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
*/
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
OutputIterator intersection(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) or a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) or a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* intersection of all polygons in the range and inserts the resulting polygons
|
||||
* with holes (resp. general polygons with holes) into a container via an output
|
||||
* with holes (respectively general polygons with holes) into a container via an output
|
||||
* iterator.
|
||||
* \tparam UsePolylines determines whether the boundaries of the polygons in the
|
||||
* input range are treated as cyclic sequences of single
|
||||
|
|
@ -1507,14 +1507,14 @@ OutputIterator intersection(InputIterator begin, InputIterator end,
|
|||
* with `CGAL::Tag_false`, `pgn1` and `pgn2` are used as is. Refer to
|
||||
* \ref bso_ssectraits_sel for more information.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
*/
|
||||
template <typename InputIterator, typename OutputIterator,
|
||||
|
|
@ -1523,22 +1523,22 @@ OutputIterator intersection(InputIterator begin, InputIterator end,
|
|||
OutputIterator oi,
|
||||
UsePolylines = Tag_true());
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* intersection of all polygons in the two ranges and inserts the resulting
|
||||
* polygons with holes (resp. general polygons with holes) into a container via
|
||||
* polygons with holes (respectively general polygons with holes) into a container via
|
||||
* an output iterator.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
*/
|
||||
template <typename InputIterator1, typename InputIterator2,
|
||||
|
|
@ -1547,10 +1547,10 @@ OutputIterator intersection(InputIterator1 begin1, InputIterator1 end1,
|
|||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* intersection of all polygons in the two ranges and inserts the resulting
|
||||
* polygons with holes (resp. general polygons with holes) into a container via
|
||||
* polygons with holes (respectively general polygons with holes) into a container via
|
||||
* an output iterator.
|
||||
* \tparam UsePolylines determines whether the boundaries of the polygons in the
|
||||
* input ranges are treated as cyclic sequences of single
|
||||
|
|
@ -1563,16 +1563,16 @@ OutputIterator intersection(InputIterator1 begin1, InputIterator1 end1,
|
|||
* with `CGAL::Tag_false`, `pgn1` and `pgn2` are used as is. Refer to
|
||||
* \ref bso_ssectraits_sel for more information.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
*/
|
||||
template <typename InputIterator1, typename InputIterator2,
|
||||
|
|
@ -1744,20 +1744,20 @@ intersection(const General_polygon_with_holes_2<Polygon>& pgn1,
|
|||
OutputIterator oi,
|
||||
const GpsTraits& traits);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) or a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) or a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* intersection of all polygons in the range and inserts the resulting
|
||||
* polygons with holes (resp. general polygons with holes) into a container via
|
||||
* polygons with holes (respectively general polygons with holes) into a container via
|
||||
* an output iterator.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param traits a traits object.
|
||||
* \return the past-the-end iterator of the output container.
|
||||
* \pre GpsTraits must be a model of `GeneralPolygonSetTraits_2`.
|
||||
|
|
@ -1767,22 +1767,22 @@ OutputIterator intersection(InputIterator begin, InputIterator end,
|
|||
OutputIterator oi,
|
||||
const GpsTraits& traits);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* intersection between all polygons in the two ranges and inserts the
|
||||
* resulting polygons with holes (resp. general polygons with holes) into a
|
||||
* resulting polygons with holes (respectively general polygons with holes) into a
|
||||
* container via an output iterator.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param traits a traits object.
|
||||
* \return the past-the-end iterator of the output container.
|
||||
* \pre GpsTraits must be a model of `GeneralPolygonSetTraits_2`.
|
||||
|
|
@ -2072,30 +2072,30 @@ bool join(const General_polygon_with_holes_2<Polygon>& pgn1,
|
|||
const General_polygon_with_holes_2<Polygon>& pgn2,
|
||||
General_polygon_with_holes_2<Polygon>& res);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) or a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) or a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* union of all polygons in the range and inserts the resulting polygons
|
||||
* with holes (resp. general polygons with holes) into a container via an output
|
||||
* with holes (respectively general polygons with holes) into a container via an output
|
||||
* iterator.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
*/
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
OutputIterator join(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) or a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) or a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* union of all polygons in the range and inserts the resulting polygons
|
||||
* with holes (resp. general polygons with holes) into a container via an output
|
||||
* with holes (respectively general polygons with holes) into a container via an output
|
||||
* iterator.
|
||||
* \tparam UsePolylines determines whether the boundaries of the polygons in the
|
||||
* input range are treated as cyclic sequences of single
|
||||
|
|
@ -2108,14 +2108,14 @@ OutputIterator join(InputIterator begin, InputIterator end,
|
|||
* with `CGAL::Tag_false`, `pgn1` and `pgn2` are used as is. Refer to
|
||||
* \ref bso_ssectraits_sel for more information.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
*/
|
||||
template <typename InputIterator, typename OutputIterator,
|
||||
|
|
@ -2124,22 +2124,22 @@ OutputIterator join(InputIterator begin, InputIterator end,
|
|||
OutputIterator oi,
|
||||
UsePolylines = Tag_true());
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* union of all polygons in the two ranges and inserts the resulting
|
||||
* polygons with holes (resp. general polygons with holes) into a container via
|
||||
* polygons with holes (respectively general polygons with holes) into a container via
|
||||
* an output iterator.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
*/
|
||||
template <typename InputIterator1, typename InputIterator2,
|
||||
|
|
@ -2276,20 +2276,20 @@ bool join(const General_polygon_with_holes_2<Polygon>& pgn1,
|
|||
General_polygon_with_holes_2<Polygon>& res,
|
||||
const GpsTraits& traits);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) or a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) or a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* union of all polygons in the range and inserts the resulting polygons
|
||||
* with holes (resp. general polygons with holes) into a container via an output
|
||||
* with holes (respectively general polygons with holes) into a container via an output
|
||||
* iterator.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param traits a traits object.
|
||||
* \return the past-the-end iterator of the output container.
|
||||
* \pre `GpsTraits` must be a model of the concept `GeneralPolygonSetTraits_2`.
|
||||
|
|
@ -2299,22 +2299,22 @@ OutputIterator join(InputIterator begin, InputIterator end,
|
|||
OutputIterator oi,
|
||||
const GpsTraits& traits);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* union of all polygons in the two ranges and inserts the resulting
|
||||
* polygons with holes (resp. general polygons with holes) into a container via
|
||||
* polygons with holes (respectively general polygons with holes) into a container via
|
||||
* an output iterator.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param traits a traits object.
|
||||
* \return the past-the-end iterator of the output container.
|
||||
* \pre `GpsTraits` must be a model of the concept `GeneralPolygonSetTraits_2`.
|
||||
|
|
@ -2326,10 +2326,10 @@ OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
|||
OutputIterator oi,
|
||||
const GpsTraits& traits);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* union of all polygons in the two ranges and inserts the resulting
|
||||
* polygons with holes (resp. general polygons with holes) into a container via
|
||||
* polygons with holes (respectively general polygons with holes) into a container via
|
||||
* an output iterator.
|
||||
* \tparam UsePolylines determines whether the boundaries of the polygons in the
|
||||
* input ranges are treated as cyclic sequences of single
|
||||
|
|
@ -2342,16 +2342,16 @@ OutputIterator join(InputIterator1 begin1, InputIterator1 end1,
|
|||
* with `CGAL::Tag_false`, `pgn1` and `pgn2` are used as is. Refer to
|
||||
* \ref bso_ssectraits_sel for more information.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
* \pre `GpsTraits` must be a model of the concept `GeneralPolygonSetTraits_2`.
|
||||
*/
|
||||
|
|
@ -3124,31 +3124,31 @@ symmetric_difference(const General_polygon_with_holes_2<Polygon>& pgn1,
|
|||
const General_polygon_with_holes_2<Polygon>& pgn2,
|
||||
OutputIterator oi);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) or a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) or a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* symmetric difference of all polygons in the range and inserts the resulting
|
||||
* polygons with holes (resp. general polygons with holes) into a container via
|
||||
* polygons with holes (respectively general polygons with holes) into a container via
|
||||
* an output iterator. A point is contained in the symmetric difference, if and
|
||||
* only if it is contained in an odd number of input polygons.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
*/
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
OutputIterator symmetric_difference(InputIterator begin, InputIterator end,
|
||||
OutputIterator oi);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) or a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) or a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* symmetric difference of all polygons in the range and inserts the resulting
|
||||
* polygons with holes (resp. general polygons with holes) into a container via
|
||||
* polygons with holes (respectively general polygons with holes) into a container via
|
||||
* an output iterator. A point is contained in the symmetric difference, if and
|
||||
* only if it is contained in an odd number of input polygons.
|
||||
* \tparam UsePolylines determines whether the boundaries of the polygons in the
|
||||
|
|
@ -3162,14 +3162,14 @@ OutputIterator symmetric_difference(InputIterator begin, InputIterator end,
|
|||
* with `CGAL::Tag_false`, `pgn1` and `pgn2` are used as is. Refer to
|
||||
* \ref bso_ssectraits_sel for more information.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
*/
|
||||
template <typename InputIterator, typename OutputIterator,
|
||||
|
|
@ -3178,24 +3178,24 @@ OutputIterator symmetric_difference(InputIterator begin, InputIterator end,
|
|||
OutputIterator oi,
|
||||
UsePolylines = Tag_true());
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* symmetric difference between all polygons in the two ranges and inserts the
|
||||
* resulting polygons with holes (resp. general polygons with holes) into a
|
||||
* resulting polygons with holes (respectively general polygons with holes) into a
|
||||
* container via an output iterator. A point is contained in the symmetric
|
||||
* difference, if and only if it is contained in an odd number of input
|
||||
* polygons.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
*/
|
||||
template <typename InputIterator1, typename InputIterator2,
|
||||
|
|
@ -3204,10 +3204,10 @@ OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
|||
InputIterator2 begin2, InputIterator2 end2,
|
||||
OutputIterator oi);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* symmetric difference between all polygons in the two ranges and inserts the
|
||||
* resulting polygons with holes (resp. general polygons with holes) into a
|
||||
* resulting polygons with holes (respectively general polygons with holes) into a
|
||||
* container via an output iterator. A point is contained in the symmetric
|
||||
* difference, if and only if it is contained in an odd number of input
|
||||
* polygons.
|
||||
|
|
@ -3222,16 +3222,16 @@ OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
|||
* with `CGAL::Tag_false`, `pgn1` and `pgn2` are used as is. Refer to
|
||||
* \ref bso_ssectraits_sel for more information.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \return the past-the-end iterator of the output container.
|
||||
*/
|
||||
template <typename InputIterator1, typename InputIterator2,
|
||||
|
|
@ -3404,21 +3404,21 @@ symmetric_difference(const General_polygon_with_holes_2<Polygon>& pgn1,
|
|||
OutputIterator oi,
|
||||
const GpsTraits& traits);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) or a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) or a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* symmetric difference of all polygons in the range and inserts the resulting
|
||||
* polygons with holes (resp. general polygons with holes) into a container via
|
||||
* polygons with holes (respectively general polygons with holes) into a container via
|
||||
* an output iterator. A point is contained in the symmetric difference, if and
|
||||
* only if it is contained in an odd number of input polygons.
|
||||
* \param begin the first iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end the past-the-end iterator of the input range. Its value type is
|
||||
* either `Polygon_2` (resp. `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* either `Polygon_2` (respectively `General_polygon_2`) or
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param traits a traits object.
|
||||
* \return the past-the-end iterator of the output container.
|
||||
* \pre GpsTraits must be a model of `GeneralPolygonSetTraits_2`.
|
||||
|
|
@ -3428,24 +3428,24 @@ OutputIterator symmetric_difference(InputIterator begin, InputIterator end,
|
|||
OutputIterator oi,
|
||||
const GpsTraits& traits);
|
||||
|
||||
/*! Given a range of polygons (resp. general polygons) and a range of
|
||||
* polygons with holes (resp. general polygons with holes) computes the
|
||||
/*! Given a range of polygons (respectively general polygons) and a range of
|
||||
* polygons with holes (respectively general polygons with holes) computes the
|
||||
* symmetric difference between all polygons in the two ranges and inserts the
|
||||
* resulting polygons with holes (resp. general polygons with holes) into a
|
||||
* resulting polygons with holes (respectively general polygons with holes) into a
|
||||
* container via an output iterator. A point is contained in the symmetric
|
||||
* difference, if and only if it is contained in an odd number of input
|
||||
* polygons.
|
||||
* \param begin1 the first iterator of the 1st input range. Its value type is
|
||||
* `Polygon_2` (resp. `General_polygon_2`).
|
||||
* `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param end1 the past-the-end iterator of the 1st input range. Its value
|
||||
* type is `Polygon_2` (resp. `General_polygon_2`).
|
||||
* type is `Polygon_2` (respectively `General_polygon_2`).
|
||||
* \param begin2 the first iterator of the 2nd input range. Its value type
|
||||
* is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param end2 the past-the-end iterator of the 2nd input range. Its value
|
||||
* type is `Polygon_with_holes_2` (resp. `General_polygon_with_holes_2`).
|
||||
* type is `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param oi the output iterator for the result.
|
||||
* Its dereference type must be convertible to
|
||||
* `Polygon_with_holes_2` (resp. `General_polygons_with_holes_2`).
|
||||
* `Polygon_with_holes_2` (respectively `General_polygon_with_holes_2`).
|
||||
* \param traits a traits object.
|
||||
* \return the past-the-end iterator of the output container.
|
||||
* \pre GpsTraits must be a model of `GeneralPolygonSetTraits_2`.
|
||||
|
|
@ -3460,4 +3460,3 @@ OutputIterator symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
|
|||
/// @}
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
\cgalPkgSince{3.1}
|
||||
\cgalPkgBib{cgal:kmz-isiobd}
|
||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||
\cgalPkgDemo{Polyhedron demo,polyhedron_3.zip}
|
||||
\cgalPkgDemo{CGAL Lab,CGALlab.zip}
|
||||
\cgalPkgShortInfoEnd
|
||||
\cgalPkgDescriptionEnd
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
\cgalPkgSince{3.5}
|
||||
\cgalPkgBib{cgal:h-emspe}
|
||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||
\cgalPkgDemo{Polyhedron demo,polyhedron_3.zip}
|
||||
\cgalPkgDemo{CGAL Lab,CGALlab.zip}
|
||||
\cgalPkgShortInfoEnd
|
||||
\cgalPkgDescriptionEnd
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ degenerate hull may also be possible.
|
|||
\cgalPkgDependsOn{The dynamic algorithms depend on \ref PkgTriangulation3 "3D Triangulations".}
|
||||
\cgalPkgBib{cgal:hs-ch3}
|
||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||
\cgalPkgDemo{Polyhedron demo,polyhedron_3.zip}
|
||||
\cgalPkgDemo{CGAL Lab,CGALlab.zip}
|
||||
\cgalPkgShortInfoEnd
|
||||
\cgalPkgDescriptionEnd
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -288,7 +288,7 @@ MainWindow::MainWindow()
|
|||
// Setup input handlers. They get events before the scene gets them
|
||||
// and the input they generate is passed to the triangulation with
|
||||
// the signal/slot mechanism
|
||||
pi = new CGAL::Qt::GraphicsViewPolylineInput<K>(this, &scene, 0, true); // inputs polylines which are not closed
|
||||
pi = new CGAL::Qt::GraphicsViewPolylineInput<K>(this, &scene, 0, true); // inputs polylines which are closed
|
||||
QObject::connect(pi, SIGNAL(generate(CGAL::Object)),
|
||||
this, SLOT(processInput(CGAL::Object)));
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ source vertices.}
|
|||
\cgalPkgDependsOn{ \ref PkgSolverInterface}
|
||||
\cgalPkgBib{cgal:cvf-hm3}
|
||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||
\cgalPkgDemo{Polyhedron demo,polyhedron_3.zip}
|
||||
\cgalPkgDemo{CGAL Lab,CGALlab.zip}
|
||||
\cgalPkgShortInfoEnd
|
||||
|
||||
\cgalPkgDescriptionEnd
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Release History
|
|||
[Release 6.0](https://github.com/CGAL/cgal/releases/tag/v6.0)
|
||||
-----------
|
||||
|
||||
Release date: October 2023
|
||||
Release date: June 2024
|
||||
|
||||
### General Changes
|
||||
|
||||
|
|
@ -17,6 +17,7 @@ Release date: October 2023
|
|||
- **Breaking change**: The usage of `boost::variant` has been replaced by `std::variant`. Packages affected are 2D Arrangements, and the Kernel intersection.
|
||||
- **Breaking change**: The file CMake file `UseCGAL.cmake` has been removed from CGAL. Usages of the CMake variables `${CGAL_USE_FILE}` and `${CGAL_LIBRARIES}` must be replaced by a link to the imported target `CGAL::CGAL`, for example: `target_link_library(the_target PRIVATE CGAL::CGAL)`.
|
||||
- The minimal supported version of Boost is now 1.72.0
|
||||
- The CGAL demo formerly known as "Polyhedron demo" has been renamed "CGAL Lab".
|
||||
|
||||
### Installation
|
||||
|
||||
|
|
@ -75,8 +76,17 @@ Release date: October 2023
|
|||
bounding box to a face graph.
|
||||
|
||||
### [2D Arrangements](https://doc.cgal.org/6.0/Manual/packages.html#PkgArrangementOnSurface2)
|
||||
- Fixed a bug in the zone construction code applied to arrangements of geodesic arcs on a sphere,
|
||||
when inserting an arc that lies on the identification curve.
|
||||
- **Breaking change**: The type of the result of point location queries changed to
|
||||
`std::variant`. The support for the old macro `CGAL_ARR_POINT_LOCATION_VERSION`
|
||||
has been removed.
|
||||
|
||||
- Eliminated the error-prone c-type casting that was used to define observers. In general, backward compatibility was maintained; however, the former class template `Arr_observer` was replaced by an alias template. (The former class Arr_observer was renamed to Aos_observer).
|
||||
|
||||
- Introduced `Arr_dcel`, which essentially replaces the former `Arr_default_dcel`. Backward compatibility was maintained by the introduction of the alias template `Arr_default_dcel`. `Arr_dcel`, as opposed to the former `Arr_default_dcel` is templated (in addition to the geometry traits) by Vertex, Halfedge, and Face template parameters, and they have default type values. All this enables the layered extension of DCEL records.
|
||||
|
||||
- Fixed a bug in the zone construction code applied to arrangements of geodesic arcs on a sphere, when inserting an arc that lies on the identification curve.
|
||||
|
||||
- Introduced a new interactive program that demonstrates 2D arrangements embedded on the sphere called `earth`. The program (i) reads a database of all administrative boundaries of the countries in the world, (ii) displays the globe with all countries and land covered by water (which is land not covered by countries) on a window, and (ii) enables interaction with the user.
|
||||
|
||||
### [Tetrahedral Remeshing](https://doc.cgal.org/6.0/Manual/packages.html#PkgTetrahedralRemeshing)
|
||||
- **Breaking change**: The template parameters of
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
\cgalPkgDependsOn{\ref PkgSolverInterface and \ref thirdpartyEigen}
|
||||
\cgalPkgBib{cgal:pc-eldp}
|
||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||
\cgalPkgDemo{Polyhedron demo,polyhedron_3.zip}
|
||||
\cgalPkgDemo{CGAL Lab,CGALlab.zip}
|
||||
\cgalPkgShortInfoEnd
|
||||
\cgalPkgDescriptionEnd
|
||||
|
||||
|
|
|
|||
|
|
@ -45,16 +45,16 @@ therefore do not appear in the constructors.
|
|||
\cgalHeading{Example}
|
||||
|
||||
\code
|
||||
typedef Cartesian<double> K;
|
||||
typedef Aff_transformation_2<K> Transformation;
|
||||
typedef Point_2<K> Point;
|
||||
typedef Vector_2<K> Vector;
|
||||
typedef Direction_2<K> Direction;
|
||||
typedef CGAL::Simple_cartesian<double> K;
|
||||
typedef CGAL::Aff_transformation_2<K> Transformation;
|
||||
typedef CGAL::Point_2<K> Point;
|
||||
typedef CGAL::Vector_2<K> Vector;
|
||||
typedef CGAL::Direction_2<K> Direction;
|
||||
|
||||
Transformation rotate(ROTATION, sin(pi), cos(pi));
|
||||
Transformation rational_rotate(ROTATION,Direction(1,1), 1, 100);
|
||||
Transformation translate(TRANSLATION, Vector(-2, 0));
|
||||
Transformation scale(SCALING, 3);
|
||||
Transformation rotate(CGAL::ROTATION, sin(pi), cos(pi));
|
||||
Transformation rational_rotate(CGAL::ROTATION,Direction(1,1), 1, 100);
|
||||
Transformation translate(CGAL::TRANSLATION, Vector(-2, 0));
|
||||
Transformation scale(CGAL::SCALING, 3);
|
||||
|
||||
Point q(0, 1);
|
||||
q = rational_rotate(q);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "Plugins/Mesh_3/config_mesh_3.h"
|
||||
// as otherwise it gets set via inclusion of cgallab.h
|
||||
// as otherwise it gets set via inclusion of CGALlab.h
|
||||
#include <CGAL/Default.h>
|
||||
|
||||
#include "SMesh_type.h"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "cgallab.h"
|
||||
#include "CGALlab.h"
|
||||
#include "MainWindow.h"
|
||||
#include <QMessageBox>
|
||||
#include <CGAL/Qt/resources.h>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "cgallab.h"
|
||||
#include "CGALlab.h"
|
||||
|
||||
/*!
|
||||
* \brief defines the entry point of the demo.
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#include "cgallab_config.h"
|
||||
#include "CGALlab_config.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QScopedPointer>
|
||||
|
|
@ -44,8 +44,8 @@ include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake)
|
|||
endif()
|
||||
# Link with CGAL
|
||||
target_link_libraries( ${plugin_name} PUBLIC CGAL::CGAL )
|
||||
if(NOT CGAL_TEST_SUITE AND TARGET Polyhedron_3)
|
||||
add_dependencies( ${plugin_name} Polyhedron_3 )
|
||||
if(NOT CGAL_TEST_SUITE AND TARGET CGALlab)
|
||||
add_dependencies( ${plugin_name} CGALlab )
|
||||
endif()
|
||||
if(NOT TARGET CGALlab_all_plugins)
|
||||
add_custom_target(CGALlab_all_plugins)
|
||||
|
|
@ -127,9 +127,9 @@ if(CGAL_Qt6_FOUND AND Qt6_FOUND)
|
|||
qt6_generate_moc("File_loader_dialog.h"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/File_loader_dialog_moc.cpp")
|
||||
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cgallab_macros.cmake)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/CGALlab_macros.cmake)
|
||||
|
||||
qt6_add_resources(CGAL_Qt6_RESOURCE_FILES cgallab.qrc)
|
||||
qt6_add_resources(CGAL_Qt6_RESOURCE_FILES CGALlab.qrc)
|
||||
find_path(
|
||||
CGAL_THREE_HEADERS_PATH
|
||||
NAMES CGAL/Three/Scene_item.h
|
||||
|
|
@ -184,7 +184,7 @@ if(CGAL_Qt6_FOUND AND Qt6_FOUND)
|
|||
Scene_item_rendering_helper.cpp
|
||||
Scene_item_rendering_helper_moc.cpp
|
||||
Primitive_container.cpp
|
||||
cgallab_plugin_helper.cpp
|
||||
CGALlab_plugin_helper.cpp
|
||||
CGAL_double_edit.cpp)
|
||||
target_link_libraries(demo_framework PUBLIC Qt6::OpenGLWidgets Qt6::Widgets Qt6::Gui Qt6::Qml
|
||||
CGAL::CGAL_Qt6)
|
||||
|
|
@ -373,17 +373,17 @@ if(CGAL_Qt6_FOUND AND Qt6_FOUND)
|
|||
target_link_libraries(cgal_lab PRIVATE Qt6::WebSockets)
|
||||
endif()
|
||||
cgal_add_compilation_test(cgal_lab)
|
||||
add_executable(cgallab cgallab.cpp)
|
||||
target_link_libraries(cgallab PRIVATE cgal_lab)
|
||||
add_to_cached_list(CGAL_EXECUTABLE_TARGETS cgallab)
|
||||
cgal_add_compilation_test(cgallab)
|
||||
add_executable(CGALlab CGALlab.cpp)
|
||||
target_link_libraries(CGALlab PRIVATE cgal_lab)
|
||||
add_to_cached_list(CGAL_EXECUTABLE_TARGETS CGALlab)
|
||||
cgal_add_compilation_test(CGALlab)
|
||||
|
||||
target_link_libraries(cgallab PRIVATE demo_framework)
|
||||
target_link_libraries(CGALlab PRIVATE demo_framework)
|
||||
|
||||
# Link with CGAL
|
||||
target_link_libraries(cgallab PUBLIC CGAL::CGAL_Qt6)
|
||||
target_link_libraries(CGALlab PUBLIC CGAL::CGAL_Qt6)
|
||||
|
||||
add_to_cached_list(CGAL_EXECUTABLE_TARGETS cgallab)
|
||||
add_to_cached_list(CGAL_EXECUTABLE_TARGETS CGALlab)
|
||||
|
||||
###########
|
||||
# PLUGINS #
|
||||
|
|
@ -452,8 +452,8 @@ if(CGAL_Qt6_FOUND AND Qt6_FOUND)
|
|||
NAMESPACE Lab_ APPEND
|
||||
FILE cgal_lab_targets.cmake)
|
||||
|
||||
configure_file(cgallabConfig.cmake.in
|
||||
cgallabConfig.cmake)
|
||||
configure_file(CGALlabConfig.cmake.in
|
||||
CGALlabConfig.cmake)
|
||||
#TO DO script the activation of all the plugins.
|
||||
|
||||
else(CGAL_Qt6_FOUND AND Qt6_FOUND)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "cgallab.h"
|
||||
#include "CGALlab.h"
|
||||
#include <clocale>
|
||||
#include <CGAL/Qt/resources.h>
|
||||
#include <QSurfaceFormat>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
<string>CGAL Three</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="cgallab.qrc">
|
||||
<iconset resource="CGALlab.qrc">
|
||||
<normaloff>:/cgal/icons/resources/cgal_logo.xpm</normaloff>:/cgal/icons/resources/cgal_logo.xpm</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
|
|
@ -132,7 +132,7 @@
|
|||
<string>+</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="cgallab.qrc">
|
||||
<iconset resource="CGALlab.qrc">
|
||||
<normaloff>:/cgal/icons/plus</normaloff>:/cgal/icons/plus</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
<string>-</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="cgallab.qrc">
|
||||
<iconset resource="CGALlab.qrc">
|
||||
<normaloff>:/cgal/icons/minus</normaloff>:/cgal/icons/minus</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -154,7 +154,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="cgallab.qrc">
|
||||
<iconset resource="CGALlab.qrc">
|
||||
<normaloff>:/cgal/icons/duplicate</normaloff>:/cgal/icons/duplicate</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -165,7 +165,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="cgallab.qrc">
|
||||
<iconset resource="CGALlab.qrc">
|
||||
<normaloff>:/cgal/icons/resources/up.png</normaloff>:/cgal/icons/resources/up.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -176,7 +176,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="cgallab.qrc">
|
||||
<iconset resource="CGALlab.qrc">
|
||||
<normaloff>:/cgal/icons/resources/down.png</normaloff>:/cgal/icons/resources/down.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -344,7 +344,7 @@
|
|||
</action>
|
||||
<action name="actionLoad">
|
||||
<property name="icon">
|
||||
<iconset resource="cgallab.qrc">
|
||||
<iconset resource="CGALlab.qrc">
|
||||
<normaloff>:/cgal/icons/plus</normaloff>:/cgal/icons/plus</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
|
@ -356,7 +356,7 @@
|
|||
</action>
|
||||
<action name="actionErase">
|
||||
<property name="icon">
|
||||
<iconset resource="cgallab.qrc">
|
||||
<iconset resource="CGALlab.qrc">
|
||||
<normaloff>:/cgal/icons/minus</normaloff>:/cgal/icons/minus</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
|
@ -368,7 +368,7 @@
|
|||
</action>
|
||||
<action name="actionDuplicate">
|
||||
<property name="icon">
|
||||
<iconset resource="cgallab.qrc">
|
||||
<iconset resource="CGALlab.qrc">
|
||||
<normaloff>:/cgal/icons/duplicate</normaloff>:/cgal/icons/duplicate</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
|
@ -471,8 +471,8 @@
|
|||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="cgallab.qrc"/>
|
||||
<include location="cgallab.qrc"/>
|
||||
<include location="CGALlab.qrc"/>
|
||||
<include location="CGALlab.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "cgallab.h"
|
||||
#include "CGALlab.h"
|
||||
#include <clocale>
|
||||
#include <CGAL/Qt/resources.h>
|
||||
#include <QSurfaceFormat>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "cgallab.h"
|
||||
#include "CGALlab.h"
|
||||
#include <clocale>
|
||||
#include <CGAL/Qt/resources.h>
|
||||
#include <QSurfaceFormat>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue