diff --git a/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h b/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h index 5422c84b2ae..021cdc6270a 100644 --- a/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h +++ b/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h @@ -21,7 +21,6 @@ #include #include #include -#include namespace CGAL { @@ -57,9 +56,9 @@ template < class FaceGraph, class CacheDatum=Tag_false > class AABB_face_graph_triangle_primitive #ifndef DOXYGEN_RUNNING - : public AABB_primitive::face_descriptor, - std::pair::face_descriptor, const FaceGraph*> >::type, + : public AABB_primitive::face_descriptor, + std::pair::face_descriptor, const FaceGraph*> >, Triangle_from_face_descriptor_map< FaceGraph, typename Default::Get::const_type >::type VertexPointPMap_; typedef typename boost::graph_traits::face_descriptor FD; - typedef typename boost::mpl::if_ >::type Id_; + typedef std::conditional_t > Id_; typedef Triangle_from_face_descriptor_map Triangle_property_map; typedef One_point_from_face_descriptor_map Point_property_map; diff --git a/AABB_tree/include/CGAL/AABB_halfedge_graph_segment_primitive.h b/AABB_tree/include/CGAL/AABB_halfedge_graph_segment_primitive.h index 13568227319..3f5481d0cfe 100644 --- a/AABB_tree/include/CGAL/AABB_halfedge_graph_segment_primitive.h +++ b/AABB_tree/include/CGAL/AABB_halfedge_graph_segment_primitive.h @@ -24,7 +24,6 @@ #include #include #include -#include #include @@ -70,9 +69,9 @@ template < class HalfedgeGraph, class CacheDatum = Tag_false > class AABB_halfedge_graph_segment_primitive #ifndef DOXYGEN_RUNNING - : public AABB_primitive< typename boost::mpl::if_::edge_descriptor, - std::pair::edge_descriptor, const HalfedgeGraph*> >::type, + : public AABB_primitive< std::conditional_t::edge_descriptor, + std::pair::edge_descriptor, const HalfedgeGraph*> >, Segment_from_edge_descriptor_map< HalfedgeGraph, typename Default::Get::const_type >::type VertexPointPMap_; typedef typename boost::graph_traits::edge_descriptor ED; - typedef typename boost::mpl::if_ >::type Id_; + typedef std::conditional_t > Id_; typedef Segment_from_edge_descriptor_map Segment_property_map; typedef Source_point_from_edge_descriptor_map Point_property_map; diff --git a/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h b/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h index e662b13be90..3d02204b9d0 100644 --- a/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h +++ b/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h @@ -32,11 +32,11 @@ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_cartesian_const_iterator_3,Cartesian_const template struct Is_ray_intersection_geomtraits -: boost::mpl::and_< Has_ray_3, - Has_construct_source_3, - Has_vector_3, - Has_construct_cartesian_const_iterator_3, - Has_cartesian_const_iterator_3 >::type +: std::bool_constant< Has_ray_3::value && + Has_construct_source_3::value && + Has_vector_3::value && + Has_construct_cartesian_const_iterator_3::value && + Has_cartesian_const_iterator_3::value > {}; diff --git a/Algebraic_foundations/include/CGAL/number_utils.h b/Algebraic_foundations/include/CGAL/number_utils.h index c17823d72b9..5a5bc2d242d 100644 --- a/Algebraic_foundations/include/CGAL/number_utils.h +++ b/Algebraic_foundations/include/CGAL/number_utils.h @@ -194,21 +194,21 @@ root_of( int k, Input_iterator begin, Input_iterator end ) { template< class Number_type > inline // select a Is_zero functor -typename boost::mpl::if_c< - ::std::is_same< typename Algebraic_structure_traits< Number_type >::Is_zero, - Null_functor >::value , +typename std::conditional_t< + std::is_same_v< typename Algebraic_structure_traits< Number_type >::Is_zero, + Null_functor >, typename Real_embeddable_traits< Number_type >::Is_zero, typename Algebraic_structure_traits< Number_type >::Is_zero ->::type::result_type +>::result_type is_zero( const Number_type& x ) { // We take the Algebraic_structure_traits<>::Is_zero functor by default. If it // is not available, we take the Real_embeddable_traits functor - typename ::boost::mpl::if_c< - ::std::is_same< + std::conditional_t< + std::is_same_v< typename Algebraic_structure_traits< Number_type >::Is_zero, - Null_functor >::value , + Null_functor > , typename Real_embeddable_traits< Number_type >::Is_zero, - typename Algebraic_structure_traits< Number_type >::Is_zero >::type + typename Algebraic_structure_traits< Number_type >::Is_zero > is_zero; return is_zero( x ); } diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/CMakeLists.txt b/Alpha_wrap_3/benchmark/Alpha_wrap_3/CMakeLists.txt new file mode 100644 index 00000000000..a9aa0d1d63c --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/CMakeLists.txt @@ -0,0 +1,15 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + +cmake_minimum_required(VERSION 3.1...3.20) +project(Alpha_wrap_3_Benchmark) + +find_package(CGAL REQUIRED) + +include_directories (BEFORE ../../include ./Quality ./Robustness) # AW3 includes +include_directories (BEFORE ../../../CGAL-Patches/include) + +# create a target per cppfile +create_single_source_cgal_program("Performance/performance_benchmark.cpp") +create_single_source_cgal_program("Quality/quality_benchmark.cpp") +create_single_source_cgal_program("Robustness/robustness_benchmark.cpp") diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/compute_performance_benchmark_data.py b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/compute_performance_benchmark_data.py new file mode 100644 index 00000000000..86c57d35146 --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/compute_performance_benchmark_data.py @@ -0,0 +1,61 @@ +# Copyright (c) 2019-2023 Google LLC (USA). +# All rights reserved. +# +# This file is part of CGAL (www.cgal.org). +# +# $URL$ +# $Id$ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +# Author(s) : Pierre Alliez +# Michael Hemmer +# Cedric Portaneri +# +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, getopt + +def compute_performance_benchmark_data(execname, filename, alpha): + + output = "" + cmd = ("/usr/bin/time", "-v", + execname, "-i", + filename, "-a", alpha) + proc = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + start_new_session=True) + + outs, errs = proc.communicate() + output = outs.decode("utf-8") + errs.decode("utf-8") + + for output_line in output.split("\n"): + if "User time (seconds): " in output_line: + print(output_line[len("User time (seconds): "):]) + continue + if "Maximum resident set size (kbytes): " in output_line: + print(output_line[len("Maximum resident set size (kbytes): "):]) + continue + +def main(argv): + execname="" + filename="" + alpha="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'e:i:a:') + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "-e": + execname = arg + elif opt == "-i": + filename = arg + elif opt == "-a": + alpha = arg + + compute_performance_benchmark_data(execname, filename, alpha) + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/generate_performance_benchmark_charts.py b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/generate_performance_benchmark_charts.py new file mode 100644 index 00000000000..445b6923277 --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/generate_performance_benchmark_charts.py @@ -0,0 +1,156 @@ +# Copyright (c) 2019-2023 Google LLC (USA). +# All rights reserved. +# +# This file is part of CGAL (www.cgal.org). +# +# $URL$ +# $Id$ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +# Author(s) : Pierre Alliez +# Michael Hemmer +# Cedric Portaneri +# +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, signal, getopt +import numpy as np +import matplotlib.pyplot as plt + +def main(argv): + + inputdir="" + outputdir="" + commit_hash="" + alpha="" + do_diff=False + diffdir="" + diff_hash="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'i:a:o:c:d:p:') + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "-i": + inputdir = arg + elif opt == "-a": + alpha = arg + elif opt == "-o": + outputdir = arg + elif opt == "-c": + commit_hash = arg + elif opt == "-d": + diff_hash = arg + do_diff = True + elif opt == "-p": + diffdir = arg + + all_metric = { + "Time_(second)" : {}, + "Memory_Peak_(kbytes)" : {}} + num_input = 0 + for filename in os.listdir(inputdir) : + new_path = os.path.join(inputdir,filename) + new_file = open(new_path) + is_empty_new = os.path.getsize(new_path) <= 1 + if do_diff : + old_path = os.path.join(diffdir,filename) + old_file = open(old_path) + is_empty_old = os.path.getsize(old_path) <= 1 + for key in all_metric: + if is_empty_new or is_empty_old : + new_val = 0. + old_val = 0. + else : + new_val = float(new_file.readline().rstrip('\n')) + old_val = float(old_file.readline().rstrip('\n')) + mesh_id = str(filename.split('.')[0]) + all_metric[key][mesh_id] = [new_val, old_val] + else : + for key in all_metric: + if is_empty_new : + new_val = 0. + else : + new_val = float(new_file.readline().rstrip('\n')) + mesh_id = str(filename.split('.')[0]) + all_metric[key][mesh_id] = [new_val, new_val] + num_input = num_input+1 + + # update .pdf chart + date_now = datetime.datetime.now() + date_for_filename = str(date_now.year) +"_"+ str(date_now.month) +"_"+ str(date_now.day) +"_"+ str(date_now.hour) +"h"+ str(date_now.minute) +"mn" + for key in all_metric: + goal = 0 + num_el = range(len(all_metric[key])) + avg_diff_to_goal = 0. + avg = 0. + x1 = [] + x2 = [] + for value in all_metric[key].values() : + avg += value[0] + diff_to_goal = abs(value[1]-goal) - abs(value[0]-goal) + avg_diff_to_goal += diff_to_goal + x1.append(value[0]) + x2.append(value[1]) + avg_diff_to_goal /= float(len(all_metric[key])) + avg /= float(len(all_metric[key])) + + plt.figure(figsize=(8,8)) + if do_diff : + plt.hist(x2, bins=100, color='tab:green', alpha=0.5) + plt.hist(x1, bins=100, color='tab:blue', alpha=0.5) + plt.vlines(x = goal, ymin=plt.ylim()[0], ymax=plt.ylim()[1], linestyles='dashed') + + title = "" + if do_diff : + title += "Diff between " + commit_hash + " and " + diff_hash + " on " + str(num_input) + " meshes from Thingi10K\nAlpha = Bbox diag length / " + alpha + else : + title += "Benchmarking on " + str(num_input) + " meshes from Thingi10K\nAlpha = Bbox diag length / " + alpha + + avg_str = str(format(abs(avg), '.2f')) + if key == "Time_(second)" : + title += "\nIn average we spend " + avg_str + " seconds" + else : + title += "\nIn average we use up to " + avg_str + " kbytes" + + if do_diff and avg_diff_to_goal == 0. : + title += "\nNo change between the two commits" + elif do_diff : + avg_diff_str = str(format(abs(avg_diff_to_goal), '.2f')) + if key == "Time_(second)" : + if avg_diff_to_goal < 0 : + title += "\nIn average we get slower by " + else : + title += "\nIn average we get faster " + title += avg_diff_str + " seconds" + else : + if avg_diff_to_goal < 0 : + title += "\nIn average we use " + avg_diff_str + " more" + else : + title += "\nIn average we use " + avg_diff_str + " less" + title += " kbytes" + + plt.title(title, fontsize=15) + plt.xlabel(key.replace("_"," "), fontsize=14) + plt.ylabel("# of meshes", fontsize=14) + plt.tick_params(axis="x", labelsize=9) + plt.tick_params(axis="y", labelsize=9) + + chart_filename = "" + if do_diff : + chart_filename += "diff_"+commit_hash+"_"+diff_hash+"_"+key+"_"+date_for_filename+".pdf" + else : + chart_filename += "results_"+commit_hash+"_"+key+"_"+date_for_filename+".pdf" + chart_path = os.path.join(outputdir+"/charts",chart_filename) + if os.path.isfile(chart_path) : + os.remove(chart_path) + plt.savefig(chart_path, bbox_inches="tight") + plt.close() + + print("pdf updated") + + sys.exit() + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/performance_benchmark.cpp b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/performance_benchmark.cpp new file mode 100644 index 00000000000..207b4704635 --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/performance_benchmark.cpp @@ -0,0 +1,65 @@ +#include +#include + +#include + +#include + +#include +#include +#include +#include + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point_3 = K::Point_3; +using Vector_3 = K::Vector_3; + +using Mesh = CGAL::Surface_mesh; + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char** argv) +{ + const int argc_check = argc - 1; + const char* entry_name_ptr = nullptr; + double relative_alpha_ratio = 20., relative_offset_ratio = 600.; + + for(int i=1; i points; + std::vector > faces; + if(!CGAL::IO::read_polygon_soup(entry_name_ptr, points, faces) || faces.empty()) + { + std::cerr << "Error: Invalid input data." << std::endl; + return EXIT_FAILURE; + } + + CGAL::Bbox_3 bbox; + for(const Point_3& p : points) + bbox += p.bbox(); + + const double diag_length = std::sqrt(CGAL::square(bbox.xmax() - bbox.xmin()) + + CGAL::square(bbox.ymax() - bbox.ymin()) + + CGAL::square(bbox.zmax() - bbox.zmin())); + const double alpha = diag_length / relative_alpha_ratio; + const double offset = diag_length / relative_offset_ratio; + + Mesh wrap; + CGAL::alpha_wrap_3(points, faces, alpha, offset, wrap); + + return EXIT_SUCCESS; +} diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/compute_quality_benchmark_data.py b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/compute_quality_benchmark_data.py new file mode 100644 index 00000000000..3b996cb5749 --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/compute_quality_benchmark_data.py @@ -0,0 +1,54 @@ +# Copyright (c) 2019-2023 Google LLC (USA). +# All rights reserved. +# +# This file is part of CGAL (www.cgal.org). +# +# $URL$ +# $Id$ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +# Author(s) : Pierre Alliez +# Michael Hemmer +# Cedric Portaneri +# +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, getopt + +def compute_quality_benchmark_data(execname, filename, alpha): + + output = "" + cmd = (execname, "-i", + filename, "-a", alpha) + proc = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + start_new_session=True) + + outs, errs = proc.communicate() + output = outs.decode("utf-8") + errs.decode("utf-8") + + print(output) + +def main(argv): + execname="" + filename="" + alpha="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'e:i:a:') + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "-e": + execname = arg + elif opt == "-i": + filename = arg + elif opt == "-a": + alpha = arg + + compute_quality_benchmark_data(execname, filename, alpha) + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/distance_utils.h b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/distance_utils.h new file mode 100644 index 00000000000..379573e9c90 --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/distance_utils.h @@ -0,0 +1,151 @@ +// Copyright (c) 2019-2022 Google LLC (USA). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Pierre Alliez +// Michael Hemmer +// Cedric Portaneri + +#ifndef CGAL_ALPHA_WRAP_3_BENCHMARK_ALPHA_WRAP_3_QUALITY_DISTANCE_H_ +#define CGAL_ALPHA_WRAP_3_BENCHMARK_ALPHA_WRAP_3_QUALITY_DISTANCE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Aw3i { + +enum Distance_metric { HAUSDORFF = 0, MEAN = 1, RMS = 2 }; + +template +inline double approximate_hausdorff_distance(const std::vector& sample_points, + const AABBTree& tree, + Point& hint) +{ + double hdist = 0; + for(const Point& pt : sample_points) + { + hint = tree.closest_point(pt, hint); + auto dist = CGAL::squared_distance(hint, pt); + double d = CGAL::to_double(CGAL::approximate_sqrt(dist)); + if(d > hdist) + hdist = d; + } + + return hdist; +} + +template +inline double approximate_mean_distance(const std::vector& sample_points, + const AABBTree& tree, + Point& hint) +{ + double mdist = 0; + for(const Point& pt : sample_points) + { + hint = tree.closest_point(pt, hint); + auto dist = CGAL::squared_distance(hint, pt); + double d = CGAL::to_double(CGAL::approximate_sqrt(dist)); + mdist += d; + } + + return mdist / sample_points.size(); +} + +template +inline double approximate_rms_distance(const std::vector& sample_points, + const AABBTree& tree, + Point& hint) +{ + double rmsdist = 0; + for(const Point& pt : sample_points) + { + hint = tree.closest_point(pt, hint); + auto dist = CGAL::squared_distance(hint, pt); + rmsdist += CGAL::to_double(dist); + } + + return CGAL::to_double(CGAL::approximate_sqrt(rmsdist / sample_points.size())); +} + +template +inline double approximate_distance(const TriangleMesh& tm1, + const TriangleMesh& tm2, + const Distance_metric& metric) +{ + using GT = typename CGAL::GetGeomTraits::type; + using Point_3 = typename GT::Point_3; + + using Primitive = CGAL::AABB_face_graph_triangle_primitive; + using AABB_traits = CGAL::AABB_traits; + using AABB_tree = CGAL::AABB_tree; + + using CGAL::parameters::choose_parameter; + using CGAL::parameters::get_parameter; + + std::vector original_sample_points; + CGAL::Polygon_mesh_processing::sample_triangle_mesh(tm1, std::back_inserter(original_sample_points), + CGAL::parameters::all_default()); + + std::vector sample_points(std::begin(original_sample_points), + std::end(original_sample_points)); + CGAL::spatial_sort(sample_points.begin(), sample_points.end()); + + AABB_tree tree(faces(tm2).first, faces(tm2).second, tm2); + tree.build(); + + auto vpm_2 = get(CGAL::vertex_point, tm2); + Point_3 hint = get(vpm_2, *vertices(tm2).first); + + if(metric == HAUSDORFF) + return approximate_hausdorff_distance(sample_points, tree, hint); + else if(metric == MEAN) + return approximate_mean_distance(sample_points, tree, hint); + else if(metric == RMS) + return approximate_rms_distance(sample_points, tree, hint); + else + std::cerr << "Metric unknown\n" << std::endl; + + return -1.0; +} + +template +double get_longest_diag_bbox(const TriangleMesh& tm) +{ + CGAL::Bbox_3 bbox = CGAL::Polygon_mesh_processing::bbox(tm); + return std::sqrt(CGAL::square(bbox.xmax() - bbox.xmin()) + + CGAL::square(bbox.ymax() - bbox.ymin()) + + CGAL::square(bbox.zmax() - bbox.zmin())); +} + +template +inline double approximate_distance_relative_to_bbox(const TriangleMesh& tm1, + const TriangleMesh& tm2, + const Distance_metric& metric) +{ + double longest_diag_length = get_longest_diag_bbox(tm1); + return approximate_distance(tm1, tm2, metric) / longest_diag_length; +} + +template +inline double approximate_distance_relative_to_bbox(const TriangleMesh& tm1, + const TriangleMesh& tm2, + const Distance_metric& metric, + const FT& longest_diag_length) +{ + return approximate_distance(tm1, tm2, metric) / CGAL::to_double(longest_diag_length); +} + +} // namespace Aw3i + +#endif // CGAL_CGAL_ALPHA_WRAP_3_BENCHMARK_ALPHA_WRAP_3_QUALITY_DISTANCE_H_ diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/generate_quality_benchmark_charts.py b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/generate_quality_benchmark_charts.py new file mode 100644 index 00000000000..0df5ed5e0f4 --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/generate_quality_benchmark_charts.py @@ -0,0 +1,182 @@ +# Copyright (c) 2019-2023 Google LLC (USA). +# All rights reserved. +# +# This file is part of CGAL (www.cgal.org). +# +# $URL$ +# $Id$ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +# Author(s) : Pierre Alliez +# Michael Hemmer +# Cedric Portaneri +# +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, signal, getopt +import numpy as np +import matplotlib.pyplot as plt + +def main(argv): + + inputdir="" + outputdir="" + commit_hash="" + alpha="" + do_diff=False + diffdir="" + diff_hash="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'i:a:o:c:d:p:') + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "-i": + inputdir = arg + elif opt == "-a": + alpha = arg + elif opt == "-o": + outputdir = arg + elif opt == "-c": + commit_hash = arg + elif opt == "-d": + diff_hash = arg + do_diff = True + elif opt == "-p": + diffdir = arg + + all_metric = { + "Mean_Min_Angle_(degree)" : {}, + "Mean_Max_Angle_(degree)" : {}, + "Mean_Radius_Ratio" : {}, + "Mean_Edge_Ratio" : {}, + "Mean_Aspect_Ratio" : {}, + "Complexity_(#_of_triangle)" : {}, + "#_of_almost_degenerate_triangle" : {}, + "Hausdorff_distance_output_to_input_(%_of_bbox_diag)" : {}} + num_input = 0 + print("inputdir = ", inputdir) + for filename in os.listdir(inputdir) : + new_path = os.path.join(inputdir,filename) + new_file = open(new_path) + if do_diff : + old_path = os.path.join(diffdir,filename) + old_file = open(old_path) + is_empty_old = os.path.getsize(old_path) <= 1 + for key in all_metric : + try : + new_val = float(new_file.readline().rstrip('\n')) + old_val = float(old_file.readline().rstrip('\n')) + mesh_id = str(filename.split('.')[0]) + all_metric[key][mesh_id] = [new_val, old_val] + except ValueError: + pass + else : + for key in all_metric : + try : + new_val = float(new_file.readline().rstrip('\n')) + mesh_id = str(filename.split('.')[0]) + all_metric[key][mesh_id] = [new_val, new_val] + except ValueError: + pass + num_input = num_input+1 + + # update .pdf chart + date_now = datetime.datetime.now() + date_for_filename = str(date_now.year) +"_"+ str(date_now.month) +"_"+ str(date_now.day) +"_"+ str(date_now.hour) +"h"+ str(date_now.minute) +"mn" + for key in all_metric: + goal = 0 + if key == "Mean_Min_Angle_(degree)" or key == "Mean_Max_Angle_(degree)": + goal = 60 + elif key == "Mean_Radius_Ratio" or key == "Mean_Edge_Ratio" or key == "Mean_Aspect_Ratio" : + goal = 1 + + num_el = range(len(all_metric[key])) + avg_diff_to_goal = 0. + avg = 0. + x1 = [] + x2 = [] + for value in all_metric[key].values() : + avg += value[0] + diff_to_goal = abs(value[1]-goal) - abs(value[0]-goal) + avg_diff_to_goal += diff_to_goal + x1.append(value[0]) + x2.append(value[1]) + avg_diff_to_goal /= float(len(all_metric[key])) + avg /= float(len(all_metric[key])) + + plt.figure(figsize=(8,8)) + if do_diff : + plt.hist(x2, bins=100, color='tab:green', alpha=0.5) + plt.hist(x1, bins=100, color='tab:blue', alpha=0.5) + plt.vlines(x = goal, ymin=plt.ylim()[0], ymax=plt.ylim()[1], linestyles='dashed') + + title = "" + if do_diff : + title += "Diff between " + commit_hash + " and " + diff_hash + " on " + str(num_input) + " meshes from Thingi10K\nAlpha = Bbox diag length / " + alpha + else : + title += "Benchmarking on " + str(num_input) + " meshes from Thingi10K\nAlpha = Bbox diag length / " + alpha + + avg_str = str(format(abs(avg), '.2f')) + if key == "Mean_Min_Angle_(degree)" or key == "Mean_Max_Angle_(degree)": + title += "\nIn average we have " + avg_str + "°" + elif key == "Mean_Radius_Ratio" or key == "Mean_Edge_Ratio" or key == "Mean_Aspect_Ratio" : + title += "\nIn average we have a ratio of " + avg_str + elif key == "Hausdorff_distance_output_to_input_(%_of_bbox_diag)" : + title += "\nIn average we have a distance of " + avg_str + "% of bbox diag" + elif key == "Complexity_(#_of_triangle)" or key == "#_of_almost_degenerate_triangle" : + title += "\nIn average we have " + avg_str + " triangles" + + if do_diff and avg_diff_to_goal == 0. : + title += "\nNo change between the two commits" + elif do_diff : + avg_diff_str = str(format(abs(avg_diff_to_goal), '.2f')) + if key == "Mean_Min_Angle_(degree)" or key == "Mean_Max_Angle_(degree)": + if avg_diff_to_goal < 0 : + title += "\nIn average we loose " + else : + title += "\nIn average we gain " + title += avg_diff_str + "° toward 60°" + elif key == "Mean_Radius_Ratio" or key == "Mean_Edge_Ratio" or key == "Mean_Aspect_Ratio" : + if avg_diff_to_goal < 0 : + title += "\nIn average we loose " + else : + title += "\nIn average we gain " + title += avg_diff_str + " of ratio toward 1" + elif key == "Hausdorff_distance_output_to_input_(%_of_bbox_diag)" : + if avg_diff_to_goal < 0 : + title += "\nIn average we increase by " + else : + title += "\nIn average we reduce by " + title += avg_diff_str + " the bbox ratio" + elif key == "Complexity_(#_of_triangle)" or key == "#_of_almost_degenerate_triangle" : + if avg_diff_to_goal < 0 : + title += "\nIn average we get " + avg_diff_str + " more" + else : + title += "\nIn average we get " + avg_diff_str + " less" + title += " triangles" + + plt.title(title, fontsize=15) + plt.xlabel(key.replace("_"," "), fontsize=14) + plt.ylabel("# of meshes", fontsize=14) + plt.tick_params(axis="x", labelsize=9) + plt.tick_params(axis="y", labelsize=9) + + chart_filename = "" + if do_diff : + chart_filename += "diff_"+commit_hash+"_"+diff_hash+"_"+key+"_"+date_for_filename+".pdf" + else : + chart_filename += "results_"+commit_hash+"_"+key+"_"+date_for_filename+".pdf" + chart_path = os.path.join(outputdir+"/charts",chart_filename) + if os.path.isfile(chart_path) : + os.remove(chart_path) + plt.savefig(chart_path, bbox_inches="tight") + plt.close() + + print("pdf updated") + + sys.exit() + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp new file mode 100644 index 00000000000..f8e54c488a4 --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp @@ -0,0 +1,271 @@ +#include + +#include +#include + +#include + +#include + +#include +#include +#include + +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point_3 = Kernel::Point_3; +using Vector_3 = Kernel::Vector_3; +using Triangle_3 = Kernel::Triangle_3; +using FT = Kernel::FT; + +using Mesh = CGAL::Surface_mesh; +using face_descriptor = boost::graph_traits::face_descriptor; + +using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_mesh_oracle; +using Dt = CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3::Triangulation; + +namespace PMP = CGAL::Polygon_mesh_processing; + +std::array triangle_angles(const Triangle_3& tr) +{ + FT sq_a = CGAL::squared_distance(tr[0], tr[1]); + FT sq_b = CGAL::squared_distance(tr[1], tr[2]); + FT sq_c = CGAL::squared_distance(tr[2], tr[0]); + + FT two_ab = 2. * CGAL::sqrt(sq_a) * CGAL::sqrt(sq_b); + FT two_bc = 2. * CGAL::sqrt(sq_b) * CGAL::sqrt(sq_c); + FT two_ca = 2. * CGAL::sqrt(sq_c) * CGAL::sqrt(sq_a); + + FT angle_a = (sq_b + sq_c - sq_a) / two_bc; + FT angle_b = (sq_c + sq_a - sq_b) / two_ca; + FT angle_c = (sq_a + sq_b - sq_c) / two_ab; + if(angle_a < -1.) angle_a = -1.; + if(angle_b < -1.) angle_b = -1.; + if(angle_c < -1.) angle_c = -1.; + if(angle_a > 1.) angle_a = 1.; + if(angle_b > 1.) angle_b = 1.; + if(angle_c > 1.) angle_c = 1.; + angle_a = std::acos(angle_a); + angle_b = std::acos(angle_b); + angle_c = std::acos(angle_c); + + return {angle_a, angle_b, angle_c}; +} + +bool is_almost_degenerate(const Triangle_3& tr, + double threshold) +{ + FT sq_area = tr.squared_area(); + return (CGAL::sqrt(CGAL::to_double(sq_area)) < threshold); +} + +auto surface_mesh_face_to_triangle(const face_descriptor fd, + const Mesh& sm) +{ + typename boost::graph_traits::halfedge_descriptor hd = halfedge(fd,sm); + return Triangle_3(sm.point(target(hd,sm)), + sm.point(target(next(hd,sm),sm)), + sm.point(target(next(next(hd,sm),sm),sm))); +} + +double mean_min_angle(const Mesh& mesh) +{ + double mean_min_angle = 0.; + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + std::array angles = triangle_angles(tr); + + FT min_angle = std::min({angles[0], angles[1], angles[2]}); + + min_angle = min_angle * (180.0 / CGAL_PI); + mean_min_angle += min_angle; + } + + mean_min_angle /= static_cast(mesh.number_of_faces()); + return mean_min_angle; +} + +double mean_max_angle(const Mesh& mesh) +{ + double mean_max_angle = 0.; + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + std::array angles = triangle_angles(tr); + + FT max_angle = std::max({angles[0], angles[1], angles[2]}); + + max_angle = max_angle * (180.0 / CGAL_PI); + mean_max_angle += max_angle; + } + + mean_max_angle /= static_cast(mesh.number_of_faces()); + return mean_max_angle; +} + +double mean_radius_ratio(const Mesh& mesh, + double degenerate_threshold) +{ + double mean_radius_ratio = 0.; + size_t num_almost_degenerate_tri = 0; + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + if(is_almost_degenerate(tr, degenerate_threshold)) + { + ++num_almost_degenerate_tri; + continue; + } + + FT circumsphere_radius = std::sqrt(CGAL::squared_radius(tr[0], tr[1], tr[2])); + + FT a = std::sqrt(CGAL::squared_distance(tr[0], tr[1])); + FT b = std::sqrt(CGAL::squared_distance(tr[1], tr[2])); + FT c = std::sqrt(CGAL::squared_distance(tr[2], tr[0])); + FT s = 0.5 * (a + b + c); + FT inscribed_radius = std::sqrt((s * (s - a) * (s - b) * (s - c)) / s); + FT radius_ratio = circumsphere_radius / inscribed_radius; + radius_ratio /= 2.; // normalized + mean_radius_ratio += radius_ratio; + } + + mean_radius_ratio /= static_cast(mesh.number_of_faces() - num_almost_degenerate_tri); + return mean_radius_ratio; +} + +double mean_edge_ratio(const Mesh& mesh, + double degenerate_threshold) +{ + double mean_edge_ratio = 0.; + size_t num_almost_degenerate_tri = 0; + + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + if(is_almost_degenerate(tr, degenerate_threshold)) + { + ++num_almost_degenerate_tri; + continue; + } + + FT a = std::sqrt(CGAL::squared_distance(tr[0], tr[1])); + FT b = std::sqrt(CGAL::squared_distance(tr[1], tr[2])); + FT c = std::sqrt(CGAL::squared_distance(tr[2], tr[0])); + FT min_edge = std::min({a, b, c}); + FT max_edge = std::max({a, b, c}); + FT edge_ratio = max_edge / min_edge; + + mean_edge_ratio += edge_ratio; + } + + mean_edge_ratio /= static_cast(mesh.number_of_faces() - num_almost_degenerate_tri); + return mean_edge_ratio; +} + +double mean_aspect_ratio(const Mesh& mesh, + double degenerate_threshold) +{ + double mean_aspect_ratio = 0.; + size_t num_almost_degenerate_tri = 0; + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + if(is_almost_degenerate(tr, degenerate_threshold)) + { + ++num_almost_degenerate_tri; + continue; + } + + FT a = std::sqrt(CGAL::squared_distance(tr[0], tr[1])); + FT b = std::sqrt(CGAL::squared_distance(tr[1], tr[2])); + FT c = std::sqrt(CGAL::squared_distance(tr[2], tr[0])); + FT s = 0.5 * (a + b + c); + FT inscribed_radius = std::sqrt((s * (s - a) * (s - b) * (s - c)) / s); + FT max_edge = std::max({a, b, c}); + FT aspect_ratio = max_edge / inscribed_radius; + aspect_ratio /= (2. * std::sqrt(3.)); // normalized + mean_aspect_ratio += aspect_ratio; + } + + mean_aspect_ratio /= static_cast(mesh.number_of_faces() - num_almost_degenerate_tri); + return mean_aspect_ratio; +} + +size_t num_almost_degenerate_tri(const Mesh& mesh, + double degenerate_threshold) +{ + size_t num_almost_degenerate_tri = 0; + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + if(is_almost_degenerate(tr, degenerate_threshold)) + { + ++num_almost_degenerate_tri; + } + } + return num_almost_degenerate_tri; +} + +int main(int argc, char** argv) +{ + const int argc_check = argc - 1; + char *entry_name_ptr = nullptr; + double relative_alpha_ratio = 20.; + double relative_offset_ratio = 600.; + + for(int i=1; i +#include + +#include +#include + +#include + +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point_3 = Kernel::Point_3; +using Mesh = CGAL::Surface_mesh; + +namespace CGAL { +namespace Alpha_wraps_3 { +namespace internal { +namespace { + +enum Robustness_benchmark_exit_code +{ + // Success + VALID_SOLID_OUTPUT = 0, + + // Failure + INPUT_IS_INVALID = 1, + OUTPUT_IS_NOT_TRIANGLE_MESH = 2, + OUTPUT_IS_COMBINATORIAL_NON_MANIFOLD = 3, + OUTPUT_HAS_BORDERS = 4, + OUTPUT_HAS_DEGENERATED_FACES = 5, + OUTPUT_HAS_GEOMETRIC_SELF_INTERSECTIONS = 6, + OUTPUT_DOES_NOT_BOUND_VOLUME = 7, + OUTPUT_DOES_NOT_CONTAIN_INPUT = 8, + OUTPUT_DISTANCE_IS_TOO_LARGE = 9, +}; + +} // namespace +} // namespace internal +} // namespace Alpha_wraps_3 +} // namespace CGAL + +namespace PMP = CGAL::Polygon_mesh_processing; +namespace AW3i = CGAL::Alpha_wraps_3::internal; + +int main(int argc, char** argv) +{ + const int argc_check = argc - 1; + char* entry_name_ptr = nullptr; + double relative_alpha_ratio = 20.; + double relative_offset_ratio = 600.; + + for(int i=1; i $2/Robustness/results/$5/$filename.log + + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/compute_performance_benchmark_data.py \ + -e $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/build-release/performance_benchmark -i $6 -a $3 \ + > $2/Performance/results/$5/$filename.log + + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/compute_quality_benchmark_data.py \ + -e $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/build-release/quality_benchmark -i $6 -a $3 \ + > $2/Quality/results/$5/$filename.log +} +export -f compute_benchmark_data + +# $1: directory containing the alpha wrap project +# $2: directory containing the input data folder +# $3: directory containing the output results +# $4: alpha value +# $5: timeout value for robustness benchmark in seconds +# $6: number of virtual thread used +# $7: hash of the latest commit +# $8: hash of a commit to perform the diff with latest +cd $1 + +mkdir -p $3/Robustness/results/$7 +mkdir -p $3/Performance/results/$7 +mkdir -p $3/Quality/results/$7 +mkdir -p $3/Robustness/charts_data +mkdir -p $3/Performance/charts_data +mkdir -p $3/Quality/charts_data +mkdir -p $3/Robustness/charts +mkdir -p $3/Performance/charts +mkdir -p $3/Quality/charts +mkdir -p $3/Robustness/log +mkdir -p $3/Performance/log +mkdir -p $3/Quality/log +mkdir -p $3/charts + +find $2 -mindepth 1 | parallel -j$6 compute_benchmark_data $1 $3 $4 $5 $7 ::: + +python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/generate_robustness_benchmark_charts.py -i $3/Robustness/results/$7 -o $3/Robustness -a $4 -c $7 + +if [ -z "$8" ]; then + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/generate_performance_benchmark_charts.py -i $3/Performance/results/$7 -o $3/Performance -a $4 -c $7; +else + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/generate_performance_benchmark_charts.py -i $3/Performance/results/$7 -o $3/Performance -a $4 -c $7 -p $3/Performance/results/$8 -d $8; +fi + +if [ -z "$8" ]; then + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/generate_quality_benchmark_charts.py -i $3/Quality/results/$7 -o $3/Quality -a $4 -c $7; +else + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/generate_quality_benchmark_charts.py -i $3/Quality/results/$7 -o $3/Quality -a $4 -c $7 -p $3/Quality/results/$8 -d $8; +fi + +charts_path="$(ls "$3/Robustness/charts"/* -dArt | tail -n 1) $(ls "$3/Performance/charts"/* -dArt | tail -n 2) $(ls "$3/Quality/charts"/* -dArt | tail -n 9)" + +pdfjam --nup 2x6 $charts_path --outfile $3/charts/results_$7_$8_alpha_$4_$(date '+%Y-%m-%d_%H:%M:%S').pdf diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt b/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt index 0be54f87eed..40187ca194c 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt @@ -13,3 +13,5 @@ create_single_source_cgal_program("point_set_wrap.cpp") create_single_source_cgal_program("wrap_from_cavity.cpp") create_single_source_cgal_program("mixed_inputs_wrap.cpp") create_single_source_cgal_program("volumetric_wrap.cpp") +create_single_source_cgal_program("successive_wraps.cpp") +create_single_source_cgal_program("pause_and_resume_wrapping.cpp") diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp index ffcedc7f1cb..90b488e0407 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp @@ -103,10 +103,10 @@ int main(int argc, char** argv) oracle.add_segment_soup(segments, CGAL::parameters::default_values()); oracle.add_point_set(ps_points, CGAL::parameters::default_values()); - CGAL::Alpha_wraps_3::internal::Alpha_wrap_3 aw3(oracle); + CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3 aw3(oracle); - Mesh output_mesh; - aw3(alpha, offset, output_mesh); + Mesh wrap; + aw3(alpha, offset, wrap); t.stop(); std::cout << "Took " << t.time() << std::endl; @@ -120,10 +120,11 @@ int main(int argc, char** argv) std::string ps_name = std::string(ps_filename); ps_name = ps_name.substr(ps_name.find_last_of("/") + 1, ps_name.length() - 1); ps_name = ps_name.substr(0, ps_name.find_last_of(".")); - std::string output_name = ts_name + "_" + ss_name + "_" + ps_name + "_" + std::to_string(static_cast(relative_alpha)) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + std::string output_name = ts_name + "_" + ss_name + "_" + ps_name + "_" + + std::to_string(static_cast(relative_alpha)) + "_" + + std::to_string(static_cast(relative_offset)) + ".off"; std::cout << "Writing to " << output_name << std::endl; - CGAL::IO::write_polygon_mesh(output_name, output_mesh, CGAL::parameters::stream_precision(17)); + CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); return EXIT_SUCCESS; } diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/output_helper.h b/Alpha_wrap_3/examples/Alpha_wrap_3/output_helper.h new file mode 100644 index 00000000000..581ac82bff0 --- /dev/null +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/output_helper.h @@ -0,0 +1,19 @@ +#ifndef CGAL_ALPHA_WRAP_3_EXAMPLES_OUTPUT_HELPER_H +#define CGAL_ALPHA_WRAP_3_EXAMPLES_OUTPUT_HELPER_H + +#include + +std::string generate_output_name(std::string input_name, + const double alpha, + const double offset) +{ + input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); + input_name = input_name.substr(0, input_name.find_last_of(".")); + std::string output_name = input_name + + "_" + std::to_string(static_cast(alpha)) + + "_" + std::to_string(static_cast(offset)) + ".off"; + + return output_name; +} + +#endif // CGAL_ALPHA_WRAP_3_EXAMPLES_OUTPUT_HELPER_H diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp new file mode 100644 index 00000000000..cee169048c3 --- /dev/null +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp @@ -0,0 +1,164 @@ +// This example demonstrates how to interrupt the wrapping process before it has terminated, +// and how to resume afterwards. +// +// -------------------------------- !! Warning !! -------------------------------------------------- +// By default, the wrapper uses an unsorted LIFO queue of faces to refine. This means that +// the intermediate result is not very useful because the algorithm carves deep and not wide +// (somewhat like a DFS vs a BFS). +// +// The sorted queue option is enabled with the macro below to make the refinement algorithm +// more uniform. The downside is that it is slower. +// ------------------------------------------------------------------------------------------------- +#define CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + +#include "output_helper.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace AW3 = CGAL::Alpha_wraps_3; +namespace PMP = CGAL::Polygon_mesh_processing; + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point_3 = K::Point_3; + +using Points = std::vector; +using Face = std::array; +using Faces = std::vector; + +using Mesh = CGAL::Surface_mesh; +using face_descriptor = boost::graph_traits::face_descriptor; + +struct Interrupter_visitor + : public AW3::internal::Wrapping_default_visitor +{ + using Base = AW3::internal::Wrapping_default_visitor; + + CGAL::Real_timer timer; + double max_time = -1; // in seconds + +public: + void set_max_time(double t) { max_time = t; } + +public: + template + void on_flood_fill_begin(const AlphaWrapper&) + { + std::cout << "Starting timer..." << std::endl; + timer.start(); + } + + template + bool go_further(const Wrapper&) + { + if(timer.time() > max_time) + { + timer.stop(); + std::cout << "Paused after " << timer.time() << " s." << std::endl; + return false; + } + + return true; + } +}; + +int main(int argc, char** argv) +{ + std::cout.precision(17); + std::cerr.precision(17); + + CGAL::Random rng; + std::cout << "Random seed = " << rng.get_seed() << std::endl; + + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/armadillo.off"); + + // = read the soup + Points points; + Faces faces; + if(!CGAL::IO::read_polygon_soup(filename, points, faces) || faces.empty()) + { + std::cerr << "Invalid soup input: " << filename << std::endl; + return EXIT_FAILURE; + } + + std::cout << "Input: " << points.size() << " points, " << faces.size() << " faces" << std::endl; + + // Compute the alpha and offset values + const double relative_alpha = (argc > 2) ? std::stod(argv[2]) : rng.get_double(150., 200.); + const double relative_offset = (argc > 3) ? std::stod(argv[3]) : 600.; + std::cout << "relative_alpha = " << relative_alpha << std::endl; + + CGAL::Bbox_3 bbox; + for(const Point_3& p : points) + bbox += p.bbox(); + + const double diag_length = std::sqrt(CGAL::square(bbox.xmax() - bbox.xmin()) + + CGAL::square(bbox.ymax() - bbox.ymin()) + + CGAL::square(bbox.zmax() - bbox.zmin())); + + const double alpha = diag_length / relative_alpha; + const double offset = diag_length / relative_offset; + + // Build the wrapper + using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_soup_oracle; + Oracle oracle(alpha); + oracle.add_triangle_soup(points, faces, CGAL::parameters::default_values()); + CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3 aw3(oracle); + + // --- Launch the wrapping, and pause when the algorithm has spent 1s flooding + Interrupter_visitor interrupter; + interrupter.set_max_time(1.); + + Mesh wrap; + aw3(alpha, offset, wrap, CGAL::parameters::visitor(interrupter)); + std::cout << ">>> The current wrap has " << num_vertices(wrap) << " vertices" << std::endl; + CGAL::IO::write_polygon_mesh("stopped_1.off", wrap, CGAL::parameters::stream_precision(17)); + + // --- Restart from the previous state, and pause a bit further + interrupter.set_max_time(2.); + aw3(alpha, offset, wrap, CGAL::parameters::visitor(interrupter) + .refine_triangulation(true)); + std::cout << ">>> The current wrap has " << num_vertices(wrap) << " vertices" << std::endl; + CGAL::IO::write_polygon_mesh("stopped_2.off", wrap, CGAL::parameters::stream_precision(17)); + + // --- Restart from the previous state, and let it finish + aw3(alpha, offset, wrap, CGAL::parameters::refine_triangulation(true)); + std::cout << ">>> The final (resumed) wrap has " << num_vertices(wrap) << " vertices" << std::endl; + std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); + std::cout << "Writing to " << "resumed_" + output_name << std::endl; + CGAL::IO::write_polygon_mesh("resumed_" + output_name, wrap, CGAL::parameters::stream_precision(17)); + + // --- Get the final wrap, in one go: + Mesh single_pass_wrap; + CGAL::alpha_wrap_3(points, faces, alpha, offset, single_pass_wrap); + std::cout << ">>> The final (from scratch) wrap has " << num_vertices(single_pass_wrap) << " vertices" << std::endl; + + output_name = generate_output_name(filename, relative_alpha, relative_offset); + std::cout << "Writing to " << output_name << std::endl; + CGAL::IO::write_polygon_mesh(output_name, single_pass_wrap, CGAL::parameters::stream_precision(17)); + + // --- Compare the results to ensure both approaches yield identical meshes + std::vector > common; + std::vector m1_only; + std::vector m2_only; + PMP::match_faces(wrap, single_pass_wrap, + std::back_inserter(common), + std::back_inserter(m1_only), + std::back_inserter(m2_only)); + if(!m1_only.empty() || !m2_only.empty()) + { + std::cerr << "Error: The two wraps should have been identical!" << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp index 8742a2a2001..a602cf5c58b 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp @@ -1,3 +1,5 @@ +#include "output_helper.h" + #include #include @@ -23,7 +25,7 @@ int main(int argc, char** argv) Point_container points; if(!CGAL::IO::read_points(filename, std::back_inserter(points)) || points.empty()) { - std::cerr << "Invalid input." << std::endl; + std::cerr << "Invalid input:" << filename << std::endl; return EXIT_FAILURE; } @@ -53,11 +55,7 @@ int main(int argc, char** argv) std::cout << "Took " << t.time() << " s." << std::endl; // Save the result - std::string input_name = std::string(filename); - input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); - input_name = input_name.substr(0, input_name.find_last_of(".")); - std::string output_name = input_name + "_" + std::to_string(static_cast(relative_alpha)) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + const std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp new file mode 100644 index 00000000000..301aec46e2d --- /dev/null +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp @@ -0,0 +1,135 @@ +// In this example, we reuse the underlying triangulation of the previous state, and carve using +// a new (smaller) alpha value. This enables considerable speed-up: the cumulated time taken +// to run `n` successive instances of `{alpha_wrap(alpha_i)}_(i=1...n)` will be roughly equal +// to the time taken to the single instance of alpha_wrap(alpha_n) from scratch. +// +// The speed-up increases with the number of intermediate results, and on the gap between +// alpha values: if alpha_2 is close to alpha_1, practically no new computation are required, +// and the speed-up is almost 100%. +// +// -------------------------------- !! Warning !! -------------------------------------------------- +// The result of: +// > alpha_wrap(alpha_1, ...) +// > alpha_wrap(alpha_2, ..., reuse) +// is not exactly identical to calling directly: +// > alpha_wrap(alpha_2, ..., do_not_reuse) +// because the queues are sorted slightly differently and the AABB tree is rebuilt differently +// to optimize the runtime. +// ------------------------------------------------------------------------------------------------- + +#include "output_helper.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include + +namespace PMP = CGAL::Polygon_mesh_processing; + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; +using FT = K::FT; +using Point_3 = K::Point_3; + +using Mesh = CGAL::Surface_mesh; + +int main(int argc, char** argv) +{ + std::cout.precision(17); + std::cerr.precision(17); + + // Read the input + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/cube.off"); + std::cout << "Reading " << filename << "..." << std::endl; + + Mesh mesh; + if(!PMP::IO::read_polygon_mesh(filename, mesh) || is_empty(mesh) || !is_triangle_mesh(mesh)) + { + std::cerr << "Invalid input:" << filename << std::endl; + return EXIT_FAILURE; + } + + std::cout << "Input: " << num_vertices(mesh) << " vertices, " << num_faces(mesh) << " faces" << std::endl; + + const CGAL::Bbox_3 bbox = CGAL::Polygon_mesh_processing::bbox(mesh); + const double diag_length = std::sqrt(CGAL::square(bbox.xmax() - bbox.xmin()) + + CGAL::square(bbox.ymax() - bbox.ymin()) + + CGAL::square(bbox.zmax() - bbox.zmin())); + + // We want decreasing alphas, and these are relative ratios, so they need to be increasing + const std::vector relative_alphas = { 1, 50, 100, 150, 200, 250 }; + const FT relative_offset = 600; + + // =============================================================================================== + // Naive approach: + + CGAL::Real_timer t; + double total_time = 0.; + + for(std::size_t i=0; i>> [" << i << "] alpha: " << alpha << " offset: " << offset << std::endl; + + Mesh wrap; + CGAL::alpha_wrap_3(mesh, alpha, offset, wrap); + + t.stop(); + std::cout << " Result: " << num_vertices(wrap) << " vertices, " << num_faces(wrap) << " faces" << std::endl; + std::cout << " Elapsed time: " << t.time() << " s." << std::endl; + + total_time += t.time(); + } + + std::cout << "Total elapsed time (naive): " << total_time << " s.\n" << std::endl; + + // =============================================================================================== + // Re-use approach + + total_time = 0.; + t.reset(); + + using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_mesh_oracle; + using Wrapper = CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3; + Wrapper wrapper; // contains the triangulation that is being refined iteratively + + for(std::size_t i=0; i>> [" << i << "] alpha: " << alpha << " offset: " << offset << std::endl; + + // The triangle mesh oracle should be initialized with alpha to internally perform a split + // of too-big facets while building the AABB Tree. This split in fact yields a significant + // speed-up for meshes with elements that are large compared to alpha. This speed-up makes it + // faster to re-build the AABB tree for every value of alpha than to use a non-optimized tree. + Oracle oracle(alpha); + oracle.add_triangle_mesh(mesh, CGAL::parameters::default_values()); + wrapper.oracle() = oracle; + + Mesh wrap; + wrapper(alpha, offset, wrap, CGAL::parameters::refine_triangulation((i != 0))); + + t.stop(); + std::cout << " Result: " << num_vertices(wrap) << " vertices, " << num_faces(wrap) << " faces" << std::endl; + std::cout << " Elapsed time: " << t.time() << " s." << std::endl; + + total_time += t.time(); + } + + std::cout << "Total elapsed time (successive): " << total_time << " s." << std::endl; + + return EXIT_SUCCESS; +} diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp index 00e2e4fd9fc..d4953490446 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp @@ -1,3 +1,5 @@ +#include "output_helper.h" + #include #include @@ -25,7 +27,7 @@ int main(int argc, char** argv) Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh) || is_empty(mesh) || !is_triangle_mesh(mesh)) { - std::cerr << "Invalid input." << std::endl; + std::cerr << "Invalid input:" << filename << std::endl; return EXIT_FAILURE; } @@ -56,12 +58,7 @@ int main(int argc, char** argv) std::cout << "Took " << t.time() << " s." << std::endl; // Save the result - std::string input_name = std::string(filename); - input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); - input_name = input_name.substr(0, input_name.find_last_of(".")); - std::string output_name = input_name - + "_" + std::to_string(static_cast(relative_alpha)) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + const std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp index 626e3bdc3ba..51e04974c28 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp @@ -1,3 +1,5 @@ +#include "output_helper.h" + #include #include @@ -30,7 +32,7 @@ int main(int argc, char** argv) std::vector > faces; if(!CGAL::IO::read_polygon_soup(filename, points, faces) || faces.empty()) { - std::cerr << "Invalid input." << std::endl; + std::cerr << "Invalid input:" << filename << std::endl; return EXIT_FAILURE; } @@ -63,12 +65,7 @@ int main(int argc, char** argv) std::cout << "Took " << t.time() << " s." << std::endl; // Save the result - std::string input_name = std::string(filename); - input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); - input_name = input_name.substr(0, input_name.find_last_of(".")); - std::string output_name = input_name - + "_" + std::to_string(static_cast(relative_alpha)) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + const std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp index 113215b631a..ddc6f765612 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp @@ -1,3 +1,5 @@ +#include "output_helper.h" + #include #include @@ -70,7 +72,7 @@ int main(int argc, char** argv) Faces faces; if(!CGAL::IO::read_polygon_soup(filename, points, faces) || faces.empty()) { - std::cerr << "Invalid input." << std::endl; + std::cerr << "Invalid input:" << filename << std::endl; return EXIT_FAILURE; } @@ -101,7 +103,7 @@ int main(int argc, char** argv) Oracle oracle(K{}); oracle.add_triangle_soup(points, faces, CGAL::parameters::default_values()); - CGAL::Alpha_wraps_3::internal::Alpha_wrap_3 aw3(oracle); + CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3 aw3(oracle); Mesh wrap; aw3(alpha, offset, wrap); @@ -113,12 +115,7 @@ int main(int argc, char** argv) auto dt = aw3.triangulation(); // Save the result - std::string input_name = std::string(filename); - input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); - input_name = input_name.substr(0, input_name.find_last_of(".")); - std::string output_name = input_name - + "_" + std::to_string(static_cast(relative_alpha)) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + const std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp index 1c1d6c7b3d7..970bb583484 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp @@ -1,3 +1,5 @@ +#include "output_helper.h" + #include #include @@ -25,13 +27,13 @@ int main(int argc, char** argv) if(!PMP::IO::read_polygon_mesh(filename, input) || is_empty(input) || !is_triangle_mesh(input)) { - std::cerr << "Invalid input." << std::endl; + std::cerr << "Invalid input:" << filename << std::endl; return EXIT_FAILURE; } std::cout << "Input: " << num_vertices(input) << " vertices, " << num_faces(input) << " faces" << std::endl; - const double relative_alpha = (argc > 2) ? std::stod(argv[2]) : 30.; + const double relative_alpha = (argc > 2) ? std::stod(argv[2]) : 40.; const double relative_offset = (argc > 3) ? std::stod(argv[3]) : 600.; // Compute the alpha and offset values diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 04b30cf7678..d6ca4fb356c 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -49,7 +49,9 @@ #include #include #include -#include +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + #include +#endif #include #include #include @@ -92,6 +94,10 @@ struct Wrapping_default_visitor template void on_flood_fill_begin(const AlphaWrapper&) { } + // Whether the flood filling process should continue + template + constexpr bool go_further(const Wrapper&) { return true; } + template void before_facet_treatment(const AlphaWrapper&, const Gate&) { } @@ -110,7 +116,7 @@ struct Wrapping_default_visitor template -class Alpha_wrap_3 +class Alpha_wrapper_3 { using Oracle = Oracle_; @@ -120,22 +126,36 @@ class Alpha_wrap_3 using Default_Vb = Alpha_wrap_triangulation_vertex_base_3; using Default_Cb = Alpha_wrap_triangulation_cell_base_3; - using Default_Cbt = Cell_base_with_timestamp; // determinism + using Default_Cbt = Cell_base_with_timestamp; // for determinism using Default_Tds = CGAL::Triangulation_data_structure_3; using Default_Triangulation = CGAL::Delaunay_triangulation_3; +public: using Triangulation = typename Default::Get::type; + // Use the geom traits from the triangulation, and trust the (advanced) user that provided it + using Geom_traits = typename Triangulation::Geom_traits; + +private: using Cell_handle = typename Triangulation::Cell_handle; using Facet = typename Triangulation::Facet; using Vertex_handle = typename Triangulation::Vertex_handle; using Locate_type = typename Triangulation::Locate_type; using Gate = internal::Gate; - using Alpha_PQ = Modifiable_priority_queue, CGAL_BOOST_PAIRING_HEAP>; - // Use the geom traits from the triangulation, and trust the (advanced) user that provided it - using Geom_traits = typename Triangulation::Geom_traits; + // A sorted queue is a priority queue sorted by circumradius, and is experimentally significantly + // slower. However, intermediate results are usable: at each point of the algorithm, the wrap + // has a somewhat uniform mesh element size. + // + // An unsorted queue is a LIFO queue, and is experimentally much faster (~35%), + // but intermediate results are not useful: a LIFO carves deep before than wide, + // and can thus for example leave scaffolding faces till almost the end of the refinement. +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + using Alpha_PQ = Modifiable_priority_queue, CGAL_BOOST_PAIRING_HEAP>; +#else + using Alpha_PQ = std::stack; +#endif using FT = typename Geom_traits::FT; using Point_3 = typename Geom_traits::Point_3; @@ -149,33 +169,48 @@ class Alpha_wrap_3 using SC_Iso_cuboid_3 = SC::Iso_cuboid_3; using SC2GT = Cartesian_converter; + using Seeds = std::vector; protected: - const Oracle m_oracle; + Oracle m_oracle; SC_Iso_cuboid_3 m_bbox; - FT m_alpha, m_sq_alpha; - FT m_offset, m_sq_offset; + FT m_alpha = FT(-1), m_sq_alpha = FT(-1); + FT m_offset = FT(-1), m_sq_offset = FT(-1); + + Seeds m_seeds; Triangulation m_tr; + Alpha_PQ m_queue; public: - // Main constructor - Alpha_wrap_3(const Oracle& oracle) - : - m_oracle(oracle), - m_tr(Geom_traits(oracle.geom_traits())), - // used to set up the initial MPQ, use some arbitrary not-too-small value - m_queue(4096) + Alpha_wrapper_3() +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + // '4096' is an arbitrary, not-too-small value for the largest ID in queue initialization + : m_queue(4096) +#endif { // Due to the Steiner point computation being a dichotomy, the algorithm is inherently inexact // and passing exact kernels is explicitly disabled to ensure no misunderstanding. static_assert(std::is_floating_point::value); } + Alpha_wrapper_3(const Oracle& oracle) + : + m_oracle(oracle), + m_tr(Geom_traits(oracle.geom_traits())) +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + , m_queue(4096) +#endif + { + static_assert(std::is_floating_point::value); + } + public: const Geom_traits& geom_traits() const { return m_tr.geom_traits(); } + Oracle& oracle() { return m_oracle; } + const Oracle& oracle() const { return m_oracle; } Triangulation& triangulation() { return m_tr; } const Triangulation& triangulation() const { return m_tr; } const Alpha_PQ& queue() const { return m_queue; } @@ -222,26 +257,53 @@ public: using parameters::get_parameter_reference; using parameters::choose_parameter; + // using OVPM = typename CGAL::GetVertexPointMap::type; OVPM ovpm = choose_parameter(get_parameter(out_np, internal_np::vertex_point), get_property_map(vertex_point, output_mesh)); - typedef typename internal_np::Lookup_named_param_def < - internal_np::visitor_t, - InputNamedParameters, - Wrapping_default_visitor // default - >::reference Visitor; + // + using Visitor = typename internal_np::Lookup_named_param_def< + internal_np::visitor_t, + InputNamedParameters, + Wrapping_default_visitor // default + >::reference; Wrapping_default_visitor default_visitor; Visitor visitor = choose_parameter(get_parameter_reference(in_np, internal_np::visitor), default_visitor); - std::vector no_seeds; - using Seeds = typename internal_np::Lookup_named_param_def< - internal_np::seed_points_t, InputNamedParameters, std::vector >::reference; - Seeds seeds = choose_parameter(get_parameter_reference(in_np, internal_np::seed_points), no_seeds); + // Points used to create initial cavities + m_seeds = choose_parameter(get_parameter_reference(in_np, internal_np::seed_points), Seeds()); + // Whether or not some cells should be reflagged as "inside" after the refinement+carving loop + // as ended, as to ensure that the result is not only combinatorially manifold, but also + // geometrically manifold. + // + // -- Warning -- + // Manifoldness postprocessing will be performed even if the wrapping is interrupted (and + // this option is enabled). const bool do_enforce_manifoldness = choose_parameter(get_parameter(in_np, internal_np::do_enforce_manifoldness), true); + // Whether to keep pockets of "outside" cells that are not connected to the exterior (or to the + // initial cavities, if used). + // + // -- Warning -- + // Pockets of "outside" cells will be purged even if the wrapping is interrupted (and + // this option is enabled). + const bool keep_inner_ccs = choose_parameter(get_parameter(in_np, internal_np::keep_inner_connected_components), false); + + // This parameter enables avoiding recomputing the triangulation from scratch when wrapping + // the same input for multiple values of alpha (and typically the same offset values). + // + // -- Warning -- + // If this is enabled, the 3D triangulation will NOT be re-initialized at launch. + // This means that the triangulation is NOT cleared, even if: + // - you use an alpha value that is greater than what was used in a previous run; you will + // obtain the same result as the last run. + // - you use a different offset value between runs, you might then get points that are not + // on the offset surface corresponding to that corresponding to the latter offset value. + const bool refining = choose_parameter(get_parameter(in_np, internal_np::refine_triangulation), false); + #ifdef CGAL_AW3_TIMER CGAL::Real_timer t; t.start(); @@ -249,76 +311,59 @@ public: visitor.on_alpha_wrapping_begin(*this); - if(!initialize(alpha, offset, seeds)) + if(!initialize(alpha, offset, refining)) return; -#ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP - extract_surface(output_mesh, ovpm, true /*tolerate non manifoldness*/); - CGAL::IO::write_polygon_mesh("initial_cavities.off", output_mesh, - CGAL::parameters::vertex_point_map(ovpm).stream_precision(17)); +#ifdef CGAL_AW3_TIMER + t.stop(); + std::cout << "Initialization took: " << t.time() << " s." << std::endl; + t.reset(); + t.start(); +#endif + +#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("starting_wrap.off", true /*only_boundary_faces*/); #endif alpha_flood_fill(visitor); +#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("flood_filled_wrap.off", true /*only_boundary_faces*/); +#endif + #ifdef CGAL_AW3_TIMER t.stop(); std::cout << "Flood filling took: " << t.time() << " s." << std::endl; + t.reset(); + t.start(); #endif if(do_enforce_manifoldness) { -#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS - std::cout << "> Make manifold..." << std::endl; - - extract_surface(output_mesh, ovpm, true /*tolerate non manifoldness*/); - -#ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP - dump_triangulation_faces("intermediate_dt3.off", false /*only_boundary_faces*/); - IO::write_polygon_mesh("intermediate.off", output_mesh, - CGAL::parameters::vertex_point_map(ovpm).stream_precision(17)); -#endif - - FT base_vol = 0; - if(is_closed(output_mesh)) // might not be due to manifoldness - base_vol = PMP::volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); - else - std::cerr << "Warning: couldn't compute volume before manifoldness fixes (mesh is not closed)" << std::endl; -#endif - -#ifdef CGAL_AW3_TIMER - t.reset(); - t.start(); -#endif - make_manifold(); +#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("manifold_wrap.off", true /*only_boundary_faces*/); +#endif + #ifdef CGAL_AW3_TIMER t.stop(); - std::cout << "\nManifoldness post-processing took: " << t.time() << " s." << std::endl; + std::cout << "Manifoldness post-processing took: " << t.time() << " s." << std::endl; + t.reset(); + t.start(); #endif + } -#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS - if(!is_zero(base_vol)) - { - extract_surface(output_mesh, ovpm, false /*do not tolerate non-manifoldness*/); + if(!keep_inner_ccs) + { + // We could purge *before* manifold enforcement, but making the mesh manifold is + // very cheap in most cases, so it is better to keep the code simpler. + purge_inner_connected_components(); - const FT manifold_vol = PMP::volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); - const FT ratio = manifold_vol / base_vol; - - std::cout << "Volumes post-manifoldness fix:\n" - << "before: " << base_vol << "\n" - << "after: " << manifold_vol << "\n" - << "ratio: " << ratio << std::endl; - if(ratio > 1.1) // more than 10% extra volume - std::cerr << "Warning: large increase of volume after manifoldness resolution" << std::endl; - } -#endif - } // do_enforce_manifoldness - -#ifdef CGAL_AW3_TIMER - t.reset(); - t.start(); +#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("purged_wrap.off", true /*only_boundary_faces*/); #endif + } extract_surface(output_mesh, ovpm, !do_enforce_manifoldness); @@ -331,9 +376,9 @@ public: std::cout << "Alpha wrap vertices: " << vertices(output_mesh).size() << std::endl; std::cout << "Alpha wrap faces: " << faces(output_mesh).size() << std::endl; - #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP - IO::write_polygon_mesh("final.off", output_mesh, CGAL::parameters::stream_precision(17)); - dump_triangulation_faces("final_dt3.off", false /*only_boundary_faces*/); + #ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + IO::write_polygon_mesh("final_wrap.off", output_mesh, CGAL::parameters::stream_precision(17)); + dump_triangulation_faces("final_tr.off", false /*only_boundary_faces*/); #endif #endif @@ -382,6 +427,20 @@ public: return bbox; } +private: + // The distinction between inside boundary and outside boundary is the presence of cells + // being flagged for manifoldness: inside boundary considers those outside, and outside + // boundary considers them inside. + bool is_on_inside_boundary(Cell_handle ch, Cell_handle nh) const + { + return (ch->is_inside() != nh->is_inside()); // one is "inside", the other is not + } + + bool is_on_outside_boundary(Cell_handle ch, Cell_handle nh) const + { + return (ch->is_outside() != nh->is_outside()); // one is "outside", the other is not + } + private: // Adjust the bbox & insert its corners to construct the starting triangulation void insert_bbox_corners() @@ -409,20 +468,20 @@ private: // - Cells whose circumcenter is in the offset volume are inside: this is because // we need to have outside cell circumcenters outside of the volume to ensure // that the refinement point is separated from the existing point set. - bool cavity_cell_outside_tag(const Cell_handle ch) + Cell_label cavity_cell_label(const Cell_handle ch) { CGAL_precondition(!m_tr.is_infinite(ch)); const Tetrahedron_with_outside_info tet(ch, geom_traits()); if(m_oracle.do_intersect(tet)) - return false; + return Cell_label::INSIDE; const Point_3& ch_cc = circumcenter(ch); typename Geom_traits::Construct_ball_3 ball = geom_traits().construct_ball_3_object(); const Ball_3 ch_cc_offset_ball = ball(ch_cc, m_sq_offset); const bool is_cc_in_offset = m_oracle.do_intersect(ch_cc_offset_ball); - return !is_cc_in_offset; + return is_cc_in_offset ? Cell_label::INSIDE : Cell_label::OUTSIDE; } // Create a cavity using seeds rather than starting from the infinity. @@ -461,15 +520,14 @@ private: // // Another way is to simply make faces incident to the seed always traversable, and then // we only have to ensure faces opposite of the seed are traversable (i.e., radius ~= 1.65 * alpha) - template - bool initialize_with_cavities(const SeedRange& seeds) + bool initialize_with_cavities() { #ifdef CGAL_AW3_DEBUG_INITIALIZATION std::cout << "> Dig cavities" << std::endl; - std::cout << seeds.size() << " seed(s)" << std::endl; + std::cout << m_seeds.size() << " seed(s)" << std::endl; #endif - CGAL_precondition(!seeds.empty()); + CGAL_precondition(!m_seeds.empty()); // Get a double value approximating the scaling factors // std::cout << sqrt(3) * sin(2pi / 5) << std::endl; @@ -478,7 +536,7 @@ private: Iso_cuboid_3 bbox = SC2GT()(m_bbox); std::vector seed_vs; - for(const Point_3& seed_p : seeds) + for(const Point_3& seed_p : m_seeds) { #ifdef CGAL_AW3_DEBUG_INITIALIZATION std::cout << "Initialize from seed " << seed_p << std::endl; @@ -504,7 +562,7 @@ private: continue; } - // Mark the seeds and icosahedron vertices as "artificial vertices" such that the facets + // Mark the seeds and icosahedron vertices as "scaffolding" vertices such that the facets // incident to these vertices are always traversable regardless of their circumcenter. // This is done because otherwise some cavities can appear on the mesh: non-traversable facets // with two vertices on the offset, and the third being a deeper inside seed / ico_seed. @@ -573,17 +631,19 @@ private: std::vector inc_cells; inc_cells.reserve(64); m_tr.incident_cells(seed_v, std::back_inserter(inc_cells)); + for(Cell_handle ch : inc_cells) - ch->is_outside() = cavity_cell_outside_tag(ch); + ch->set_label(cavity_cell_label(ch)); } - // Might as well go through the full triangulation since only seeds should have been inserted + // Should be cheap enough to go through the full triangulation as only seeds have been inserted for(Cell_handle ch : m_tr.all_cell_handles()) { - if(!ch->is_outside()) + if(ch->is_inside()) continue; - // When the algorithm starts from a manually dug hole, infinite cells are tagged "inside" + // When the algorithm starts from a manually dug hole, infinite cells are initialized + // as "inside" such that they do not appear on the boundary CGAL_assertion(!m_tr.is_infinite(ch)); for(int i=0; i<4; ++i) @@ -601,7 +661,7 @@ private: return true; } - // tag all infinite cells OUTSIDE and all finite cells INSIDE + // tag all infinite cells "outside" and all finite cells "inside" // init queue with all convex hull facets bool initialize_from_infinity() { @@ -609,20 +669,52 @@ private: { if(m_tr.is_infinite(ch)) { - ch->is_outside() = true; + ch->set_label(Cell_label::OUTSIDE); const int inf_index = ch->index(m_tr.infinite_vertex()); push_facet(std::make_pair(ch, inf_index)); } else { - ch->is_outside() = false; + ch->set_label(Cell_label::INSIDE); } } return true; } -public: + void reset_manifold_labels() + { + // No erase counter increment, or it will mess up with a possibly non-empty queue. + for(Cell_handle ch : m_tr.all_cell_handles()) + if(ch->label() == Cell_label::MANIFOLD) + ch->set_label(Cell_label::OUTSIDE); + } + + // This function is used in the case of resumption of a previous run: m_tr is not cleared, + // and we fill the queue with the new parameters. + bool initialize_from_existing_triangulation() + { +#ifdef CGAL_AW3_DEBUG_INITIALIZATION + std::cout << "Restart from a DT of " << m_tr.number_of_cells() << " cells" << std::endl; +#endif + + for(Cell_handle ch : m_tr.all_cell_handles()) + { + if(ch->is_inside()) + continue; + + for(int i=0; i<4; ++i) + { + if(ch->neighbor(i)->is_inside()) + push_facet(std::make_pair(ch, i)); + + } + } + + return true; + } + +private: // Manifoldness is tolerated while debugging and extracting at intermediate states // Not the preferred way because it uses 3*nv storage template @@ -662,7 +754,6 @@ public: if(cell->tds_data().processed()) continue; - cell->tds_data().mark_processed(); for(int fid=0; fid<4; ++fid) @@ -689,8 +780,6 @@ public: } } - PMP::duplicate_non_manifold_edges_in_polygon_soup(points, faces); - CGAL_assertion(PMP::is_polygon_soup_a_polygon_mesh(faces)); PMP::polygon_soup_to_polygon_mesh(points, faces, output_mesh, CGAL::parameters::default_values(), @@ -708,6 +797,8 @@ public: CGAL_postcondition(is_closed(output_mesh)); PMP::orient_to_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); + + collect_garbage(output_mesh); } template @@ -717,7 +808,7 @@ public: namespace PMP = Polygon_mesh_processing; #ifdef CGAL_AW3_DEBUG - std::cout << "> Extract wrap... ()" << std::endl; + std::cout << "> Extract manifold wrap... ()" << std::endl; #endif CGAL_assertion_code(for(Vertex_handle v : m_tr.finite_vertex_handles())) @@ -725,35 +816,30 @@ public: clear(output_mesh); - // boundary faces to polygon soup std::vector points; std::vector > faces; std::unordered_map vertex_to_id; - std::size_t nv = 0; - for(auto fit=m_tr.finite_facets_begin(), fend=m_tr.finite_facets_end(); fit!=fend; ++fit) + for(auto fit=m_tr.all_facets_begin(), fend=m_tr.all_facets_end(); fit!=fend; ++fit) { Facet f = *fit; if(!f.first->is_outside()) f = m_tr.mirror_facet(f); - const Cell_handle c = f.first; + const Cell_handle ch = f.first; const int s = f.second; - const Cell_handle nh = c->neighbor(s); - if(c->is_outside() == nh->is_outside()) + const Cell_handle nh = ch->neighbor(s); + if(!is_on_outside_boundary(ch, nh)) continue; std::array ids; for(int pos=0; pos<3; ++pos) { - Vertex_handle vh = c->vertex(Triangulation::vertex_triple_index(s, pos)); - auto insertion_res = vertex_to_id.emplace(vh, nv); + Vertex_handle vh = ch->vertex(Triangulation::vertex_triple_index(s, pos)); + auto insertion_res = vertex_to_id.emplace(vh, vertex_to_id.size()); if(insertion_res.second) // successful insertion, never-seen-before vertex - { points.push_back(m_tr.point(vh)); - ++nv; - } ids[pos] = insertion_res.first->second; } @@ -761,12 +847,22 @@ public: faces.emplace_back(std::array{ids[0], ids[1], ids[2]}); } +#ifdef CGAL_AW3_DEBUG + std::cout << "\t" << points.size() << " points" << std::endl; + std::cout << "\t" << faces.size() << " faces" << std::endl; +#endif + if(faces.empty()) + { +#ifdef CGAL_AW3_DEBUG + std::cerr << "Warning: empty wrap?..." << std::endl; +#endif return; + } if(!PMP::is_polygon_soup_a_polygon_mesh(faces)) { - CGAL_warning_msg(false, "Could NOT extract mesh..."); + CGAL_warning_msg(false, "Failed to extract a manifold boundary!"); return; } @@ -777,10 +873,12 @@ public: CGAL_postcondition(!is_empty(output_mesh)); CGAL_postcondition(is_valid_polygon_mesh(output_mesh)); CGAL_postcondition(is_closed(output_mesh)); + CGAL_postcondition(PMP::does_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm))); PMP::orient_to_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); } +public: template void extract_surface(OutputMesh& output_mesh, OVPM ovpm, @@ -886,43 +984,76 @@ private: } private: - enum Facet_queue_status + // A permissive gate is a gate that we can traverse without checking its circumradius + enum class Facet_status { IRRELEVANT = 0, - ARTIFICIAL_FACET, + HAS_INFINITE_NEIGHBOR, // the cell incident to the mirrored facet is infinite (permissive) + SCAFFOLDING, // incident to a SEED or BBOX vertex (permissive) TRAVERSABLE }; + inline const char* get_status_message(const Facet_status status) + { + constexpr std::size_t status_count = 4; + + // Messages corresponding to Error_code list above. Must be kept in sync! + static const char* message[status_count] = { + "Irrelevant facet", + "Facet incident to infinite neighbor", + "Facet with a bbox/seed vertex", + "Traversable facet" + }; + + const std::size_t status_id = static_cast(status); + if(status_id > status_count || status_id < 0) + return "Unknown status"; + else + return message[status_id]; + } + +public: // @speed some decent time may be spent constructing Facet (pairs) for no reason as it's always // just to grab the .first and .second as soon as it's constructed, and not due to API requirements - // e.g. from DT3 - Facet_queue_status facet_status(const Facet& f) const + Facet_status facet_status(const Facet& f) const { CGAL_precondition(!m_tr.is_infinite(f)); #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "facet status: " - << f.first->vertex((f.second + 1)&3)->point() << " " - << f.first->vertex((f.second + 2)&3)->point() << " " - << f.first->vertex((f.second + 3)&3)->point() << std::endl; + << m_tr.point(f.first, Triangulation::vertex_triple_index(f.second, 0)) << " " + << m_tr.point(f.first, Triangulation::vertex_triple_index(f.second, 1)) << " " + << m_tr.point(f.first, Triangulation::vertex_triple_index(f.second, 2)) << std::endl; #endif - // skip if neighbor is OUTSIDE or infinite + // skip if neighbor is "outside" or infinite const Cell_handle ch = f.first; const int id = f.second; + CGAL_precondition(ch->label() == Cell_label::INSIDE || ch->label() == Cell_label::OUTSIDE); + + if(!ch->is_outside()) // "inside" or "manifold" + { +#ifdef CGAL_AW3_DEBUG_FACET_STATUS + std::cout << "Facet is inside" << std::endl; +#endif + return Facet_status::IRRELEVANT; + } + const Cell_handle nh = ch->neighbor(id); + CGAL_precondition(ch->label() == Cell_label::INSIDE || ch->label() == Cell_label::OUTSIDE); + if(m_tr.is_infinite(nh)) - return TRAVERSABLE; + return Facet_status::HAS_INFINITE_NEIGHBOR; if(nh->is_outside()) { #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "Neighbor already outside" << std::endl; #endif - return IRRELEVANT; + return Facet_status::IRRELEVANT; } - // push if facet is connected to artificial vertices + // push if facet is connected to scaffolding vertices for(int i=0; i<3; ++i) { const Vertex_handle vh = ch->vertex(Triangulation::vertex_triple_index(id, i)); @@ -930,9 +1061,9 @@ private: vh->type() == AW3i::Vertex_type:: SEED_VERTEX) { #ifdef CGAL_AW3_DEBUG_FACET_STATUS - std::cout << "artificial facet due to artificial vertex #" << i << std::endl; + std::cout << "Scaffolding facet due to vertex #" << i << std::endl; #endif - return ARTIFICIAL_FACET; + return Facet_status::SCAFFOLDING; } } @@ -942,78 +1073,143 @@ private: #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "traversable" << std::endl; #endif - return TRAVERSABLE; + return Facet_status::TRAVERSABLE; } #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "not traversable" << std::endl; #endif - return IRRELEVANT; + return Facet_status::IRRELEVANT; } +private: bool push_facet(const Facet& f) { CGAL_precondition(f.first->is_outside()); +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE // skip if f is already in queue if(m_queue.contains_with_bounds_check(Gate(f))) return false; +#endif - const Facet_queue_status s = facet_status(f); - if(s == IRRELEVANT) + // @todo could avoid useless facet_status() calls by doing it after the zombie check + // for the unsorted priority queue, but AFAIR, it doesn't save noticeable time (and that + // increases the queue size). + const Facet_status status = facet_status(f); + if(status == Facet_status::IRRELEVANT) return false; - const Cell_handle ch = f.first; - const int id = f.second; - const Point_3& p0 = m_tr.point(ch, (id+1)&3); - const Point_3& p1 = m_tr.point(ch, (id+2)&3); - const Point_3& p2 = m_tr.point(ch, (id+3)&3); +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + const FT sqr = smallest_squared_radius_3(f, m_tr); + const bool is_permissive = (status == Facet_status::HAS_INFINITE_NEIGHBOR || + status == Facet_status::SCAFFOLDING); + m_queue.resize_and_push(Gate(f, sqr, is_permissive)); +#else + m_queue.push(Gate(f, m_tr)); +#endif - // @todo should prob be the real value we compare to alpha instead of squared_radius - const FT sqr = geom_traits().compute_squared_radius_3_object()(p0, p1, p2); - m_queue.resize_and_push(Gate(f, sqr, (s == ARTIFICIAL_FACET))); +#ifdef CGAL_AW3_DEBUG_QUEUE + const Cell_handle ch = f.first; + const int s = f.second; + const Point_3& p0 = m_tr.point(ch, Triangulation::vertex_triple_index(s, 0)); + const Point_3& p1 = m_tr.point(ch, Triangulation::vertex_triple_index(s, 1)); + const Point_3& p2 = m_tr.point(ch, Triangulation::vertex_triple_index(s, 2)); + + static int gid = 0; + std::cout << "Queue insertion #" << gid++ << "\n" + << " ch = " << &*ch << " (" << m_tr.is_infinite(ch) << ") " << "\n" + << "\t" << p0 << "\n\t" << p1 << "\n\t" << p2 << std::endl; + std::cout << " Status: " << get_status_message(status) << std::endl; + #ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + std::cout << " SQR: " << sqr << std::endl; + std::cout << " Permissiveness: " << is_permissive << std::endl; + + CGAL_assertion(is_permissive || sqr >= m_sq_alpha); + #endif // CGAL_AW3_USE_SORTED_PRIORITY_QUEUE +#endif // CGAL_AW3_DEBUG_QUEUE return true; } private: - template bool initialize(const double alpha, const double offset, - const SeedRange& seeds) + const bool refining) { #ifdef CGAL_AW3_DEBUG std::cout << "> Initialize..." << std::endl; - std::cout << "Alpha: " << alpha << std::endl; - std::cout << "Offset: " << offset << std::endl; +#endif + + const bool resuming = refining && (alpha == m_alpha) && (offset == m_offset); + +#ifdef CGAL_AW3_DEBUG + std::cout << "\tAlpha: " << alpha << std::endl; + std::cout << "\tOffset: " << offset << std::endl; + std::cout << "\tRefining? " << refining << std::endl; + std::cout << "\tResuming? " << resuming << std::endl; #endif if(!is_positive(alpha) || !is_positive(offset)) { #ifdef CGAL_AW3_DEBUG - std::cout << "Error: invalid input parameters" << std::endl; + std::cerr << "Error: invalid input parameters: " << alpha << " and" << offset << std::endl; #endif return false; } + if(refining && alpha > m_alpha) + std::cerr << "Warning: refining with an alpha greater than the last iteration's!" << std::endl; + if(refining && offset != m_offset) + std::cerr << "Warning: refining with a different offset value!" << std::endl; + m_alpha = FT(alpha); m_sq_alpha = square(m_alpha); m_offset = FT(offset); m_sq_offset = square(m_offset); - m_tr.clear(); + // Resuming means that we do not need to re-initialize the queue: either we have finished + // and there is nothing to do, or the interruption was due to a user callback in the visitor, + // and we can resume with the current queue + if(resuming) + { +#ifdef CGAL_AW3_DEBUG + std::cout << "Resuming with a queue of size: " << m_queue.size() << std::endl; +#endif + + reset_manifold_labels(); + return true; + } + +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE m_queue.clear(); +#else + m_queue = { }; +#endif - insert_bbox_corners(); + if(refining) + { + // If we are re-using the triangulation, change the label of the extra elements + // that we have added to ensure a manifold result back to external ("manifold" -> "outside") + reset_manifold_labels(); - if(seeds.empty()) - return initialize_from_infinity(); + return initialize_from_existing_triangulation(); + } else - return initialize_with_cavities(seeds); + { + m_tr.clear(); + + insert_bbox_corners(); + + if(m_seeds.empty()) + return initialize_from_infinity(); + else + return initialize_with_cavities(); + } } template - void alpha_flood_fill(Visitor& visitor) + bool alpha_flood_fill(Visitor& visitor) { #ifdef CGAL_AW3_DEBUG std::cout << "> Flood fill..." << std::endl; @@ -1024,33 +1220,47 @@ private: // Explore all finite cells that are reachable from one of the initial outside cells. while(!m_queue.empty()) { + if(!visitor.go_further(*this)) + return false; + #ifdef CGAL_AW3_DEBUG_QUEUE_PP check_queue_sanity(); #endif // const& to something that will be popped, but safe as `ch` && `id` are extracted before the pop const Gate& gate = m_queue.top(); + +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + if(gate.is_zombie()) + { + m_queue.pop(); + continue; + } +#endif + const Facet& f = gate.facet(); CGAL_precondition(!m_tr.is_infinite(f)); const Cell_handle ch = f.first; - const int id = f.second; - const Cell_handle neighbor = ch->neighbor(id); + const int s = f.second; + CGAL_precondition(ch->is_outside()); + + const Cell_handle nh = ch->neighbor(s); + CGAL_precondition(nh->label() == Cell_label::INSIDE || nh->label() == Cell_label::OUTSIDE); #ifdef CGAL_AW3_DEBUG_QUEUE static int fid = 0; std::cout << m_tr.number_of_vertices() << " DT vertices" << std::endl; std::cout << m_queue.size() << " facets in the queue" << std::endl; std::cout << "Face " << fid++ << "\n" - << "c = " << &*ch << " (" << m_tr.is_infinite(ch) << "), n = " << &*neighbor << " (" << m_tr.is_infinite(neighbor) << ")" << "\n" - << m_tr.point(ch, (id+1)&3) << "\n" << m_tr.point(ch, (id+2)&3) << "\n" << m_tr.point(ch, (id+3)&3) << std::endl; - std::cout << "Priority: " << gate.priority() << std::endl; + << "c = " << &*ch << " (" << m_tr.is_infinite(ch) << "), n = " << &*nh << " (" << m_tr.is_infinite(nh) << ")" << "\n" + << m_tr.point(ch, Triangulation::vertex_triple_index(s, 0)) << "\n" + << m_tr.point(ch, Triangulation::vertex_triple_index(s, 1)) << "\n" + << m_tr.point(ch, Triangulation::vertex_triple_index(s, 2)) << std::endl; + std::cout << "Priority: " << gate.priority() << " (sq alpha: " << m_sq_alpha << ")" << std::endl; + std::cout << "Permissiveness: " << gate.is_permissive_facet() << std::endl; #endif - visitor.before_facet_treatment(*this, gate); - - m_queue.pop(); - #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP static int i = 0; std::string step_name = "results/steps/step_" + std::to_string(static_cast(i)) + ".off"; @@ -1059,18 +1269,27 @@ private: std::string face_name = "results/steps/face_" + std::to_string(static_cast(i++)) + ".xyz"; std::ofstream face_out(face_name); face_out.precision(17); - face_out << "3\n" << m_tr.point(ch, (id+1)&3) << "\n" << m_tr.point(ch, (id+2)&3) << "\n" << m_tr.point(ch, (id+3)&3) << std::endl; + face_out << "3\n" << m_tr.point(ch, Triangulation::vertex_triple_index(s, 0)) << "\n" + << m_tr.point(ch, Triangulation::vertex_triple_index(s, 1)) << "\n" + << m_tr.point(ch, Triangulation::vertex_triple_index(s, 2)) << std::endl; face_out.close(); #endif - if(m_tr.is_infinite(neighbor)) + visitor.before_facet_treatment(*this, gate); + + m_queue.pop(); + + if(m_tr.is_infinite(nh)) { - neighbor->is_outside() = true; + nh->set_label(Cell_label::OUTSIDE); +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + nh->increment_erase_counter(); +#endif continue; } Point_3 steiner_point; - if(compute_steiner_point(ch, neighbor, steiner_point)) + if(compute_steiner_point(ch, nh, steiner_point)) { // std::cout << CGAL::abs(CGAL::approximate_sqrt(m_oracle.squared_distance(steiner_point)) - m_offset) // << " vs " << 1e-2 * m_offset << std::endl; @@ -1079,7 +1298,7 @@ private: // locate cells that are going to be destroyed and remove their facet from the queue int li, lj = 0; Locate_type lt; - const Cell_handle conflict_cell = m_tr.locate(steiner_point, lt, li, lj, neighbor); + const Cell_handle conflict_cell = m_tr.locate(steiner_point, lt, li, lj, nh); CGAL_assertion(lt != Triangulation::VERTEX); // Using small vectors like in Triangulation_3 does not bring any runtime improvement @@ -1092,6 +1311,7 @@ private: std::back_inserter(boundary_facets), std::back_inserter(conflict_zone)); +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE // Purge the queue of facets that will be deleted/modified by the Steiner point insertion, // and which might have been gates for(const Cell_handle& cch : conflict_zone) @@ -1110,6 +1330,7 @@ private: if(m_queue.contains_with_bounds_check(Gate(mf))) m_queue.erase(Gate(mf)); } +#endif visitor.before_Steiner_point_insertion(*this, steiner_point); @@ -1124,10 +1345,10 @@ private: std::vector new_cells; new_cells.reserve(32); m_tr.incident_cells(vh, std::back_inserter(new_cells)); - for(const Cell_handle& ch : new_cells) + for(const Cell_handle& new_ch : new_cells) { - // std::cout << "new cell has time stamp " << ch->time_stamp() << std::endl; - ch->is_outside() = m_tr.is_infinite(ch); + // std::cout << "new cell has time stamp " << new_ch->time_stamp() << std::endl; + new_ch->set_label(m_tr.is_infinite(new_ch) ? Cell_label::OUTSIDE : Cell_label::INSIDE); } // Push all new boundary facets to the queue. @@ -1135,34 +1356,37 @@ private: // because we need to handle internal facets, infinite facets, and also more subtle changes // such as a new cell being marked inside which now creates a boundary // with its incident "outside" flagged cell. - for(Cell_handle ch : new_cells) + for(Cell_handle new_ch : new_cells) { for(int i=0; i<4; ++i) { - if(m_tr.is_infinite(ch, i)) + if(m_tr.is_infinite(new_ch, i)) continue; - const Cell_handle nh = ch->neighbor(i); - if(nh->is_outside() == ch->is_outside()) // not on the boundary + const Cell_handle new_nh = new_ch->neighbor(i); + if(new_nh->label() == new_ch->label()) // not on a boundary continue; - const Facet boundary_f = std::make_pair(ch, i); - if(ch->is_outside()) + const Facet boundary_f = std::make_pair(new_ch, i); + if(new_ch->is_outside()) push_facet(boundary_f); else push_facet(m_tr.mirror_facet(boundary_f)); } } } - else + else // no need for a Steiner point, carve through and continue { - // tag neighbor as OUTSIDE - neighbor->is_outside() = true; + nh->set_label(Cell_label::OUTSIDE); +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + nh->increment_erase_counter(); +#endif // for each finite facet of neighbor, push it to the queue - for(int i=0; i<4; ++i) + const int mi = m_tr.mirror_index(ch, s); + for(int i=1; i<4; ++i) { - const Facet neighbor_f = std::make_pair(neighbor, i); + const Facet neighbor_f = std::make_pair(nh, (mi+i)&3); push_facet(neighbor_f); } } @@ -1172,11 +1396,103 @@ private: // Check that no useful facet has been ignored CGAL_postcondition_code(for(auto fit=m_tr.finite_facets_begin(), fend=m_tr.finite_facets_end(); fit!=fend; ++fit) {) - CGAL_postcondition_code( if(fit->first->is_outside() == fit->first->neighbor(fit->second)->is_outside()) continue;) + CGAL_postcondition_code( Cell_handle ch = fit->first; Cell_handle nh = fit->first->neighbor(fit->second); ) + CGAL_postcondition_code( if(ch->label() == nh->label()) continue;) CGAL_postcondition_code( Facet f = *fit;) - CGAL_postcondition_code( if(!fit->first->is_outside()) f = m_tr.mirror_facet(f);) - CGAL_postcondition( facet_status(f) == IRRELEVANT); + CGAL_postcondition_code( if(ch->is_inside()) f = m_tr.mirror_facet(f);) + CGAL_postcondition( facet_status(f) == Facet_status::IRRELEVANT); CGAL_postcondition_code(}) + + return true; + } + + // Any outside cell that isn't reachable from infinity is a cavity that can be discarded. + std::size_t purge_inner_connected_components() + { +#ifdef CGAL_AW3_DEBUG + std::cout << "> Purge inner islands..." << std::endl; + + std::size_t pre_counter = 0; + for(Cell_handle ch : m_tr.all_cell_handles()) + if(ch->is_outside()) + ++pre_counter; + std::cout << pre_counter << " / " << m_tr.all_cell_handles().size() << " (pre purge)" << std::endl; +#endif + + std::size_t label_change_counter = 0; + + std::stack cells_to_visit; + + if(!m_seeds.empty()) + { + for(const Point_3& seed : m_seeds) + { + Locate_type lt; + int li, lj; + Cell_handle ch = m_tr.locate(seed, lt, li, lj); + + if(!ch->is_outside()) + { + std::cerr << "Warning: cell containing seed is not outside?!" << std::endl; + continue; + } + + cells_to_visit.push(ch); + } + } + else // typical flooding from outside + { + cells_to_visit.push(m_tr.infinite_vertex()->cell()); + } + + while(!cells_to_visit.empty()) + { + Cell_handle curr_c = cells_to_visit.top(); + cells_to_visit.pop(); + + CGAL_assertion(curr_c->is_outside()); + + if(curr_c->tds_data().processed()) + continue; + curr_c->tds_data().mark_processed(); + + for(int j=0; j<4; ++j) + { + Cell_handle neigh_c = curr_c->neighbor(j); + if(neigh_c->tds_data().processed() || !neigh_c->is_outside()) + continue; + + cells_to_visit.push(neigh_c); + } + } + + for(Cell_handle ch : m_tr.all_cell_handles()) + { + if(ch->tds_data().is_clear() && ch->is_outside()) + { + ch->set_label(Cell_label::INSIDE); +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + ch->increment_erase_counter(); +#endif + ++label_change_counter; + } + } + + // reset the conflict flags + for(Cell_handle ch : m_tr.all_cell_handles()) + ch->tds_data().clear(); + +#ifdef CGAL_AW3_DEBUG + std::size_t post_counter = 0; + for(Cell_handle ch : m_tr.all_cell_handles()) + if(ch->is_outside()) + ++post_counter; + std::cout << post_counter << " / " << m_tr.all_cell_handles().size() << " (pre purge)" << std::endl; + + std::cout << label_change_counter << " label changes" << std::endl; +#endif + + return label_change_counter; } private: @@ -1190,7 +1506,7 @@ private: inc_cells.reserve(64); m_tr.incident_cells(v, std::back_inserter(inc_cells)); - // Flood one inside and outside CC. + // Flood one inside and outside CC within the cell umbrella of the vertex. // Process both an inside and an outside CC to also detect edge pinching. // If there are still unprocessed afterwards, there is a non-manifoldness issue. // @@ -1204,7 +1520,7 @@ private: if(ic->is_outside()) outside_start = ic; else if(inside_start == Cell_handle()) - inside_start = ic; + inside_start = ic; // can be "inside" or "manifold" } // fully inside / outside @@ -1236,8 +1552,10 @@ private: CGAL_assertion(neigh_c->has_vertex(v)); if(neigh_c->tds_data().processed() || - neigh_c->is_outside() != curr_c->is_outside()) // do not cross the boundary + is_on_outside_boundary(neigh_c, curr_c)) // do not cross the boundary + { continue; + } cells_to_visit.push(neigh_c); } @@ -1330,22 +1648,47 @@ public: // Not the best complexity, but it's very cheap compared to the rest of the algorithm. void make_manifold() { - namespace PMP = Polygon_mesh_processing; +#ifdef CGAL_AW3_DEBUG + std::cout << "> Make manifold..." << std::endl; - // This seems more harmful than useful after the priority queue has been introduced since - // it adds a lot of flat cells into the triangulation, which then get added to the mesh - // during manifoldness fixing. + auto wrap_volume = [&]() + { + FT vol = 0; + for(Cell_handle ch : m_tr.finite_cell_handles()) + if(!ch->is_outside()) + vol += volume(m_tr.point(ch, 0), m_tr.point(ch, 1), m_tr.point(ch, 2), m_tr.point(ch, 3)); + + return vol; + }; + + #ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("carved_tr.off", true /*only_boundary_faces*/); + #endif + + FT base_vol = wrap_volume(); + if(!is_positive(base_vol)) + std::cerr << "Warning: wrap with non-positive volume?" << std::endl; +#endif + + // This ends up more harmful than useful after the priority queue has been introduced since + // it usually results in a lot of flat cells into the triangulation, which then get added + // to the mesh during manifoldness fixing. // remove_bbox_vertices(); std::stack non_manifold_vertices; // @todo sort somehow? for(Vertex_handle v : m_tr.finite_vertex_handles()) { if(is_non_manifold(v)) + { +#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS_PP + std::cout << v->point() << " is non-manifold" << std::endl; +#endif non_manifold_vertices.push(v); + } } // Some lambdas for the comparer - auto has_artificial_vertex = [](Cell_handle c) -> bool + auto has_scaffolding_vertex = [](Cell_handle c) -> bool { for(int i=0; i<4; ++i) { @@ -1359,79 +1702,77 @@ public: return false; }; - auto is_on_boundary = [](Cell_handle c, int i) -> bool - { - return (c->is_outside() != c->neighbor(i)->is_outside()); - }; + // This originally seemed like a good idea, but in the end it can have strong cascading issues, + // whereas some cells with much smaller volume could have solved the non-manifoldness. +// auto is_on_boundary = [](Cell_handle c, int i) -> bool +// { +// return is_on_outside_boundary(c, c->neighbor(i)); +// }; +// +// auto count_boundary_facets = [&](Cell_handle c, Vertex_handle v) -> int +// { +// const int v_index_in_c = c->index(v); +// int boundary_facets = 0; +// for(int i=0; i<3; ++i) // also take into account the opposite facet? +// { +// if(i == v_index_in_c) +// continue; +// +// boundary_facets += is_on_boundary(c, i); +// } +// +// return boundary_facets; +// }; - auto count_boundary_facets = [&](Cell_handle c, Vertex_handle v) -> int - { - const int v_index_in_c = c->index(v); - int boundary_facets = 0; - for(int i=0; i<3; ++i) // also take into account the opposite facet? - { - if(i == v_index_in_c) - continue; - - boundary_facets += is_on_boundary(c, i); - } - - return boundary_facets; - }; - - // longest edge works better + // Experimentally, longest edge works better // auto sq_circumradius = [&](Cell_handle c) -> FT // { // const Point_3& cc = circumcenter(c); // return geom_traits().compute_squared_distance_3_object()(m_tr.point(c, 0), cc); // }; + // The reasoning behind using longest edge rather than volume is that we want to avoid + // spikes (which would have a small volume), and can often happen since we do not spend + // any care on the quality of tetrahedra. auto sq_longest_edge = [&](Cell_handle c) -> FT { return (std::max)({ squared_distance(m_tr.point(c, 0), m_tr.point(c, 1)), squared_distance(m_tr.point(c, 0), m_tr.point(c, 2)), squared_distance(m_tr.point(c, 0), m_tr.point(c, 3)), squared_distance(m_tr.point(c, 1), m_tr.point(c, 2)), - squared_distance(m_tr.point(c, 3), m_tr.point(c, 3)), + squared_distance(m_tr.point(c, 1), m_tr.point(c, 3)), squared_distance(m_tr.point(c, 2), m_tr.point(c, 3)) }); }; -#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS +#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS_PP std::cout << non_manifold_vertices.size() << " initial NMV" << std::endl; #endif while(!non_manifold_vertices.empty()) { -#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS +#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS_PP std::cout << non_manifold_vertices.size() << " NMV in queue" << std::endl; #endif Vertex_handle v = non_manifold_vertices.top(); non_manifold_vertices.pop(); -#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS - std::cout << "·"; -#endif - if(!is_non_manifold(v)) continue; // Prioritize: // - cells without bbox vertices - // - cells that already have a large number of boundary facets // - small cells when equal number of boundary facets - // @todo give topmost priority to cells with > 1 non-manifold vertex? + // + // Note that these are properties that do not depend on the cell labels, and so we only need + // to sort once. However, if a criterion such as the number of incident inside cells were added, + // we would need to sort after each modification of "inside"/"outside" labels. auto comparer = [&](Cell_handle l, Cell_handle r) -> bool { - if(has_artificial_vertex(l)) - return false; - if(has_artificial_vertex(r)) - return true; + CGAL_precondition(!m_tr.is_infinite(l) && !m_tr.is_infinite(r)); - const int l_bf_count = count_boundary_facets(l, v); - const int r_bf_count = count_boundary_facets(r, v); - if(l_bf_count != r_bf_count) - return l_bf_count > r_bf_count; + if(has_scaffolding_vertex(l) != has_scaffolding_vertex(r)) + return has_scaffolding_vertex(r); return sq_longest_edge(l) < sq_longest_edge(r); }; @@ -1440,22 +1781,22 @@ public: inc_cells.reserve(64); m_tr.finite_incident_cells(v, std::back_inserter(inc_cells)); -#define CGAL_AW3_USE_BRUTE_FORCE_MUTABLE_PRIORITY_QUEUE -#ifndef CGAL_AW3_USE_BRUTE_FORCE_MUTABLE_PRIORITY_QUEUE - std::sort(inc_cells.begin(), inc_cells.end(), comparer); // sort once -#endif + std::vector finite_outside_inc_cells; + finite_outside_inc_cells.reserve(64); + std::copy_if(inc_cells.begin(), inc_cells.end(), std::back_inserter(finite_outside_inc_cells), + [&](Cell_handle c) -> bool { return !m_tr.is_infinite(c) && c->is_outside(); }); - for(auto cit=inc_cells.begin(), cend=inc_cells.end(); cit!=cend; ++cit) + // 'std::stable_sort' to have determinism without having to write something like: + // if(longest_edge(l) == longest_edge(r)) return ... + // in the comparer. It's almost always a small range, so the extra cost does not matter. + std::stable_sort(finite_outside_inc_cells.begin(), finite_outside_inc_cells.end(), comparer); + + for(Cell_handle ic : finite_outside_inc_cells) { -#ifdef CGAL_AW3_USE_BRUTE_FORCE_MUTABLE_PRIORITY_QUEUE - // sort at every iteration since the number of boundary facets evolves - std::sort(cit, cend, comparer); -#endif - Cell_handle ic = *cit; - CGAL_assertion(!m_tr.is_infinite(ic)); + CGAL_assertion(!m_tr.is_infinite(ic) && ic->is_outside()); // This is where new material is added - ic->is_outside() = false; + ic->set_label(Cell_label::MANIFOLD); #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP static int i = 0; @@ -1470,6 +1811,8 @@ public: CGAL_assertion(!is_non_manifold(v)); + // Check if the new material has not created a non-manifold configuration. + // @speed this could be done on only the vertices of cells whose labels have changed. std::vector adj_vertices; adj_vertices.reserve(64); m_tr.finite_adjacent_vertices(v, std::back_inserter(adj_vertices)); @@ -1481,12 +1824,34 @@ public: CGAL_assertion_code(for(Vertex_handle v : m_tr.finite_vertex_handles())) CGAL_assertion(!is_non_manifold(v)); + +#ifdef CGAL_AW3_DEBUG + std::size_t nm_cells_counter = 0; + for(Cell_handle ch : m_tr.all_cell_handles()) + if(ch->label() == Cell_label::MANIFOLD) + ++nm_cells_counter; + std::cout << "Number of added cells: " << nm_cells_counter << std::endl; + + if(!is_zero(base_vol)) + { + const FT manifold_vol = wrap_volume(); + const FT ratio = manifold_vol / base_vol; + + std::cout << "Volumes post-manifoldness fix:\n" + << "before: " << base_vol << "\n" + << "after: " << manifold_vol << "\n" + << "ratio: " << ratio << std::endl; + if(ratio > 1.1) // more than 10% extra volume + std::cerr << "Warning: large increase of volume after manifoldness resolution" << std::endl; + } +#endif } private: void check_queue_sanity() { - std::cout << "Check queue sanity..." << std::endl; + std::cout << "\t~~~ Check queue sanity ~~~" << std::endl; + std::vector queue_gates; Gate previous_top_gate = m_queue.top(); while(!m_queue.empty()) @@ -1496,24 +1861,31 @@ private: const Facet& current_f = current_gate.facet(); const Cell_handle ch = current_f.first; const int id = current_f.second; - const Point_3& p0 = m_tr.point(ch, (id+1)&3); - const Point_3& p1 = m_tr.point(ch, (id+2)&3); - const Point_3& p2 = m_tr.point(ch, (id+3)&3); - const FT sqr = geom_traits().compute_squared_radius_3_object()(p0, p1, p2); + const Point_3& p0 = m_tr.point(ch, Triangulation::vertex_triple_index(id, 0)); + const Point_3& p1 = m_tr.point(ch, Triangulation::vertex_triple_index(id, 1)); + const Point_3& p2 = m_tr.point(ch, Triangulation::vertex_triple_index(id, 2)); - std::cout << "At Facet with VID " << get(Gate_ID_PM(), current_gate) << std::endl; + std::cout << "Facet with VID " << get(Gate_ID_PM(), current_gate) << "\n"; + std::cout << "\t" << p0 << "\n\t" << p1 << "\n\t" << p2 << "\n"; - if(current_gate.priority() != sqr) - std::cerr << "Error: facet in queue has wrong priority" << std::endl; +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + std::cout << " Permissiveness: " << current_gate.is_permissive_facet() << "\n"; + std::cout << " SQR: " << geom_traits().compute_squared_radius_3_object()(p0, p1, p2) << "\n"; + std::cout << " Priority " << current_gate.priority() << std::endl; if(Less_gate()(current_gate, previous_top_gate)) std::cerr << "Error: current gate has higher priority than the previous top" << std::endl; previous_top_gate = current_gate; +#else + if(current_gate.is_zombie()) + std::cout << "Gate is a zombie!" << std::endl; +#endif m_queue.pop(); } - std::cout << "End sanity check" << std::endl; + + std::cout << "\t~~~ End queue sanity check ~~~" << std::endl; // Rebuild CGAL_assertion(m_queue.empty()); @@ -1536,17 +1908,17 @@ private: for(auto fit=m_tr.finite_facets_begin(), fend=m_tr.finite_facets_end(); fit!=fend; ++fit) { - Cell_handle c = fit->first; + Cell_handle ch = fit->first; int s = fit->second; - Cell_handle nc = c->neighbor(s); - if(only_boundary_faces && (c->is_outside() == nc->is_outside())) + Cell_handle nh = ch->neighbor(s); + if(only_boundary_faces && ch->label() == nh->label()) continue; std::array ids; for(std::size_t pos=0; pos<3; ++pos) { - Vertex_handle v = c->vertex((s+pos+1)&3); + Vertex_handle v = ch->vertex((s+pos+1)&3); auto insertion_res = vertex_to_id.emplace(v, nv); if(insertion_res.second) { diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h index db1df61c8f6..efaeb82d330 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h @@ -20,18 +20,26 @@ namespace CGAL { namespace Alpha_wraps_3 { namespace internal { +enum class Cell_label +{ + // Cells that have been carved + OUTSIDE, + // Cells that have not yet been carved + INSIDE, + // OUTSIDE cells that have been labeled "inside" again as to make the result manifold + MANIFOLD +}; + template < typename GT, typename Cb = CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3 > class Alpha_wrap_triangulation_cell_base_3 : public Cb { -private: - bool outside = false; - public: typedef typename Cb::Vertex_handle Vertex_handle; typedef typename Cb::Cell_handle Cell_handle; +public: template < typename TDS2 > struct Rebind_TDS { @@ -39,6 +47,14 @@ public: using Other = Alpha_wrap_triangulation_cell_base_3; }; +private: + Cell_label m_label = Cell_label::INSIDE; + +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + unsigned int m_erase_counter; +#endif + +public: Alpha_wrap_triangulation_cell_base_3() : Cb() {} @@ -55,8 +71,26 @@ public: : Cb(v0, v1, v2, v3, n0, n1, n2, n3) {} - bool is_outside() const { return outside; } - bool& is_outside() { return outside; } +public: + Cell_label label() const { return m_label; } + void set_label(const Cell_label label) { m_label = label; } + bool is_inside() const { return m_label == Cell_label::INSIDE; } + bool is_outside() const { return m_label == Cell_label::OUTSIDE; } + +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + unsigned int erase_counter() const + { + return m_erase_counter; + } + void set_erase_counter(unsigned int c) + { + m_erase_counter = c; + } + void increment_erase_counter() + { + ++m_erase_counter; + } +#endif }; template diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h index 85bd11c00b6..7f3534a484c 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h @@ -321,7 +321,6 @@ public: typename AABB_tree::Bounding_box bbox() const { CGAL_precondition(!empty()); - return tree().bbox(); } diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h index 7bad2ff313d..33f8a52b178 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace CGAL { @@ -41,6 +42,7 @@ struct PS_oracle_traits using Geom_traits = Alpha_wrap_AABB_geom_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 using Points = std::vector; + using Points_ptr = std::shared_ptr; using PR_iterator = typename Points::const_iterator; using Primitive = AABB_primitive; private: - Points m_points; + Points_ptr m_points_ptr; public: // Constructors - Point_set_oracle() - : Oracle_base(BaseOracle(), Base_GT()) - { } - Point_set_oracle(const BaseOracle& base_oracle, const Base_GT& gt = Base_GT()) : Oracle_base(base_oracle, gt) - { } + { + m_points_ptr = std::make_shared(); + } Point_set_oracle(const Base_GT& gt, const BaseOracle& base_oracle = BaseOracle()) - : Oracle_base(base_oracle, gt) + : Point_set_oracle(base_oracle, gt) + { } + + Point_set_oracle() + : Point_set_oracle(BaseOracle(), Base_GT()) { } public: @@ -101,21 +106,27 @@ public: if(points.empty()) { #ifdef CGAL_AW3_DEBUG - std::cout << "Warning: Input is empty " << std::endl; + std::cout << "Warning: Input is empty (PS)" << std::endl; #endif return; } - const std::size_t old_size = m_points.size(); - m_points.insert(std::cend(m_points), std::cbegin(points), std::cend(points)); + const std::size_t old_size = m_points_ptr->size(); + m_points_ptr->insert(std::cend(*m_points_ptr), std::cbegin(points), std::cend(points)); #ifdef CGAL_AW3_DEBUG std::cout << "Insert into AABB tree (points)..." << std::endl; #endif - this->tree().insert(std::next(std::cbegin(m_points), old_size), std::cend(m_points)); + this->tree().insert(std::next(std::cbegin(*m_points_ptr), old_size), std::cend(*m_points_ptr)); - CGAL_postcondition(this->tree().size() == m_points.size()); + // Manually constructing it here purely for profiling reasons: if we keep the lazy approach, + // it will be done at the first treatment of a facet that needs a Steiner point. + // So if one wanted to bench the flood fill runtime, it would be skewed by the time it takes + // to accelerate the tree. + this->tree().accelerate_distance_queries(); + + CGAL_postcondition(this->tree().size() == m_points_ptr->size()); } }; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h index d02a9f9faaf..349cd012ef7 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace CGAL { @@ -40,7 +41,9 @@ struct SS_oracle_traits { using Geom_traits = Alpha_wrap_AABB_geom_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 - using Segments = std::vector; + using Segment = typename GT_::Segment_3; + using Segments = std::vector; + using Segments_ptr = std::shared_ptr; using SR_iterator = typename Segments::const_iterator; using Primitive = AABB_primitive; private: - Segments m_segments; + Segments_ptr m_segments_ptr; public: // Constructors - Segment_soup_oracle() - : Oracle_base(BaseOracle(), Base_GT()) - { } - Segment_soup_oracle(const BaseOracle& base_oracle, const Base_GT& gt = Base_GT()) : Oracle_base(base_oracle, gt) - { } + { + m_segments_ptr = std::make_shared(); + } Segment_soup_oracle(const Base_GT& gt, const BaseOracle& base_oracle = BaseOracle()) - : Oracle_base(base_oracle, gt) + : Segment_soup_oracle(base_oracle, gt) + { } + + Segment_soup_oracle() + : Segment_soup_oracle(BaseOracle(), Base_GT()) { } public: @@ -100,20 +107,40 @@ public: if(segments.empty()) { #ifdef CGAL_AW3_DEBUG - std::cout << "Warning: Input is empty " << std::endl; + std::cout << "Warning: Input is empty (SS)" << std::endl; #endif return; } - const std::size_t old_size = m_segments.size(); - m_segments.insert(std::cend(m_segments), std::cbegin(segments), std::cend(segments)); + typename Geom_traits::Is_degenerate_3 is_degenerate = this->geom_traits().is_degenerate_3_object(); + + const std::size_t old_size = m_segments_ptr->size(); + + for(const Segment& s : segments) + { + if(is_degenerate(s)) + { +#ifdef CGAL_AW3_DEBUG + std::cerr << "Warning: ignoring degenerate segment " << s << std::endl; +#endif + continue; + } + + m_segments_ptr->push_back(s); + } #ifdef CGAL_AW3_DEBUG std::cout << "Insert into AABB tree (segments)..." << std::endl; #endif - this->tree().insert(std::next(std::cbegin(m_segments), old_size), std::cend(m_segments)); + this->tree().insert(std::next(std::cbegin(*m_segments_ptr), old_size), std::cend(*m_segments_ptr)); - CGAL_postcondition(this->tree().size() == m_segments.size()); + // Manually constructing it here purely for profiling reasons: if we keep the lazy approach, + // it will be done at the first treatment of a facet that needs a Steiner point. + // So if one wanted to bench the flood fill runtime, it would be skewed by the time it takes + // to accelerate the tree. + this->tree().accelerate_distance_queries(); + + CGAL_postcondition(this->tree().size() == m_segments_ptr->size()); } }; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h index c87f82ac75f..d7f325e1428 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h @@ -135,7 +135,7 @@ public: if(is_empty(tmesh)) { #ifdef CGAL_AW3_DEBUG - std::cout << "Warning: Input is empty " << std::endl; + std::cout << "Warning: Input is empty (TM)" << std::endl; #endif return; } @@ -153,7 +153,12 @@ public: for(face_descriptor f : faces(tmesh)) { if(Polygon_mesh_processing::is_degenerate_triangle_face(f, tmesh, np)) + { +#ifdef CGAL_AW3_DEBUG + std::cerr << "Warning: ignoring degenerate face " << f << std::endl; +#endif continue; + } const Point_ref p0 = get(vpm, source(halfedge(f, tmesh), tmesh)); const Point_ref p1 = get(vpm, target(halfedge(f, tmesh), tmesh)); @@ -164,6 +169,12 @@ public: Splitter_base::split_and_insert_datum(tr, this->tree(), this->geom_traits()); } + // Manually constructing it here purely for profiling reasons: if we keep the lazy approach, + // it will be done at the first treatment of a facet that needs a Steiner point. + // So if one wanted to bench the flood fill runtime, it would be skewed by the time it takes + // to accelerate the tree. + this->tree().accelerate_distance_queries(); + #ifdef CGAL_AW3_DEBUG std::cout << "Tree: " << this->tree().size() << " primitives (" << num_faces(tmesh) << " faces in input)" << std::endl; #endif diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h index 0a8f589fc2d..dadfb5d8be1 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h @@ -133,7 +133,7 @@ public: if(points.empty() || faces.empty()) { #ifdef CGAL_AW3_DEBUG - std::cout << "Warning: Input is empty " << std::endl; + std::cout << "Warning: Input is empty (TS)" << std::endl; #endif return; } @@ -164,11 +164,22 @@ public: const Triangle_3 tr = triangle(p0, p1, p2); if(is_degenerate(tr)) + { +#ifdef CGAL_AW3_DEBUG + std::cerr << "Warning: ignoring degenerate face " << tr << std::endl; +#endif continue; + } Splitter_base::split_and_insert_datum(tr, this->tree(), this->geom_traits()); } + // Manually constructing it here purely for profiling reasons: if we keep the lazy approach, + // it will be done at the first treatment of a facet that needs a Steiner point. + // So if one wanted to bench the flood fill runtime, it would be skewed by the time it takes + // to accelerate the tree. + this->tree().accelerate_distance_queries(); + #ifdef CGAL_AW3_DEBUG std::cout << "Tree: " << this->tree().size() << " primitives (" << faces.size() << " faces in input)" << std::endl; #endif @@ -179,12 +190,31 @@ public: void add_triangle_soup(const TriangleRange& triangles, const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values()) { + if(triangles.empty()) + { +#ifdef CGAL_AW3_DEBUG + std::cout << "Warning: Input is empty (TS)" << std::endl; +#endif + return; + } + +#ifdef CGAL_AW3_DEBUG + std::cout << "Insert into AABB Tree (triangles)..." << std::endl; +#endif + typename Geom_traits::Is_degenerate_3 is_degenerate = this->geom_traits().is_degenerate_3_object(); + Splitter_base::reserve(triangles.size()); + for(const Triangle_3& tr : triangles) { if(is_degenerate(tr)) + { +#ifdef CGAL_AW3_DEBUG + std::cerr << "Warning: ignoring degenerate triangle " << tr << std::endl; +#endif continue; + } Splitter_base::split_and_insert_datum(tr, this->tree(), this->geom_traits()); } diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h index 8d63e34c9e3..ec48b4f458b 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h @@ -27,27 +27,29 @@ namespace CGAL { namespace Alpha_wraps_3 { namespace internal { +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + // Represents an alpha-traversable facet in the mutable priority queue -template +template class Gate { - using Facet = typename DT3::Facet; - using FT = typename DT3::Geom_traits::FT; + using Facet = typename Tr::Facet; + using FT = typename Tr::Geom_traits::FT; private: Facet m_facet; FT m_priority; // circumsphere sq_radius - bool m_is_artificial_facet; + bool m_is_permissive_facet; public: // Constructors Gate(const Facet& facet, const FT& priority, - const bool is_artificial_facet) + const bool is_permissive_facet) : m_facet(facet), m_priority(priority), - m_is_artificial_facet(is_artificial_facet) + m_is_permissive_facet(is_permissive_facet) { CGAL_assertion(priority >= 0); } @@ -60,34 +62,85 @@ public: public: const Facet& facet() const { return m_facet; } const FT& priority() const { return m_priority; } - bool is_artificial_facet() const { return m_is_artificial_facet; } + bool is_permissive_facet() const { return m_is_permissive_facet; } }; struct Less_gate { - template - bool operator()(const Gate& a, const Gate& b) const + template + bool operator()(const Gate& a, const Gate& b) const { - // @fixme? make it a total order by comparing addresses if both gates are bbox facets - if(a.is_artificial_facet()) - return true; - else if(b.is_artificial_facet()) - return false; + // If one is permissive and the other is not, give priority to the permissive facet. + // + // The permissive facet are given highest priority because they need to be treated + // regardless of their circumradius. Treating them first allow the part that depends + // on alpha to be treated uniformly in a way: whatever the alpha, all permissive faces + // will first be treated. + if(a.is_permissive_facet() != b.is_permissive_facet()) + return a.is_permissive_facet(); + + if(a.priority() == b.priority()) + { + // arbitrary, the sole purpose is to make it a total order for determinism + if(a.facet().first->time_stamp() == b.facet().first->time_stamp()) + return a.facet().second < b.facet().second; + + return a.facet().first->time_stamp() < b.facet().first->time_stamp(); + } + return a.priority() > b.priority(); } }; -template +#else // CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + +// Represents an alpha-traversable facet in the mutable priority queue +template +class Gate +{ + using Facet = typename Tr::Facet; + using FT = typename Tr::Geom_traits::FT; + +private: + Facet m_facet, m_mirror_facet; + const unsigned int m_erase_counter_mem; + const unsigned int m_mirror_erase_counter_mem; + +public: + // Constructors + Gate(const Facet& facet, + const Tr& tr) + : + m_facet(facet), + m_mirror_facet(tr.mirror_facet(facet)), + m_erase_counter_mem(m_facet.first->erase_counter()), + m_mirror_erase_counter_mem(m_mirror_facet.first->erase_counter()) + { + } + +public: + const Facet& facet() const { return m_facet; } + + bool is_zombie() const + { + return (m_facet.first->erase_counter() != m_erase_counter_mem) || + (m_mirror_facet.first->erase_counter() != m_mirror_erase_counter_mem); + } +}; + +#endif // CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + +template struct Gate_ID_PM { - using key_type = Gate; + using key_type = Gate; using value_type = std::size_t; using reference = std::size_t; using category = boost::readable_property_map_tag; inline friend value_type get(Gate_ID_PM, const key_type& k) { - using Facet = typename DT3::Facet; + using Facet = typename Tr::Facet; const Facet& f = k.facet(); return (4 * f.first->time_stamp() + f.second); diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h index d3814d0f3b2..7f5f60de701 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h @@ -40,16 +40,16 @@ struct Orientation_of_circumcenter } }; -template +template bool -less_squared_radius_of_min_empty_sphere(typename Dt::Geom_traits::FT sq_alpha, - const typename Dt::Facet& fh, - const Dt& dt) +less_squared_radius_of_min_empty_sphere(typename Tr::Geom_traits::FT sq_alpha, + const typename Tr::Facet& fh, + const Tr& tr) { - using Cell_handle = typename Dt::Cell_handle; - using Point = typename Dt::Point; + using Cell_handle = typename Tr::Cell_handle; + using Point = typename Tr::Point; - using CK = typename Dt::Geom_traits; + using CK = typename Tr::Geom_traits; using Exact_kernel = typename Exact_kernel_selector::Exact_kernel; using Approximate_kernel = Simple_cartesian; using C2A = Cartesian_converter; @@ -61,21 +61,30 @@ less_squared_radius_of_min_empty_sphere(typename Dt::Geom_traits::FT sq_alpha, Orientation_of_circumcenter orientation_of_circumcenter; +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "Checking for traversability of facet" << std::endl; +#endif + const Cell_handle c = fh.first; const int ic = fh.second; const Cell_handle n = c->neighbor(ic); - const Point& p1 = dt.point(c, Dt::vertex_triple_index(ic,0)); - const Point& p2 = dt.point(c, Dt::vertex_triple_index(ic,1)); - const Point& p3 = dt.point(c, Dt::vertex_triple_index(ic,2)); + const Point& p1 = tr.point(c, Tr::vertex_triple_index(ic,0)); + const Point& p2 = tr.point(c, Tr::vertex_triple_index(ic,1)); + const Point& p3 = tr.point(c, Tr::vertex_triple_index(ic,2)); // This is not actually possible in the context of alpha wrapping, but keeping it for genericity // and because it does not cost anything. - if(dt.is_infinite(n)) + if(tr.is_infinite(n)) { +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cerr << "Warning: computing less_squared_radius_of_min_empty_sphere() with an infinite neighbor?" << std::endl; +#endif + CGAL_assertion(!tr.is_infinite(c)); + Orientation ori = orientation_of_circumcenter(p1, p2, p3, - dt.point(c, 0), dt.point(c, 1), - dt.point(c, 2), dt.point(c, 3)); + tr.point(c, 0), tr.point(c, 1), + tr.point(c, 2), tr.point(c, 3)); if(ori == POSITIVE) { @@ -84,18 +93,22 @@ less_squared_radius_of_min_empty_sphere(typename Dt::Geom_traits::FT sq_alpha, } else { - Comparison_result cr = compare_squared_radius(dt.point(c, 0), dt.point(c, 1), - dt.point(c, 2), dt.point(c, 3), + Comparison_result cr = compare_squared_radius(tr.point(c, 0), tr.point(c, 1), + tr.point(c, 2), tr.point(c, 3), sq_alpha); return cr == LARGER; } } - if(dt.is_infinite(c)) + if(tr.is_infinite(c)) { Orientation ori = orientation_of_circumcenter(p1, p2, p3, - dt.point(n, 0), dt.point(n, 1), - dt.point(n, 2), dt.point(n, 3)); + tr.point(n, 0), tr.point(n, 1), + tr.point(n, 2), tr.point(n, 3)); + +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "Cell 'c' is infinite; Orientation: " << ori << std::endl; +#endif if(ori == NEGATIVE) { @@ -104,8 +117,8 @@ less_squared_radius_of_min_empty_sphere(typename Dt::Geom_traits::FT sq_alpha, } else { - Comparison_result cr = compare_squared_radius(dt.point(n, 0), dt.point(n, 1), - dt.point(n, 2), dt.point(n, 3), + Comparison_result cr = compare_squared_radius(tr.point(n, 0), tr.point(n, 1), + tr.point(n, 2), tr.point(n, 3), sq_alpha); return cr == LARGER; } @@ -113,40 +126,40 @@ less_squared_radius_of_min_empty_sphere(typename Dt::Geom_traits::FT sq_alpha, // both c and n are finite if(orientation_of_circumcenter(p1, p2, p3, - dt.point(c, 0), dt.point(c, 1), dt.point(c, 2), dt.point(c, 3)) != + tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)) != orientation_of_circumcenter(p1, p2, p3, - dt.point(n, 0), dt.point(n, 1), dt.point(n, 2), dt.point(n, 3))) + tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3))) { Comparison_result cr = compare_squared_radius(p1, p2, p3, sq_alpha); #ifdef CGAL_AW3_DEBUG_TRAVERSABILITY std::cout << "dual crosses the face; CR: " - << typename Dt::Geom_traits().compute_squared_radius_3_object()(p1, p2, p3) + << typename Tr::Geom_traits().compute_squared_radius_3_object()(p1, p2, p3) << " sq alpha " << sq_alpha << std::endl; #endif return cr == LARGER; } else { - Comparison_result cr = compare_squared_radius(dt.point(c, 0), dt.point(c, 1), - dt.point(c, 2), dt.point(c, 3), + Comparison_result cr = compare_squared_radius(tr.point(c, 0), tr.point(c, 1), + tr.point(c, 2), tr.point(c, 3), sq_alpha); #ifdef CGAL_AW3_DEBUG_TRAVERSABILITY std::cout << "dual does not cross the face; CR(c): " - << typename Dt::Geom_traits().compute_squared_radius_3_object()(dt.point(c, 0), dt.point(c, 1), - dt.point(c, 2), dt.point(c, 3)) + << typename Tr::Geom_traits().compute_squared_radius_3_object()(tr.point(c, 0), tr.point(c, 1), + tr.point(c, 2), tr.point(c, 3)) << " sq alpha " << sq_alpha << std::endl; #endif if(cr != LARGER) return false; - cr = compare_squared_radius(dt.point(n, 0), dt.point(n, 1), - dt.point(n, 2), dt.point(n, 3), + cr = compare_squared_radius(tr.point(n, 0), tr.point(n, 1), + tr.point(n, 2), tr.point(n, 3), sq_alpha); #ifdef CGAL_AW3_DEBUG_TRAVERSABILITY std::cout << "dual does not cross the face; CR(n): " - << typename Dt::Geom_traits().compute_squared_radius_3_object()(dt.point(n, 0), dt.point(n, 1), - dt.point(n, 2), dt.point(n, 3)) + << typename Tr::Geom_traits().compute_squared_radius_3_object()(tr.point(n, 0), tr.point(n, 1), + tr.point(n, 2), tr.point(n, 3)) << " sq alpha " << sq_alpha << std::endl; #endif @@ -154,6 +167,100 @@ less_squared_radius_of_min_empty_sphere(typename Dt::Geom_traits::FT sq_alpha, } } +template +typename Tr::Geom_traits::FT +smallest_squared_radius_3(const typename Tr::Facet& fh, + const Tr& tr) +{ + using Cell_handle = typename Tr::Cell_handle; + using Point = typename Tr::Point; + using FT = typename Tr::Geom_traits::FT; + + using CK = typename Tr::Geom_traits; + using Exact_kernel = typename Exact_kernel_selector::Exact_kernel; + using Approximate_kernel = Simple_cartesian; + using C2A = Cartesian_converter; + using C2E = typename Exact_kernel_selector::C2E; + + using Orientation_of_circumcenter = Filtered_predicate, + Orientation_of_circumcenter, + C2E, C2A>; + + Orientation_of_circumcenter orientation_of_circumcenter; + + auto squared_radius = tr.geom_traits().compute_squared_radius_3_object(); + +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "Computing circumradius of facet" << std::endl; +#endif + + CGAL_precondition(!tr.is_infinite(fh)); + + const Cell_handle c = fh.first; + const int ic = fh.second; + const Cell_handle n = c->neighbor(ic); + + const Point& p1 = tr.point(c, Tr::vertex_triple_index(ic,0)); + const Point& p2 = tr.point(c, Tr::vertex_triple_index(ic,1)); + const Point& p3 = tr.point(c, Tr::vertex_triple_index(ic,2)); + + // This is not actually possible in the context of alpha wrapping, but keeping it for genericity + // and because it does not cost anything. + if(tr.is_infinite(n)) + { + CGAL_assertion(!tr.is_infinite(c)); + + Orientation ori = orientation_of_circumcenter(p1, p2, p3, + tr.point(c, 0), tr.point(c, 1), + tr.point(c, 2), tr.point(c, 3)); + if(ori == POSITIVE) + return squared_radius(p1, p2, p3); + else + return squared_radius(tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)); + } + + if(tr.is_infinite(c)) + { + Orientation ori = orientation_of_circumcenter(p1, p2, p3, + tr.point(n, 0), tr.point(n, 1), + tr.point(n, 2), tr.point(n, 3)); + +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "Cell 'c' is infinite; Orientation: " << ori << std::endl; +#endif + + if(ori == NEGATIVE) + return squared_radius(p1, p2, p3); + else + return squared_radius(tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3)); + } + + // both c and n are finite + if(orientation_of_circumcenter(p1, p2, p3, + tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)) != + orientation_of_circumcenter(p1, p2, p3, + tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3))) + { +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "dual crosses the face; CR: " << squared_radius(p1, p2, p3) << std::endl; +#endif + + return squared_radius(p1, p2, p3); + } + else + { + const FT cr = squared_radius(tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)); + const FT cnr = squared_radius(tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3)); + +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "dual does not cross the face; CR(c): " << cr << " CRn: " << cnr << std::endl; +#endif + + return (CGAL::min)(cr, cnr); + } +} + + } // namespace internal } // namespace Alpha_wraps_3 } // namespace CGAL diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/alpha_wrap_validation.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/validation.h similarity index 97% rename from Alpha_wrap_3/test/Alpha_wrap_3/alpha_wrap_validation.h rename to Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/validation.h index c9445c9e9c5..6d9a9191d5f 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/alpha_wrap_validation.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/validation.h @@ -117,7 +117,7 @@ bool has_expected_Hausdorff_distance(const TriangleMesh& wrap, template bool is_valid_wrap(const TriangleMesh& wrap, - const bool check_manifoldness = true, + const bool check_manifoldness, const NamedParameters& np = parameters::default_values()) { namespace PMP = CGAL::Polygon_mesh_processing; @@ -203,6 +203,13 @@ bool is_valid_wrap(const TriangleMesh& wrap, return true; } +template +bool is_valid_wrap(const TriangleMesh& wrap, + const NamedParameters& np = parameters::default_values()) +{ + return is_valid_wrap(wrap, true /*consider manifoldness*/, np); +} + template diff --git a/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h index 638c5fb9fa1..8be78675422 100644 --- a/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h @@ -105,7 +105,7 @@ void alpha_wrap_3(const PointRange& points, using NP_helper = Point_set_processing_3_np_helper; using Geom_traits = typename NP_helper::Geom_traits; using Oracle = Alpha_wraps_3::internal::Triangle_soup_oracle; - using AW3 = Alpha_wraps_3::internal::Alpha_wrap_3; + using AW3 = Alpha_wraps_3::internal::Alpha_wrapper_3; Geom_traits gt = choose_parameter(get_parameter(in_np, internal_np::geom_traits)); @@ -254,7 +254,7 @@ void alpha_wrap_3(const TriangleMesh& tmesh, using Geom_traits = typename GetGeomTraits::type; using Oracle = Alpha_wraps_3::internal::Triangle_mesh_oracle; - using AW3 = Alpha_wraps_3::internal::Alpha_wrap_3; + using AW3 = Alpha_wraps_3::internal::Alpha_wrapper_3; Geom_traits gt = choose_parameter(get_parameter(in_np, internal_np::geom_traits)); @@ -350,7 +350,7 @@ void alpha_wrap_3(const PointRange& points, using NP_helper = Point_set_processing_3_np_helper; using Geom_traits = typename NP_helper::Geom_traits; using Oracle = Alpha_wraps_3::internal::Point_set_oracle; - using AW3 = Alpha_wraps_3::internal::Alpha_wrap_3; + using AW3 = Alpha_wraps_3::internal::Alpha_wrapper_3; Geom_traits gt = choose_parameter(get_parameter(in_np, internal_np::geom_traits)); diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp index d7567bab205..af94eecd25a 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp @@ -1,12 +1,13 @@ #define CGAL_AW3_TIMER #define CGAL_AW3_DEBUG +#define CGAL_AW3_DEBUG_MANIFOLDNESS // #define CGAL_AW3_DEBUG_INITIALIZATION #include #include #include -#include "alpha_wrap_validation.h" +#include #include @@ -27,7 +28,7 @@ void generate_random_seeds(const Oracle& oracle, Seeds& seeds, CGAL::Random& r) { - const auto bbox = CGAL::Alpha_wraps_3::internal::Alpha_wrap_3(oracle).construct_bbox(offset); + const auto bbox = CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3(oracle).construct_bbox(offset); const double sq_offset = CGAL::square(offset); while(seeds.size() < 3) @@ -69,7 +70,7 @@ void alpha_wrap_triangle_mesh(Mesh& input_mesh, Oracle oracle; oracle.add_triangle_mesh(input_mesh); - AW3::internal::Alpha_wrap_3 aw3(oracle); + AW3::internal::Alpha_wrapper_3 aw3(oracle); if(seeds.empty()) generate_random_seeds(oracle, offset, seeds, r); diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp index 638431e3056..954fe6163df 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp @@ -1,11 +1,12 @@ #define CGAL_AW3_TIMER #define CGAL_AW3_DEBUG +#define CGAL_AW3_DEBUG_MANIFOLDNESS //#define CGAL_AW3_DEBUG_STEINER_COMPUTATION //#define CGAL_AW3_DEBUG_INITIALIZATION //#define CGAL_AW3_DEBUG_QUEUE #include -#include "alpha_wrap_validation.h" +#include #include #include diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp index e2abc6f1f12..35a954f17b2 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp @@ -1,10 +1,11 @@ #define CGAL_AW3_TIMER #define CGAL_AW3_DEBUG +#define CGAL_AW3_DEBUG_MANIFOLDNESS #include #include -#include "alpha_wrap_validation.h" +#include #include #include @@ -52,7 +53,7 @@ void alpha_wrap_triangle_soup(Points& pr, // AW3 Oracle oracle; oracle.add_triangle_soup(pr, fr); - AW3::internal::Alpha_wrap_3 aw3(oracle); + AW3::internal::Alpha_wrapper_3 aw3(oracle); Mesh wrap; aw3(alpha, offset, wrap, CGAL::parameters::do_enforce_manifoldness(false)); diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp index 470d48e40d4..6209019a7a4 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp @@ -1,12 +1,12 @@ #define CGAL_AW3_TIMER //#define CGAL_AW3_DEBUG -//#define CGAL_AW3_DEBUG_MANIFOLDNESS +#define CGAL_AW3_DEBUG_MANIFOLDNESS //#define CGAL_AW3_DEBUG_STEINER_COMPUTATION //#define CGAL_AW3_DEBUG_INITIALIZATION //#define CGAL_AW3_DEBUG_QUEUE #include -#include "alpha_wrap_validation.h" +#include #include #include diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_batched_point_location.h b/Arrangement_on_surface_2/include/CGAL/Arr_batched_point_location.h index 42715621e4b..85ba6ccc235 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_batched_point_location.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_batched_point_location.h @@ -26,7 +26,6 @@ #include #include -#include #include namespace CGAL { @@ -120,7 +119,7 @@ locate(const Arrangement_on_surface_2& arr, * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ - typename boost::mpl::if_, const Bgt2&, Bgt2>::type + std::conditional_t, const Bgt2&, Bgt2> ex_traits(*geom_traits); // Define the sweep-line visitor and perform the sweep. diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h index 2951b1983fe..dfa6fb89ffc 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -247,8 +246,8 @@ overlay(const Arrangement_on_surface_2& arr1 * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ - typename boost::mpl::if_, - const Ovl_gt2&, Ovl_gt2>::type + std::conditional_t, + const Ovl_gt2&, Ovl_gt2> ex_traits(*traits_adaptor); Ovl_visitor visitor(&arr1, &arr2, &arr, &ovl_tr); diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h index 91313be6c5d..8f3c78095f4 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -246,14 +245,14 @@ struct Arr_all_sides_not_finite_tag : struct Arr_not_all_sides_not_finite_tag : public virtual Arr_not_all_sides_oblivious_tag {}; -typedef boost::mpl::bool_ Arr_true; -typedef boost::mpl::bool_ Arr_false; +typedef std::true_type Arr_true; +typedef std::false_type Arr_false; template struct Arr_is_side_oblivious { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef boost::mpl::if_ result; + typedef std::bool_constant result; typedef typename result::type type; }; @@ -261,7 +260,7 @@ template struct Arr_is_side_open { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef boost::mpl::if_ result; + typedef std::bool_constant result; typedef typename result::type type; }; @@ -269,15 +268,19 @@ template struct Arr_is_side_identified { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef boost::mpl::if_ result; + typedef std::bool_constant result; typedef typename result::type type; }; +template +inline constexpr bool Arr_is_side_identified_v = + Arr_is_side_identified::type::value; + template struct Arr_is_side_contracted { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef boost::mpl::if_ result; + typedef std::bool_constant result; typedef typename result::type type; }; @@ -285,7 +288,7 @@ template struct Arr_is_side_closed { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef boost::mpl::if_ result; + typedef std::bool_constant result; typedef typename result::type type; }; @@ -307,10 +310,10 @@ struct Arr_all_sides_oblivious_category { /*! Boolean tag that is Arr_all_sides_oblivious_tag if all sides are * oblivious, otherwise Arr_not_all_sides_oblivious_tag */ - typedef typename boost::mpl::if_, - Arr_all_sides_oblivious_tag, - Arr_not_all_sides_oblivious_tag>::type + typedef std::conditional_t result; }; @@ -331,19 +334,19 @@ private: typedef typename Arr_is_side_open::result Bot_ope; typedef typename Arr_is_side_open::result Top_ope; - typedef boost::mpl::not_ Lef_not_ope; - typedef boost::mpl::not_ Rig_not_ope; - typedef boost::mpl::not_ Bot_not_ope; - typedef boost::mpl::not_ Top_not_ope; + static inline constexpr bool lef_not_ope = !Lef_ope::value; + static inline constexpr bool rig_not_ope = !Rig_ope::value; + static inline constexpr bool bot_not_ope = !Bot_ope::value; + static inline constexpr bool top_not_ope = !Top_ope::value; public: /*! Boolean tag that is Arr_all_sides_not_open_tag if all sides are not-open, * otherwise Arr_not_all_sides_not_open_tag */ - typedef typename boost::mpl::if_, - Arr_all_sides_not_open_tag, - Arr_not_all_sides_not_open_tag>::type + typedef std::conditional_t result; }; @@ -374,23 +377,23 @@ private: typedef typename Arr_is_side_open::result Bot_ope; typedef typename Arr_is_side_open::result Top_ope; - typedef boost::mpl::or_ Lef_obl_or_ope; - typedef boost::mpl::or_ Rig_obl_or_ope; - typedef boost::mpl::or_ Bot_obl_or_ope; - typedef boost::mpl::or_ Top_obl_or_ope; + static inline constexpr bool lef_obl_or_ope = Lef_obl::value || Lef_ope::value; + static inline constexpr bool rig_obl_or_ope = Rig_obl::value || Rig_ope::value; + static inline constexpr bool bot_obl_or_ope = Bot_obl::value || Bot_ope::value; + static inline constexpr bool top_obl_or_ope = Top_obl::value || Top_ope::value; - typedef typename boost::mpl::if_, - Arr_all_sides_not_finite_tag, - Arr_not_all_sides_not_finite_tag>::type + typedef std::conditional_t tmp; public: - typedef typename boost::mpl::if_, - Arr_all_sides_oblivious_tag, tmp>::type + typedef std::conditional_t result; }; @@ -404,32 +407,27 @@ struct Arr_sane_identified_tagging { typedef ArrBottomSideCategory Bot_side_cat; typedef ArrTopSideCategory Top_side_cat; - typedef typename Arr_is_side_identified::result Lef_ide; - typedef typename Arr_is_side_identified::result Rig_ide; - typedef typename Arr_is_side_identified::result Bot_ide; - typedef typename Arr_is_side_identified::result Top_ide; + static inline constexpr bool lef_ide = Arr_is_side_identified_v; + static inline constexpr bool rig_ide = Arr_is_side_identified_v; + static inline constexpr bool bot_ide = Arr_is_side_identified_v; + static inline constexpr bool top_ide = Arr_is_side_identified_v; - typedef boost::mpl::and_ LR_ide; - typedef boost::mpl::and_ BT_ide; + static inline constexpr bool lr_ide = lef_ide && rig_ide; + static inline constexpr bool bt_ide = bot_ide && top_ide; - typedef boost::mpl::not_ Lef_not_ide; - typedef boost::mpl::not_ Rig_not_ide; - typedef boost::mpl::not_ Bot_not_ide; - typedef boost::mpl::not_ Top_not_ide; + static inline constexpr bool lr_not_ide = !lef_ide && !rig_ide; - typedef boost::mpl::and_ LR_not_ide; + static inline constexpr bool bt_not_ide = !bot_ide && !top_ide; - typedef boost::mpl::and_ BT_not_ide; + static inline constexpr bool lr_ok = lr_ide || lr_not_ide; + static inline constexpr bool bt_ok = bt_ide || bt_not_ide; - typedef boost::mpl::or_ LR_ok; - typedef boost::mpl::or_ BT_ok; - - /*! Boolean tag that is bool_ if opposite sides are either + /*! Boolean tag that is bool_constant if opposite sides are either * both identified or both not-identified, - * otherwise bool_ + * otherwise bool_constant */ - typedef boost::mpl::and_ result; - static constexpr bool value = result::value; + typedef std::bool_constant result; + static inline constexpr bool value = result::value; }; /*! Checks whether one of two boundary sides are identified @@ -448,10 +446,10 @@ struct Arr_has_identified_sides { typedef typename Arr_is_side_identified::result Side_one_ide; typedef typename Arr_is_side_identified::result Side_two_ide; - /*! Boolean tag that is bool_ if one side is identified, - * otherwise bool_ + /*! Boolean tag that is bool_constant if one side is identified, + * otherwise bool_constant */ - typedef boost::mpl::or_ result; + typedef std::bool_constant result; }; /*! Checks whether one of two boundary sides are contracted @@ -464,10 +462,11 @@ struct Arr_has_contracted_sides_two { typedef typename Arr_is_side_contracted::result Side_one_con; typedef typename Arr_is_side_contracted::result Side_two_con; - /*!\ Boolean tag that is bool_ if one side is identified, - * otherwise bool_ + /*!\ Boolean tag that is bool_constant if one side is identified, + * otherwise bool_constant */ - typedef boost::mpl::or_ result; + typedef std::bool_constant result; }; /*! Checks whether one of two boundary sides are closed @@ -480,10 +479,11 @@ struct Arr_has_closed_sides_two { typedef typename Arr_is_side_closed::result Side_one_clo; typedef typename Arr_is_side_closed::result Side_two_clo; - /*! Boolean tag that is bool_ if one side is identified, - * otherwise bool_ + /*! Boolean tag that is bool_constant if one side is identified, + * otherwise bool_constant */ - typedef boost::mpl::or_ result; + typedef std::bool_constant result; }; /*! Checks whether one of two boundary sides are open @@ -496,10 +496,11 @@ struct Arr_has_open_sides_two { typedef typename Arr_is_side_open::result Side_one_ope; typedef typename Arr_is_side_open::result Side_two_ope; - /*! Boolean tag that is bool_ if one side is identified, - * otherwise bool_ + /*! Boolean tag that is bool_constant if one side is identified, + * otherwise bool_constant */ - typedef boost::mpl::or_ result; + typedef std::bool_constant result; }; /*! Categorizes two boundary sides: @@ -532,11 +533,11 @@ struct Arr_two_sides_category { Is_open; public: - typedef typename boost::mpl::if_::type>::type>::type>::type + typedef std::conditional_t>>> result; }; diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_vertical_decomposition_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_vertical_decomposition_2.h index 75c8f25e0c9..099f44192ee 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_vertical_decomposition_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_vertical_decomposition_2.h @@ -24,7 +24,6 @@ #include #include -#include #include namespace CGAL { @@ -124,7 +123,7 @@ decompose(const Arrangement_on_surface_2& arr, * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ - typename boost::mpl::if_, const Vgt2&, Vgt2>::type + std::conditional_t, const Vgt2&, Vgt2> ex_traits(*geom_traits); // Define the sweep-line visitor and perform the sweep. diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h index e4533596dd2..9bcabf985d6 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h @@ -17,7 +17,6 @@ #include -#include #include #include #include @@ -59,25 +58,22 @@ public: private: - typedef boost::mpl::bool_< true > true_; - typedef boost::mpl::bool_< false > false_; + typedef std::conditional_t< + std::is_same_v< Arr_smaller_implementation_tag, Arr_use_traits_tag >, + std::true_type, std::false_type > Smaller_traits; - typedef boost::mpl::if_< - std::is_same< Arr_smaller_implementation_tag, Arr_use_traits_tag >, - true_, false_ > Smaller_traits; - - typedef boost::mpl::if_< - std::is_same< Arr_larger_implementation_tag, Arr_use_traits_tag >, - true_, false_ > Larger_traits; + typedef std::conditional_t< + std::is_same_v< Arr_larger_implementation_tag, Arr_use_traits_tag >, + std::true_type, std::false_type > Larger_traits; public: //! the result type (if one side asks for traits, then ask traits! //! Or vice versa: If both ask for dummy, then dummy!) - typedef typename boost::mpl::if_< - boost::mpl::or_< Smaller_traits, Larger_traits >, + typedef std::conditional_t< + Smaller_traits::value || Larger_traits::value, Arr_use_traits_tag, - Arr_use_dummy_tag >::type type; + Arr_use_dummy_tag > type; }; diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h index 0f2957d4714..5bc8054c525 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h @@ -23,8 +23,6 @@ #include #include -#include -#include #include #include @@ -66,7 +64,7 @@ namespace Ss2 = Surface_sweep_2; // // error: no matching function for call to `do_intersect(Arrangement_2<>&, // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, -// mpl_::bool_< true>)' +// std::bool_constant< true>)' // template @@ -137,7 +135,7 @@ void insert(Arrangement_on_surface_2& arr, // // error: no matching function for call to `do_intersect(Arrangement_2<>&, // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, -// mpl_::bool_< true>)' +// std::bool_constant< true>)' // // template & arr, * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ - typename boost::mpl::if_, const Cgt2&, Cgt2>::type + std::conditional_t, const Cgt2&, Cgt2> traits(*geom_traits); // Define a surface-sweep instance and perform the sweep: @@ -326,7 +324,7 @@ void insert_empty(Arrangement_on_surface_2& * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ - typename boost::mpl::if_, const Cgt2&, Cgt2>::type + std::conditional_t, const Cgt2&, Cgt2> traits(*geom_traits); // Define a surface-sweep instance and perform the sweep. @@ -379,7 +377,7 @@ void insert_non_empty(Arrangement_on_surface_2, const Igt2&, Igt2>::type + std::conditional_t, const Igt2&, Igt2> traits(*geom_traits); // Create a set of existing as well as new curves and points. @@ -411,7 +409,7 @@ void insert_non_empty(Arrangement_on_surface_2&, // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, -// mpl_::bool_< true>)' +// std::bool_constant< true>)' // template @@ -465,7 +463,7 @@ void insert(Arrangement_on_surface_2& arr, // // error: no matching function for call to `do_intersect(Arrangement_2<>&, // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, -// mpl_::bool_< true>)' +// std::bool_constant< true>)' // template @@ -979,7 +977,7 @@ non_intersecting_insert_non_empty(Arrangement_on_surface_2, const Igt2&, Igt2>::type + std::conditional_t, const Igt2&, Igt2> traits(*geom_traits); // Create a set of existing as well as new curves and points. @@ -1526,7 +1524,7 @@ zone(Arrangement_on_surface_2& arr, // workaround since it didn't compile in FC3_g++-3.4.4 with the error of: // // error: no matching function for call to `do_intersect(Arrangement_on_surface_2<>&, -// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, mpl_::bool_< true>)' +// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, std::bool_constant< true>)' // template @@ -1564,7 +1562,7 @@ do_intersect(Arrangement_on_surface_2& arr, // // error: no matching function for call to // `do_intersect(Arrangement_on_surface_2<>&, -// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, mpl_::bool_< true>)' +// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, std::bool_constant< true>)' // template diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h index 30c8b38b4a0..06052a8f19d 100644 --- a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h @@ -295,7 +295,7 @@ protected: * \param tag The tag used for dispatching. */ void _map_boundary_vertices(Event* event, Vertex_handle v, - boost::mpl::bool_ /* tag */); + std::bool_constant /* tag */); /*! * Update the boundary vertices map. @@ -306,7 +306,7 @@ protected: * \param tag The tag used for dispatching. */ void _map_boundary_vertices(Event* event, Vertex_handle v, - boost::mpl::bool_ /* tag */); + std::bool_constant /* tag */); /*! * Update a newly created vertex using the overlay traits. @@ -319,7 +319,7 @@ protected: * \param tag The tag used for dispatching. */ void _create_vertex(Event* event, Vertex_handle res_v, Subcurve* sc, - boost::mpl::bool_ /* tag */); + std::bool_constant /* tag */); /*! * Update a newly created vertex using the overlay traits. @@ -331,7 +331,7 @@ protected: * \param tag The tag used for dispatching. */ void _create_vertex(Event* event, Vertex_handle res_v, Subcurve* sc, - boost::mpl::bool_ /* tag */); + std::bool_constant /* tag */); /*! * Update a newly created edge using the overlay traits. @@ -922,7 +922,7 @@ _map_halfedge_and_twin(Halfedge_handle he, // template void Arr_overlay_ss_visitor:: -_map_boundary_vertices(Event* event, Vertex_handle v, boost::mpl::bool_) +_map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant) { // Update the red and blue object if the last event on sc is on the boundary. if ((event->parameter_space_in_x() != ARR_INTERIOR) || @@ -960,7 +960,7 @@ _map_boundary_vertices(Event* event, Vertex_handle v, boost::mpl::bool_) template void Arr_overlay_ss_visitor:: _map_boundary_vertices(Event* /* event */, Vertex_handle /* v */, - boost::mpl::bool_) + std::bool_constant) {} /* Notify the overlay traits about a newly created vertex. @@ -974,7 +974,7 @@ void Arr_overlay_ss_visitor:: _create_vertex(Event* event, Vertex_handle new_v, Subcurve* sc, - boost::mpl::bool_) + std::bool_constant) { const Point_2& pt = event->point(); const Cell_handle_red* red_handle = pt.red_cell_handle(); @@ -1011,7 +1011,7 @@ _create_vertex(Event* event, return; } - _create_vertex(event, new_v, sc, boost::mpl::bool_()); + _create_vertex(event, new_v, sc, std::bool_constant()); } /* Notify the overlay traits about a newly created vertex. */ @@ -1020,7 +1020,7 @@ void Arr_overlay_ss_visitor:: _create_vertex(Event* event, Vertex_handle new_v, Subcurve* sc, - boost::mpl::bool_) + std::bool_constant) { const Point_2& pt = event->point(); const Cell_handle_red* red_handle = pt.red_cell_handle(); diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_tags.cpp b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_tags.cpp index 81eae420496..a86325de2af 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_tags.cpp +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_tags.cpp @@ -6,7 +6,6 @@ #include #include -#include struct Traits1 { typedef CGAL::Arr_open_side_tag Left_side_category; diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_traits_dispatching.cpp b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_traits_dispatching.cpp index 5c8e19fa12e..ce17f3b9105 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_traits_dispatching.cpp +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_traits_dispatching.cpp @@ -4,7 +4,6 @@ #include #include -#include int dispatch(CGAL::Arr_use_dummy_tag) { return 0; diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/utils.h b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/utils.h index f49b92f4c01..f4975fb1428 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/utils.h +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/utils.h @@ -55,13 +55,13 @@ private: // This function is invoked for traits classes where at least one // boundary is not oblivious and all boundaries are not identified. bool operator()(const Point_2& p1, const Point_2& p2, - boost::mpl::bool_) const + std::bool_constant) const { return (m_traits.compare_xy_2_object()(p1, p2) == CGAL::SMALLER); } // This function should be invoked for traits classes where at least one // boundary is identified. bool operator()(const Point_2& p1, const Point_2& p2, - boost::mpl::bool_) const + std::bool_constant) const { // Compare in y boundaries: CGAL::Arr_parameter_space ps_y1 = diff --git a/BGL/doc/BGL/Doxyfile.in b/BGL/doc/BGL/Doxyfile.in index 4e5d35a91d2..72d3e79168c 100644 --- a/BGL/doc/BGL/Doxyfile.in +++ b/BGL/doc/BGL/Doxyfile.in @@ -1,7 +1,8 @@ @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - CGAL and the Boost Graph Library" -INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ +INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/IO/polygon_mesh_io.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/iterator.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/helpers.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/generators.h \ diff --git a/BGL/examples/BGL_LCC/distance_lcc.cpp b/BGL/examples/BGL_LCC/distance_lcc.cpp index 9e60c5bfb29..b19f0ab2b38 100644 --- a/BGL/examples/BGL_LCC/distance_lcc.cpp +++ b/BGL/examples/BGL_LCC/distance_lcc.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include // wrapper to suppress a warning diff --git a/BGL/examples/BGL_LCC/incident_vertices_lcc.cpp b/BGL/examples/BGL_LCC/incident_vertices_lcc.cpp index f2b66d46ca0..af02d72a81b 100644 --- a/BGL/examples/BGL_LCC/incident_vertices_lcc.cpp +++ b/BGL/examples/BGL_LCC/incident_vertices_lcc.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/BGL/examples/BGL_LCC/normals_lcc.cpp b/BGL/examples/BGL_LCC/normals_lcc.cpp index da1177a7062..b729b0b4792 100644 --- a/BGL/examples/BGL_LCC/normals_lcc.cpp +++ b/BGL/examples/BGL_LCC/normals_lcc.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include diff --git a/BGL/examples/BGL_LCC/range_lcc.cpp b/BGL/examples/BGL_LCC/range_lcc.cpp index 02a28d869a0..cdf89714c30 100644 --- a/BGL/examples/BGL_LCC/range_lcc.cpp +++ b/BGL/examples/BGL_LCC/range_lcc.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp b/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp index 0bfc0891437..988c0230bae 100644 --- a/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp +++ b/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include diff --git a/BGL/examples/BGL_OpenMesh/TriMesh.cpp b/BGL/examples/BGL_OpenMesh/TriMesh.cpp index 0f30d0c10a5..e474020cc67 100644 --- a/BGL/examples/BGL_OpenMesh/TriMesh.cpp +++ b/BGL/examples/BGL_OpenMesh/TriMesh.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include diff --git a/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp b/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp index 57c96a907d8..1f57a67524f 100644 --- a/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp +++ b/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/BGL/include/CGAL/IO/polygon_mesh_io.h b/BGL/include/CGAL/IO/polygon_mesh_io.h new file mode 100644 index 00000000000..b8b86d45f8f --- /dev/null +++ b/BGL/include/CGAL/IO/polygon_mesh_io.h @@ -0,0 +1,264 @@ +// Copyright (c) 2020 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Maxime Gimeno +// Mael Rouxel-Labbé + +#ifndef CGAL_IO_POLYGON_MESH_IO_H +#define CGAL_IO_POLYGON_MESH_IO_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace CGAL { + +namespace IO { + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Read + +//not for now : some readers will return "ok" despite not managing to read anything +/* +template +bool read_polygon_mesh(std::istream& is, + Graph& g, + const NamedParameters& np = parameters::default_values()) +{ + bool ok = false; + ok = read_OFF(is, g, np, false); + if(ok) + return true; + g.clear(); + is.clear();//reset the error state + is.seekg (0, is.beg); + ok = read_OBJ(is, g, np, false); + if(ok) + return true; + g.clear(); + is.clear(); + is.seekg (0, is.beg); + ok = read_PLY(is, g, np, false); + if(ok) + return true; + g.clear(); + is.clear(); + is.seekg (0, is.beg); + ok = read_STL(is, g, np, false); + if(ok) + return true; + g.clear(); + is.clear(); + is.seekg (0, is.beg); + ok = read_GOCAD(is, g, np, false); + return ok; +} + +*/ + +/*! + * \ingroup PkgBGLIOFct + * + * \brief reads a polygon mesh from a file. + * + * Supported file formats are the following: + * - \ref IOStreamOFF (`.off`) + * - \ref IOStreamOBJ (`.obj`) + * - \ref IOStreamSTL (`.stl`) + * - \ref IOStreamPLY (`.ply`) + * - \ref IOStreamGocad (`.ts`) + * - \ref IOStreamVTK (`.vtp`) + * + * The format is detected from the filename extension (letter case is not important). + * + * The data is expected to represent a 2-manifold (possibly with borders). + * + * \tparam Graph a model of `MutableFaceGraph` + * \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * \param fname the name of the file + * \param g the mesh + * \param np optional \ref bgl_namedparameters "Named Parameters" described below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `g`} + * \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and `%Point_3` as value type} + * \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} + * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` + * must be available in `Graph`.} + * \cgalParamNEnd + * + * \cgalParamNBegin{verbose} + * \cgalParamDescription{whether extra information is printed when an incident occurs during reading} + * \cgalParamType{Boolean} + * \cgalParamDefault{`false`} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + * Other named parameters may be used according to the file extension, see \ref PkgBGLIOFct for an exhaustive list. + * + * \return `true` if reading was successful, `false` otherwise. + * + * \sa \link PMP_IO_grp `CGAL::Polygon_mesh_processing::IO::read_polygon_mesh()`\endlink if the data is not 2-manifold +*/ +template +bool read_polygon_mesh(const std::string& fname, + Graph& g, + const NamedParameters& np = parameters::default_values()) +{ + const bool verbose = parameters::choose_parameter(parameters::get_parameter(np, internal_np::verbose), false); + + const std::string ext = internal::get_file_extension(fname); + if(ext == std::string()) + { + if(verbose) + std::cerr << "Error: cannot read from file without extension" << std::endl; + return false; + } + + if(ext == "obj") + return read_OBJ(fname, g, np); + else if(ext == "off") + return read_OFF(fname, g, np); + else if(ext == "ply") + return read_PLY(fname, g, np); + else if(ext == "stl") + return read_STL(fname, g, np); + else if(ext == "ts") + return read_GOCAD(fname, g, np); +#ifdef CGAL_USE_VTK + else if(ext == "vtp") + return read_VTP(fname, g, np); +#endif + + if(verbose) + { + std::cerr << "Error: unknown input file extension: " << ext << "\n" + << "Please refer to the documentation for the list of supported file formats" << std::endl; + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Write + +/*! + * \ingroup PkgBGLIOFct + * + * \brief writes a polygon mesh in a file. + * + * Supported file formats are the following: + * - \ref IOStreamOFF (`.off`) + * - \ref IOStreamOBJ (`.obj`) + * - \ref IOStreamSTL (`.stl`) + * - \ref IOStreamPLY (`.ply`) + * - \ref IOStreamGocad (`.ts`) + * - \ref IOStreamVTK (`.vtp`) + * + * The format is detected from the filename extension (letter case is not important). + * + * \tparam Graph a model of `FaceListGraph` and `HalfedgeListGraph` + * \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * \param fname the name of the file + * \param g the mesh to be output + * \param np optional \ref bgl_namedparameters "Named Parameters" described below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `g`} + * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and `%Point_3` as value type} + * \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} + * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` + * must be available in `Graph`.} + * \cgalParamNEnd + * + * \cgalParamNBegin{stream_precision} + * \cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream} + * \cgalParamType{int} + * \cgalParamDefault{`6`} + * \cgalParamExtra{This parameter is only meaningful while using \ascii encoding.} + * \cgalParamNEnd + * + * \cgalParamNBegin{use_binary_mode} + * \cgalParamDescription{indicates whether data should be written in binary (`true`) or in \ascii (`false`)} + * \cgalParamType{Boolean} + * \cgalParamDefault{`true`} + * \cgalParamExtra{This parameter is only meaningful for formats that support binary encoding.} + * \cgalParamNEnd + * + * \cgalParamNBegin{verbose} + * \cgalParamDescription{whether extra information is printed when an incident occurs during reading} + * \cgalParamType{Boolean} + * \cgalParamDefault{`false`} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + * Other named parameters may be used according to the file extension, see \ref PkgBGLIOFct for an exhaustive list. + * + * \return `true` if writing was successful, `false` otherwise. + */ +template +bool write_polygon_mesh(const std::string& fname, + Graph& g, + const NamedParameters& np = parameters::default_values()) +{ + const bool verbose = parameters::choose_parameter(parameters::get_parameter(np, internal_np::verbose), false); + + const std::string ext = internal::get_file_extension(fname); + if(ext == std::string()) + { + if(verbose) + std::cerr << "Error: trying to output to file without extension" << std::endl; + return false; + } + + if(ext == "obj") + return write_OBJ(fname, g, np); + else if(ext == "off") + return write_OFF(fname, g, np); + else if(ext == "ply") + return write_PLY(fname, g, np); + else if(ext == "stl") + return write_STL(fname, g, np); + else if(ext == "ts") + return write_GOCAD(fname, g, np); +#ifdef CGAL_USE_VTK + else if(ext == "vtp") + return write_VTP(fname, g, np); +#endif + + if(verbose) + { + std::cerr << "Error: unknown output file extension: " << ext << "\n" + << "Please refer to the documentation for the list of supported file formats" << std::endl; + } + + return false; +} + +} // namespace IO +} // namespace CGAL + +#endif // CGAL_IO_POLYGON_MESH_IO_H diff --git a/BGL/include/CGAL/boost/graph/IO/polygon_mesh_io.h b/BGL/include/CGAL/boost/graph/IO/polygon_mesh_io.h index d60af3c9949..84189cf7373 100644 --- a/BGL/include/CGAL/boost/graph/IO/polygon_mesh_io.h +++ b/BGL/include/CGAL/boost/graph/IO/polygon_mesh_io.h @@ -1,4 +1,4 @@ -// Copyright (c) 2020 GeometryFactory (France). All rights reserved. +// Copyright (c) 2023 GeometryFactory (France). All rights reserved. // // This file is part of CGAL (www.cgal.org) // @@ -6,258 +6,11 @@ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Maxime Gimeno -// Mael Rouxel-Labbé +// Author(s) : Mael Rouxel-Labbé #ifndef CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H #define CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace CGAL { - -namespace IO { - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Read - -//not for now : some readers will return "ok" despite not managing to read anything -/* -template -bool read_polygon_mesh(std::istream& is, - Graph& g, - const NamedParameters& np = parameters::default_values()) -{ - bool ok = false; - ok = read_OFF(is, g, np, false); - if(ok) - return true; - g.clear(); - is.clear();//reset the error state - is.seekg (0, is.beg); - ok = read_OBJ(is, g, np, false); - if(ok) - return true; - g.clear(); - is.clear(); - is.seekg (0, is.beg); - ok = read_PLY(is, g, np, false); - if(ok) - return true; - g.clear(); - is.clear(); - is.seekg (0, is.beg); - ok = read_STL(is, g, np, false); - if(ok) - return true; - g.clear(); - is.clear(); - is.seekg (0, is.beg); - ok = read_GOCAD(is, g, np, false); - return ok; -} - -*/ - -/*! - * \ingroup PkgBGLIOFct - * - * \brief reads a polygon mesh from a file. - * - * Supported file formats are the following: - * - \ref IOStreamOFF (`.off`) - * - \ref IOStreamOBJ (`.obj`) - * - \ref IOStreamSTL (`.stl`) - * - \ref IOStreamPLY (`.ply`) - * - \ref IOStreamGocad (`.ts`) - * - \ref IOStreamVTK (`.vtp`) - * - * The format is detected from the filename extension (letter case is not important). - * - * The data is expected to represent a 2-manifold (possibly with borders). - * - * \tparam Graph a model of `MutableFaceGraph` - * \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" - * - * \param fname the name of the file - * \param g the mesh - * \param np optional \ref bgl_namedparameters "Named Parameters" described below - * - * \cgalNamedParamsBegin - * \cgalParamNBegin{vertex_point_map} - * \cgalParamDescription{a property map associating points to the vertices of `g`} - * \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%vertex_descriptor` - * as key type and `%Point_3` as value type} - * \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} - * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` - * must be available in `Graph`.} - * \cgalParamNEnd - * - * \cgalParamNBegin{verbose} - * \cgalParamDescription{whether extra information is printed when an incident occurs during reading} - * \cgalParamType{Boolean} - * \cgalParamDefault{`false`} - * \cgalParamNEnd - * \cgalNamedParamsEnd - * - * Other named parameters may be used according to the file extension, see \ref PkgBGLIOFct for an exhaustive list. - * - * \return `true` if reading was successful, `false` otherwise. - * - * \sa \link PMP_IO_grp `CGAL::Polygon_mesh_processing::IO::read_polygon_mesh()`\endlink if the data is not 2-manifold -*/ -template -bool read_polygon_mesh(const std::string& fname, - Graph& g, - const NamedParameters& np = parameters::default_values()) -{ - const bool verbose = parameters::choose_parameter(parameters::get_parameter(np, internal_np::verbose), false); - - const std::string ext = internal::get_file_extension(fname); - if(ext == std::string()) - { - if(verbose) - std::cerr << "Error: cannot read from file without extension" << std::endl; - return false; - } - - if(ext == "obj") - return read_OBJ(fname, g, np); - else if(ext == "off") - return read_OFF(fname, g, np); - else if(ext == "ply") - return read_PLY(fname, g, np); - else if(ext == "stl") - return read_STL(fname, g, np); - else if(ext == "ts") - return read_GOCAD(fname, g, np); -#ifdef CGAL_USE_VTK - else if(ext == "vtp") - return read_VTP(fname, g, np); -#endif - - if(verbose) - { - std::cerr << "Error: unknown input file extension: " << ext << "\n" - << "Please refer to the documentation for the list of supported file formats" << std::endl; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Write - -/*! - * \ingroup PkgBGLIOFct - * - * \brief writes a polygon mesh in a file. - * - * Supported file formats are the following: - * - \ref IOStreamOFF (`.off`) - * - \ref IOStreamOBJ (`.obj`) - * - \ref IOStreamSTL (`.stl`) - * - \ref IOStreamPLY (`.ply`) - * - \ref IOStreamGocad (`.ts`) - * - \ref IOStreamVTK (`.vtp`) - * - * The format is detected from the filename extension (letter case is not important). - * - * \tparam Graph a model of `FaceListGraph` and `HalfedgeListGraph` - * \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" - * - * \param fname the name of the file - * \param g the mesh to be output - * \param np optional \ref bgl_namedparameters "Named Parameters" described below - * - * \cgalNamedParamsBegin - * \cgalParamNBegin{vertex_point_map} - * \cgalParamDescription{a property map associating points to the vertices of `g`} - * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` - * as key type and `%Point_3` as value type} - * \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} - * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` - * must be available in `Graph`.} - * \cgalParamNEnd - * - * \cgalParamNBegin{stream_precision} - * \cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream} - * \cgalParamType{int} - * \cgalParamDefault{`6`} - * \cgalParamExtra{This parameter is only meaningful while using \ascii encoding.} - * \cgalParamNEnd - * - * \cgalParamNBegin{use_binary_mode} - * \cgalParamDescription{indicates whether data should be written in binary (`true`) or in \ascii (`false`)} - * \cgalParamType{Boolean} - * \cgalParamDefault{`true`} - * \cgalParamExtra{This parameter is only meaningful for formats that support binary encoding.} - * \cgalParamNEnd - * - * \cgalParamNBegin{verbose} - * \cgalParamDescription{whether extra information is printed when an incident occurs during reading} - * \cgalParamType{Boolean} - * \cgalParamDefault{`false`} - * \cgalParamNEnd - * \cgalNamedParamsEnd - * - * Other named parameters may be used according to the file extension, see \ref PkgBGLIOFct for an exhaustive list. - * - * \return `true` if writing was successful, `false` otherwise. - */ -template -bool write_polygon_mesh(const std::string& fname, - Graph& g, - const NamedParameters& np = parameters::default_values()) -{ - const bool verbose = parameters::choose_parameter(parameters::get_parameter(np, internal_np::verbose), false); - - const std::string ext = internal::get_file_extension(fname); - if(ext == std::string()) - { - if(verbose) - std::cerr << "Error: trying to output to file without extension" << std::endl; - return false; - } - - if(ext == "obj") - return write_OBJ(fname, g, np); - else if(ext == "off") - return write_OFF(fname, g, np); - else if(ext == "ply") - return write_PLY(fname, g, np); - else if(ext == "stl") - return write_STL(fname, g, np); - else if(ext == "ts") - return write_GOCAD(fname, g, np); -#ifdef CGAL_USE_VTK - else if(ext == "vtp") - return write_VTP(fname, g, np); -#endif - - if(verbose) - { - std::cerr << "Error: unknown output file extension: " << ext << "\n" - << "Please refer to the documentation for the list of supported file formats" << std::endl; - } - - return false; -} - -}} // namespace CGAL::IO +#include #endif // CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index 76135fd82a7..43016f9889f 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -953,6 +953,11 @@ void swap_edges(const typename boost::graph_traits::halfedge_descript if (fo2 != nf && halfedge(fo2, g)==oh2) set_halfedge(fo2, oh1, g); } +template +void collect_garbage(Graph&) +{ + // nothing by default +} } //end of internal namespace diff --git a/BGL/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h b/BGL/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h index e726e161a6b..01104c54680 100644 --- a/BGL/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h +++ b/BGL/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h @@ -20,8 +20,6 @@ #include #include -#include - namespace CGAL { // adapted from circulator.h, does not support @@ -45,23 +43,20 @@ public: typedef typename I__traits::iterator_category iterator_category; - typedef typename - boost::mpl::if_c< Prevent_deref - , C - , typename C::value_type - >::type value_type; + typedef std::conditional_t< Prevent_deref + , C + , typename C::value_type> + value_type; typedef typename C::difference_type difference_type; - typedef typename - boost::mpl::if_c< Prevent_deref - , C& - , typename C::reference - >::type reference; - typedef typename - boost::mpl::if_c< Prevent_deref - , C* - , typename C::reference - >::type pointer; + typedef std::conditional_t< Prevent_deref + , C& + , typename C::reference + > reference; + typedef std::conditional_t< Prevent_deref + , C* + , typename C::reference + > pointer; OM_iterator_from_circulator(){} diff --git a/BGL/include/CGAL/boost/graph/internal/initialized_index_maps_helpers.h b/BGL/include/CGAL/boost/graph/internal/initialized_index_maps_helpers.h index 2d85e38d35c..eddefcec7fb 100644 --- a/BGL/include/CGAL/boost/graph/internal/initialized_index_maps_helpers.h +++ b/BGL/include/CGAL/boost/graph/internal/initialized_index_maps_helpers.h @@ -276,8 +276,8 @@ class GetInitializedIndexMap { public: // Check if there is an internal property map; if not, we must a dynamic property map - typedef typename boost::mpl::if_c< - CGAL::graph_has_property::value, Tag, DynamicTag>::type Final_tag; + typedef std::conditional_t< + CGAL::graph_has_property::value, Tag, DynamicTag> Final_tag; typedef typename internal_np::Lookup_named_param_def< PropertyTag, diff --git a/BGL/include/CGAL/boost/graph/named_params_helper.h b/BGL/include/CGAL/boost/graph/named_params_helper.h index 1e0efd6faa6..7dd7edd0887 100644 --- a/BGL/include/CGAL/boost/graph/named_params_helper.h +++ b/BGL/include/CGAL/boost/graph/named_params_helper.h @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -43,14 +42,13 @@ class property_map_selector { public: typedef typename graph_has_property::type Has_internal_pmap; - typedef typename boost::mpl::if_c::type, - typename boost::cgal_no_property::type - >::type type; - typedef typename boost::mpl::if_c::const_type, - typename boost::cgal_no_property::const_type - >::type const_type; + typedef std::conditional_t::type, + typename boost::cgal_no_property::type> type; + typedef std::conditional_t::const_type, + typename boost::cgal_no_property::const_type + > const_type; type get_pmap(const PropertyTag& p, PolygonMesh& pmesh) { @@ -209,10 +207,10 @@ struct GetGeomTraits_impl::value, - typename GetK::Kernel, - Fake_GT>::type type; + typedef std::conditional_t::value, + typename GetK::Kernel, + Fake_GT> type; }; template typedef ValueType value_type; typedef Handle key_type; - typedef typename boost::mpl::if_< std::is_reference, - ValueType&, - ValueType >::type Reference; + typedef std::conditional_t< std::is_reference_v, + ValueType&, + ValueType > Reference; Point_accessor() {} Point_accessor(Point_accessor) {} @@ -172,9 +172,9 @@ struct Is_writable_property_map // property map must define. template struct Is_writable_property_map - : boost::mpl::if_c::reference>::type>::value, - CGAL::Tag_false, CGAL::Tag_true>::type + CGAL::Tag_false, CGAL::Tag_true> { }; } // namespace internal diff --git a/BGL/include/CGAL/boost/graph/properties_OpenMesh.h b/BGL/include/CGAL/boost/graph/properties_OpenMesh.h index 861f5aea98b..f6f56cea7ef 100644 --- a/BGL/include/CGAL/boost/graph/properties_OpenMesh.h +++ b/BGL/include/CGAL/boost/graph/properties_OpenMesh.h @@ -13,7 +13,6 @@ #include #include #include -#include #ifndef OPEN_MESH_CLASS #error OPEN_MESH_CLASS is not defined @@ -29,13 +28,13 @@ namespace CGAL { template class OM_pmap { public: - typedef typename boost::mpl::if_::vertex_descriptor>, - OpenMesh::VPropHandleT, - typename boost::mpl::if_::face_descriptor>, - OpenMesh::FPropHandleT, - typename boost::mpl::if_::halfedge_descriptor>, - OpenMesh::HPropHandleT, - OpenMesh::EPropHandleT >::type>::type>::type H; + typedef std::conditional_t::vertex_descriptor>, + OpenMesh::VPropHandleT, + std::conditional_t::face_descriptor>, + OpenMesh::FPropHandleT, + std::conditional_t::halfedge_descriptor>, + OpenMesh::HPropHandleT, + OpenMesh::EPropHandleT >>> H; typedef boost::lvalue_property_map_tag category; diff --git a/BGL/include/CGAL/boost/graph/property_maps.h b/BGL/include/CGAL/boost/graph/property_maps.h index aab29d9b881..b6973feb65c 100644 --- a/BGL/include/CGAL/boost/graph/property_maps.h +++ b/BGL/include/CGAL/boost/graph/property_maps.h @@ -15,7 +15,6 @@ #include #include -#include namespace CGAL{ diff --git a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h index 48572f24118..9876131f47b 100644 --- a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h +++ b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h @@ -636,12 +636,11 @@ public: template void draw_in_ipe(const iterator begin,const iterator end,const Iso_rectangle_2& bbox,bool make_grp=true,bool deselect_all=false, - std::enable_if_t< boost::mpl::or_< std::is_same::value_type,Point_2> , - boost::mpl::or_< std::is_same::value_type,Segment_2> , - boost::mpl::or_< std::is_same::value_type,Circle_2> , - boost::mpl::or_< std::is_same::value_type,Circular_arc_2> , - std::is_same::value_type,Polygon_2> - > > > >::value + std::enable_if_t< std::is_same_v::value_type,Point_2> || + std::is_same_v::value_type,Segment_2> || + std::is_same_v::value_type,Circle_2> || + std::is_same_v::value_type,Circular_arc_2> || + std::is_same_v::value_type,Polygon_2> >* = nullptr) const { for (iterator it=begin;it!=end;++it) diff --git a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h index 5373b0a3445..3dc51367d33 100644 --- a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h +++ b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h @@ -645,12 +645,11 @@ public: template void draw_in_ipe(const iterator begin,const iterator end,const Iso_rectangle_2& bbox,bool make_grp=true,bool deselect_all=false, - std::enable_if_t< boost::mpl::or_< std::is_same::value_type,Point_2> , - boost::mpl::or_< std::is_same::value_type,Segment_2> , - boost::mpl::or_< std::is_same::value_type,Circle_2> , - boost::mpl::or_< std::is_same::value_type,Circular_arc_2> , - std::is_same::value_type,Polygon_2> - > > > >::value + std::enable_if_t< std::is_same_v::value_type,Point_2> || + std::is_same_v::value_type,Segment_2> || + std::is_same_v::value_type,Circle_2> || + std::is_same_v::value_type,Circular_arc_2> || + std::is_same_v::value_type,Polygon_2> >* = nullptr) const { for (iterator it=begin;it!=end;++it) diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_iterators_base.h b/Combinatorial_map/include/CGAL/Combinatorial_map_iterators_base.h index a50266f7659..555dc554c58 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map_iterators_base.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_iterators_base.h @@ -18,7 +18,6 @@ #include #include -#include #include @@ -68,24 +67,24 @@ namespace CGAL { class CMap_dart_iterator; template < typename Map_,bool Const> - class CMap_dart_iterator: public boost::mpl::if_c< Const, + class CMap_dart_iterator: public std::conditional_t< Const, typename Map_::Dart_container::const_iterator, - typename Map_::Dart_container::iterator>::type + typename Map_::Dart_container::iterator> //public internal::CC_iterator { public: typedef CMap_dart_iterator Self; - typedef typename boost::mpl::if_c< Const, + typedef std::conditional_t< Const, typename Map_::Dart_container::const_iterator, - typename Map_::Dart_container::iterator>::type Base; + typename Map_::Dart_container::iterator> Base; // typedef internal::CC_iterator Base; - typedef typename boost::mpl::if_c< Const, - typename Map_::Dart_const_descriptor, - typename Map_::Dart_descriptor>::type + typedef std::conditional_t< Const, + typename Map_::Dart_const_descriptor, + typename Map_::Dart_descriptor> Dart_descriptor; - typedef typename boost::mpl::if_c< Const, const Map_, Map_>::type Map; + typedef std::conditional_t< Const, const Map_, Map_> Map; typedef std::input_iterator_tag iterator_category; typedef typename Base::value_type value_type; @@ -180,25 +179,24 @@ namespace CGAL { template < typename Map_,bool Const > class CMap_dart_iterator: - /*public boost::mpl::if_c< Const, + /*public std::conditional_t< Const, typename Map_::Dart_container::const_iterator, - typename Map_::Dart_container::iterator>::type*/ + typename Map_::Dart_container::iterator>*/ public internal::CC_iterator_with_index { public: typedef CMap_dart_iterator Self; - /*typedef typename boost::mpl::if_c< Const, + /*typedef std::conditional_t< Const, typename Map_::Dart_container::const_iterator, - typename Map_::Dart_container::iterator>::type Base;*/ + typename Map_::Dart_container::iterator> Base;*/ typedef internal::CC_iterator_with_index Base; - typedef typename boost::mpl::if_c< Const, - typename Map_::Dart_const_descriptor, - typename Map_::Dart_descriptor>::type + typedef std::conditional_t< Const, + typename Map_::Dart_const_descriptor, + typename Map_::Dart_descriptor> Dart_descriptor; - typedef typename boost::mpl::if_c< Const, const Map_, - Map_>::type Map; + typedef std::conditional_t< Const, const Map_, Map_> Map; typedef std::input_iterator_tag iterator_category; typedef typename Base::value_type value_type; diff --git a/Combinatorial_map/include/CGAL/Compact_container_with_index.h b/Combinatorial_map/include/CGAL/Compact_container_with_index.h index d3d67c57a88..dbb9aa8bae6 100644 --- a/Combinatorial_map/include/CGAL/Compact_container_with_index.h +++ b/Combinatorial_map/include/CGAL/Compact_container_with_index.h @@ -861,14 +861,13 @@ namespace internal { typedef typename DSC::value_type value_type; typedef typename DSC::size_type size_type; typedef typename DSC::difference_type difference_type; - typedef typename boost::mpl::if_c< Const, const value_type*, - value_type*>::type pointer; - typedef typename boost::mpl::if_c< Const, const value_type&, - value_type&>::type reference; + typedef std::conditional_t< Const, const value_type*, + value_type*> pointer; + typedef std::conditional_t< Const, const value_type&, + value_type&> reference; typedef std::bidirectional_iterator_tag iterator_category; - typedef typename boost::mpl::if_c< Const, const DSC*, DSC*>::type - cc_pointer; + typedef std::conditional_t< Const, const DSC*, DSC*> cc_pointer; CC_iterator_with_index(): m_ptr_to_cc(nullptr), m_index(0) diff --git a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_3.h b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_3.h index 19ee436cc52..112d91491cc 100644 --- a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_3.h +++ b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_3.h @@ -26,7 +26,9 @@ #include #include // For interior_polyhedron_3 +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER #include +#endif #include #include @@ -227,7 +229,11 @@ namespace CGAL template void halfspace_intersection_3 (PlaneIterator begin, PlaneIterator end, Polyhedron &P, - std::optional::value_type>::Kernel::Point_3> origin = std::nullopt) { + std::optional::value_type>::Kernel::Point_3> origin +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER + = std::nullopt +#endif + ) { // Checks whether the intersection is a polyhedron CGAL_assertion_msg(Convex_hull_3::internal::is_intersection_dim_3(begin, end), "halfspace_intersection_3: intersection not a polyhedron"); @@ -238,8 +244,10 @@ namespace CGAL // if a point inside is not provided find one using linear programming if (!origin) { +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER // find a point inside the intersection origin = halfspace_intersection_interior_point_3(begin, end); +#endif CGAL_assertion_msg(origin!=std::nullopt, "halfspace_intersection_3: problem when determining a point inside the intersection"); if (origin==std::nullopt) diff --git a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h index d8946af7353..df781ade4ee 100644 --- a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h +++ b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h @@ -23,7 +23,9 @@ #include // For interior_polyhedron_3 +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER #include +#endif #include #include @@ -99,7 +101,9 @@ namespace CGAL // if a point inside is not provided find one using linear programming if (!origin) { // find a point inside the intersection +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER origin = halfspace_intersection_interior_point_3(pbegin, pend); +#endif CGAL_assertion_msg(origin!=std::nullopt, "halfspace_intersection_with_constructions_3: problem when determining a point inside the intersection"); if (origin==std::nullopt) @@ -134,7 +138,11 @@ namespace CGAL void halfspace_intersection_with_constructions_3 (PlaneIterator pbegin, PlaneIterator pend, Polyhedron &P, - std::optional::value_type>::Kernel::Point_3> const& origin = std::nullopt) { + std::optional::value_type>::Kernel::Point_3> const& origin +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER + = std::nullopt +#endif + ) { typedef typename Kernel_traits::value_type>::Kernel K; typedef typename K::Point_3 Point_3; typedef typename Convex_hull_3::internal::Default_traits_for_Chull_3::type Traits; diff --git a/Data/data/meshes/regular_tetrahedron.off b/Data/data/meshes/regular_tetrahedron.off new file mode 100644 index 00000000000..08a25ad43b3 --- /dev/null +++ b/Data/data/meshes/regular_tetrahedron.off @@ -0,0 +1,11 @@ +OFF +4 4 0 +-1 0 -0.707107 +1 0 -0.707107 +0 -1 0.707107 +0 1 0.707107 +3 0 1 2 +3 0 3 1 +3 0 2 3 +3 1 3 2 + diff --git a/Documentation/doc/biblio/cgal_manual.bib b/Documentation/doc/biblio/cgal_manual.bib index e16202c69dd..51dfb109004 100644 --- a/Documentation/doc/biblio/cgal_manual.bib +++ b/Documentation/doc/biblio/cgal_manual.bib @@ -778,7 +778,7 @@ Teillaud" , volume = 44 , year = 2011 , pages = "160--168" -, url = "https://theses.hal.science/inria-00560388/" +, url = "https://hal.science/inria-00560388/" , doi = "10.1016/j.comgeo.2010.09.010" } diff --git a/Filtered_kernel/include/CGAL/Lazy_kernel.h b/Filtered_kernel/include/CGAL/Lazy_kernel.h index 911a86debc3..8f43a8a1af1 100644 --- a/Filtered_kernel/include/CGAL/Lazy_kernel.h +++ b/Filtered_kernel/include/CGAL/Lazy_kernel.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -199,9 +198,9 @@ private: boost::mpl::eval_if< std::is_same< typename internal::Lazy_result_type::type, CGAL::Object >, boost::mpl::int_, - boost::mpl::eval_if< boost::mpl::or_< - std::is_same< typename internal::Lazy_result_type::type, CGAL::Bbox_2 >, - std::is_same< typename internal::Lazy_result_type::type, CGAL::Bbox_3 > >, + boost::mpl::eval_if< std::bool_constant< + std::is_same_v< typename internal::Lazy_result_type::type, CGAL::Bbox_2 > || + std::is_same_v< typename internal::Lazy_result_type::type, CGAL::Bbox_3 > >, boost::mpl::int_, boost::mpl::int_ > > >, boost::mpl::int_ >::type {}; diff --git a/Generalized_map/include/CGAL/Generalized_map_iterators_base.h b/Generalized_map/include/CGAL/Generalized_map_iterators_base.h index 034b1600f93..1747f89f354 100644 --- a/Generalized_map/include/CGAL/Generalized_map_iterators_base.h +++ b/Generalized_map/include/CGAL/Generalized_map_iterators_base.h @@ -19,7 +19,6 @@ #include #include #include -#include namespace CGAL { diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/PointH2.h b/Homogeneous_kernel/include/CGAL/Homogeneous/PointH2.h index afb6bff830e..06ff55945fe 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/PointH2.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/PointH2.h @@ -53,8 +53,8 @@ public: template < typename Tx, typename Ty > PointH2(const Tx & x, const Ty & y, - std::enable_if_t< boost::mpl::and_, - std::is_convertible >::value >* = 0) + std::enable_if_t< std::is_convertible_v && + std::is_convertible_v >* = 0) : base(x, y) {} PointH2(const FT& x, const FT& y) diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/PointH3.h b/Homogeneous_kernel/include/CGAL/Homogeneous/PointH3.h index 87da02cabff..f64d5b64c9a 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/PointH3.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/PointH3.h @@ -52,9 +52,9 @@ public: template < typename Tx, typename Ty, typename Tz > PointH3(const Tx & x, const Ty & y, const Tz & z, - std::enable_if_t< boost::mpl::and_< boost::mpl::and_< std::is_convertible, - std::is_convertible >, - std::is_convertible >::value >* = 0) + std::enable_if_t && + std::is_convertible_v && + std::is_convertible_v>* = 0) : base(x, y, z) {} PointH3(const FT& x, const FT& y, const FT& z) diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH2.h b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH2.h index 81cd3107595..92afeec7941 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH2.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH2.h @@ -57,8 +57,8 @@ public: template < typename Tx, typename Ty > VectorH2(const Tx & x, const Ty & y, - std::enable_if_t< boost::mpl::and_, - std::is_convertible >::value >* = 0) + std::enable_if_t && + std::is_convertible_v>* = 0) : base(CGAL::make_array(x, y, RT(1))) {} VectorH2(const FT& x, const FT& y) diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h index 5228d5251ad..aecd718d41a 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h @@ -67,9 +67,9 @@ public: template < typename Tx, typename Ty, typename Tz > VectorH3(const Tx & x, const Ty & y, const Tz & z, - std::enable_if_t< boost::mpl::and_< boost::mpl::and_< std::is_convertible, - std::is_convertible >, - std::is_convertible >::value >* = 0) + std::enable_if_t< std::is_convertible_v && + std::is_convertible_v && + std::is_convertible_v>* = 0) : base(CGAL::make_array(x, y, z, RT(1))) {} VectorH3(const FT& x, const FT& y, const FT& z) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index d1cdeef1bcc..09bde261d24 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -14,7 +14,7 @@ Release date: October 2023 - **Breaking change**: The usage of `boost::shared_ptr` has been replaced by `std::shared_ptr`. Packages affected are 2D Straight Line Skeleton and Shape Detection. - **Breaking change**: The usage of `boost::optional` has been replaced by `std::optional`. Packages affected are 2D Straight Line Skeleton, 3D Fast Intersection and Distance Computation (AABB Tree), and the Kernel intersection. - **Breaking change**: The usage of `boost::variant` has been replaced by `std::variant`. Packages affected are 2D Arrangements, and the Kernel intersection. -- **Breaking chahge**: 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)`. +- **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)`. #### 2D Arrangements @@ -44,6 +44,11 @@ Release date: October 2023 the mean and Gaussian curvatures, as well as the principal curvature and directions. - Added the option to use a variable sizing field for `CGAL::Polygon_mesh_processing::isotropic_remeshing()`, and a sizing function based on a measure of local curvature for adaptive remeshing. +- Added the function `CGAL::Polygon_mesh_processing::refine_mesh_at_isolevel()` that refines a polygon mesh along an isocurve. +- Added the function + `CGAL::Polygon_mesh_processing::autorefine_triangle_soup()` that refines a soup of triangles so that no pair of triangles intersects + in their interiors. Also added, the function `autorefine()` operating directly on a triangle mesh and updating it + using the aforementioned function on a triangle soup. ### [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, diff --git a/Installation/CMakeLists.txt b/Installation/CMakeLists.txt index 744e4fed4ab..1e912131c12 100644 --- a/Installation/CMakeLists.txt +++ b/Installation/CMakeLists.txt @@ -1253,6 +1253,6 @@ if(RUNNING_CGAL_AUTO_TEST OR CGAL_TEST_SUITE) "USING BOOST_VERSION = '${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}'" ) if(Qt6_FOUND) - message(STATUS "USING Qt6_VERSION = '${Qt6Core_VERSION_STRING}'") + message(STATUS "USING Qt6_VERSION = '${Qt6Core_VERSION}'") endif()#Qt6_FOUND endif()#RUNNING_CGAL_AUTO_TEST OR CGAL_TEST_SUITE diff --git a/Installation/include/CGAL/license/Polygon_mesh_processing/autorefinement.h b/Installation/include/CGAL/license/Polygon_mesh_processing/autorefinement.h new file mode 100644 index 00000000000..8f3c9cc5e3f --- /dev/null +++ b/Installation/include/CGAL/license/Polygon_mesh_processing/autorefinement.h @@ -0,0 +1,54 @@ +// Copyright (c) 2016 GeometryFactory SARL (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Andreas Fabri +// +// Warning: this file is generated, see include/CGAL/license/README.md + +#ifndef CGAL_LICENSE_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H +#define CGAL_LICENSE_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H + +#include +#include + +#ifdef CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE + +# if CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE + +# if defined(CGAL_LICENSE_WARNING) + + CGAL_pragma_warning("Your commercial license for CGAL does not cover " + "this release of the Polygon Mesh Processing - Autorefinement package.") +# endif + +# ifdef CGAL_LICENSE_ERROR +# error "Your commercial license for CGAL does not cover this release \ + of the Polygon Mesh Processing - Autorefinement package. \ + You get this error, as you defined CGAL_LICENSE_ERROR." +# endif // CGAL_LICENSE_ERROR + +# endif // CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE + +#else // no CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE + +# if defined(CGAL_LICENSE_WARNING) + CGAL_pragma_warning("\nThe macro CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE is not defined." + "\nYou use the CGAL Polygon Mesh Processing - Autorefinement package under " + "the terms of the GPLv3+.") +# endif // CGAL_LICENSE_WARNING + +# ifdef CGAL_LICENSE_ERROR +# error "The macro CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE is not defined.\ + You use the CGAL Polygon Mesh Processing - Autorefinement package under the terms of \ + the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR." +# endif // CGAL_LICENSE_ERROR + +#endif // no CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE + +#endif // CGAL_LICENSE_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H diff --git a/Installation/include/CGAL/license/Polygon_mesh_processing/interpolated_corrected_curvatures.h b/Installation/include/CGAL/license/Polygon_mesh_processing/interpolated_corrected_curvatures.h index e484daaf5ea..5bf31aaa352 100644 --- a/Installation/include/CGAL/license/Polygon_mesh_processing/interpolated_corrected_curvatures.h +++ b/Installation/include/CGAL/license/Polygon_mesh_processing/interpolated_corrected_curvatures.h @@ -9,10 +9,10 @@ // // Author(s) : Andreas Fabri // -// Warning: this file is generated, see include/CGAL/licence/README.md +// Warning: this file is generated, see include/CGAL/license/README.md -#ifndef CGAL_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H -#define CGAL_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H +#ifndef CGAL_LICENSE_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H +#define CGAL_LICENSE_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H #include #include @@ -51,4 +51,4 @@ #endif // no CGAL_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_COMMERCIAL_LICENSE -#endif // CGAL_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H +#endif // CGAL_LICENSE_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H diff --git a/Installation/include/CGAL/license/SMDS_3.h b/Installation/include/CGAL/license/SMDS_3.h index 4f349c13acf..b4011300b50 100644 --- a/Installation/include/CGAL/license/SMDS_3.h +++ b/Installation/include/CGAL/license/SMDS_3.h @@ -24,12 +24,12 @@ # if defined(CGAL_LICENSE_WARNING) CGAL_pragma_warning("Your commercial license for CGAL does not cover " - "this release of the 3D Mesh Data Structure package.") + "this release of the 3D Simplicial Mesh Data Structure package.") # endif # ifdef CGAL_LICENSE_ERROR # error "Your commercial license for CGAL does not cover this release \ - of the 3D Mesh Data Structure package. \ + of the 3D Simplicial Mesh Data Structure package. \ You get this error, as you defined CGAL_LICENSE_ERROR." # endif // CGAL_LICENSE_ERROR diff --git a/Installation/include/CGAL/license/gpl_package_list.txt b/Installation/include/CGAL/license/gpl_package_list.txt index 41612d5b9fc..fd4eeeb7d65 100644 --- a/Installation/include/CGAL/license/gpl_package_list.txt +++ b/Installation/include/CGAL/license/gpl_package_list.txt @@ -61,6 +61,7 @@ Polygon_mesh_processing/geometric_repair Polygon Mesh Processing - Geometric Rep Polygon_mesh_processing/miscellaneous Polygon Mesh Processing - Miscellaneous Polygon_mesh_processing/detect_features Polygon Mesh Processing - Feature Detection Polygon_mesh_processing/collision_detection Polygon Mesh Processing - Collision Detection +Polygon_mesh_processing/autorefinement Polygon Mesh Processing - Autorefinement Polyhedron 3D Polyhedral Surface Polyline_simplification_2 2D Polyline Simplification Polytope_distance_d Optimal Distances diff --git a/Interpolation/include/CGAL/sibson_gradient_fitting.h b/Interpolation/include/CGAL/sibson_gradient_fitting.h index f08600a4603..f6d6d0559dd 100644 --- a/Interpolation/include/CGAL/sibson_gradient_fitting.h +++ b/Interpolation/include/CGAL/sibson_gradient_fitting.h @@ -23,7 +23,6 @@ #include #include -#include #include #include diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h index b0cc8f3ec22..138d2c9bd45 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h @@ -84,10 +84,13 @@ intersection(const typename K::Plane_3& plane1, typename K::Line_3, typename K::Plane_3> > result_type; - typedef typename K::Point_3 Point_3; typedef typename K::Line_3 Line_3; typedef typename K::Plane_3 Plane_3; + auto res = intersection_point(plane1,plane2,plane3, k); + if (res) + return result_type(*res); + // Intersection between plane1 and plane2 can either be // a line, a plane, or empty. typename Intersection_traits::result_type @@ -97,26 +100,19 @@ intersection(const typename K::Plane_3& plane1, { if(const Line_3* l = intersect_get(o12)) { - // either point or line - typename Intersection_traits::result_type - v = internal::intersection(plane3, *l, k); - if(v) - { - if(const Point_3* p = intersect_get(v)) - return result_type(*p); - else if(const Line_3* l = intersect_get(v)) - return result_type(*l); - } + if (internal::do_intersect(*l, plane3, k)) + return result_type(*l); } - else if(const Plane_3 *pl = intersect_get(o12)) + else { + CGAL_assertion(intersect_get(o12) != nullptr); // either line or plane typename Intersection_traits::result_type - v = internal::intersection(plane3, *pl, k); + v = internal::intersection(plane3, plane1, k); if(v) { - if(const Plane_3* p = intersect_get(v)) - return result_type(*p); + if( intersect_get(v)!=nullptr) + return result_type(plane1); else if(const Line_3* l = intersect_get(v)) return result_type(*l); } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h index 42182e01636..269c86c3e60 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h @@ -14,6 +14,8 @@ #ifndef CGAL_INTERNAL_INTERSECTIONS_TRIANGLE_3_TRIANGLE_3_INTERSECTION_H #define CGAL_INTERNAL_INTERSECTIONS_TRIANGLE_3_TRIANGLE_3_INTERSECTION_H +//#define CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + #include #include #include @@ -21,6 +23,9 @@ #include +#include +#include + #include #include #include @@ -30,53 +35,338 @@ namespace Intersections { namespace internal{ template -void intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p, - const typename Kernel::Point_3& q, - const typename Kernel::Point_3& r, - const Kernel& k, - std::list& inter_pts) +struct Point_on_triangle { - typedef typename std::list::iterator Iterator; + // triangle points are not stored in this class but are expected + // to always be passed in the same order. For a triangle pqr, + // edge 0 is pq, edge 1 qr and edge 2 rp. Point 0 is p, 1 is q and 2 is r. + // + // (id, -1) point on t1 + // (-1, id) point on t2 + // (id1, id2) intersection of edges + std::pair t1_t2_ids; + boost::container::flat_set extra_t1; // store other ids of edges containing the point + typename Kernel::FT alpha; // + +////// + + static + inline + const typename Kernel::Point_3& + point_from_id(const typename Kernel::Point_3& p, + const typename Kernel::Point_3& q, + const typename Kernel::Point_3& r, + int id) + { + switch(id) + { + case 0: + return p; + case 1: + return q; + default: + return r; + } + } + + Point_on_triangle(int i1, int i2=-1, typename Kernel::FT alpha = 0.) // TODO add global zero()? + : t1_t2_ids(i1,i2) + , alpha(alpha) + {} + + // orientation of the current point wrt to edge id1 (p1q1) + Orientation + orientation (const typename Kernel::Point_3& p1, // source of edge edge_id1 + const typename Kernel::Point_3& q1, // target of edge edge_id1 + const typename Kernel::Point_3& r1, + int edge_id1, + const typename Kernel::Point_3& p2, + const typename Kernel::Point_3& q2, + const typename Kernel::Point_3& r2, + const Kernel& k) const + { + if (t1_t2_ids.first!=-1) + { + if (t1_t2_ids.second==-1) + return (edge_id1==t1_t2_ids.first || (edge_id1+1)%3==t1_t2_ids.first) ? ZERO:POSITIVE; // it is a point on t1 + // this is an intersection point + + if (t1_t2_ids.first==edge_id1) + return ZERO; + if (t1_t2_ids.first==(edge_id1+1)%3) + { + if (alpha==0) return ZERO; + return alpha>=0 ? POSITIVE:NEGATIVE; + } + CGAL_assertion((t1_t2_ids.first+1)%3==edge_id1); + if (alpha==1) return ZERO; + return alpha<=1?POSITIVE:NEGATIVE; + } + else + { + //this is an input point of t2 + typename Kernel::Coplanar_orientation_3 orient = k.coplanar_orientation_3_object(); + const typename Kernel::Point_3& query = point_from_id(p2,q2,r2,t1_t2_ids.second); + return orient(p1,q1,r1,query); + } + } + + int id1() const { return t1_t2_ids.first; } + int id2() const { return t1_t2_ids.second; } + + // construct the intersection point from the info stored + typename Kernel::Point_3 + point(const typename Kernel::Point_3& p1, + const typename Kernel::Point_3& q1, + const typename Kernel::Point_3& r1, + const typename Kernel::Point_3& p2, + const typename Kernel::Point_3& q2, + const typename Kernel::Point_3& r2, + const Kernel& k) const + { + if (t1_t2_ids.first==-1) + return point_from_id(p2,q2,r2,t1_t2_ids.second); + if (t1_t2_ids.second==-1) + return point_from_id(p1,q1,r1,t1_t2_ids.first); + + return k.construct_barycenter_3_object()(point_from_id(p1,q1,r1,(t1_t2_ids.first+1)%3), alpha, point_from_id(p1,q1,r1,t1_t2_ids.first)) ; + } +}; + +// the intersection of two triangles is computed by interatively intersection t2 +// with halfspaces defined by edges of t1. The following function is called +// for each each on t1 on edge of the current intersection. +// pq is such an edge and p1q1 from t1 defines the halfspace intersection +// we are currently interseted in. We return the intersection point of +// pq with p1q1 +template +Point_on_triangle +intersection(const Point_on_triangle& p, + const Point_on_triangle& q, + int edge_id_t1, + const typename Kernel::Point_3& p1, + const typename Kernel::Point_3& q1, +// const typename Kernel::Point_3& r1, + const typename Kernel::Point_3& p2, + const typename Kernel::Point_3& q2, + const typename Kernel::Point_3& r2, + const Kernel& k) +{ +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " calling intersection: "; + std::cout << " (" << p.id1() << "," << p.id2() << ",[" << p.alpha << "]) -"; + std::cout << " (" << q.id1() << "," << q.id2() << ",[" << q.alpha << "]) || e" << edge_id_t1; +#endif + typename Kernel::Compute_alpha_for_coplanar_triangle_intersection_3 compute_alpha + = k.compute_alpha_for_coplanar_triangle_intersection_3_object(); + typedef Point_on_triangle Pot; + switch(p.id1()) + { + case -1: + { + switch(q.id1()) + { + case -1: // A: (-1, ip2) - (-1, iq2) + { + CGAL_assertion((p.id2()+1)%3 == q.id2() || (q.id2()+1)%3 == p.id2()); +// CGAL_assertion(p.extra_t1.empty() && q.extra_t1.empty()); // TMP to see if it's worth implementing special case +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 1\n"; +#endif + typename Kernel::FT alpha = compute_alpha(p1, q1, + Pot::point_from_id(p2, q2, r2, p.id2()), + Pot::point_from_id(p2, q2, r2, q.id2())); + int id2 = (p.id2()+1)%3 == q.id2() ? p.id2() : q.id2(); + return Point_on_triangle(edge_id_t1, id2, alpha); // intersection with an original edge of t2 + } + default: + if (q.id2()!=-1) // B: (-1, ip2) - (iq1, iq2) + { + if (p.id2() == q.id2() || p.id2() == (q.id2()+1)%3) + { +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 2\n"; +#endif + // points are on the same edge of t2 --> we shorten an already cut edge + typename Kernel::FT alpha = compute_alpha(p1, q1, + Pot::point_from_id(p2, q2, r2, q.id2()), + Pot::point_from_id(p2, q2, r2, (q.id2()+1)%3)); + + return Point_on_triangle(edge_id_t1, q.id2(), alpha); + } +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 3\n"; +#endif + // point of t1: look for an edge of t1 containing both points + CGAL_assertion( p.extra_t1.count(q.id1())!=0 || p.extra_t1.count(3-q.id1()-edge_id_t1)!=0 ); + int eid1 = p.extra_t1.count(q.id1())!=0 ? q.id1() : 3-q.id1()-edge_id_t1; + return Point_on_triangle((eid1+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3, -1); // vertex of t1 + } + // C: (-1, ip2) - (iq1, -1) + //vertex of t1, special case t1 edge passed thru a vertex of t2 + CGAL_assertion(edge_id_t1 == 2); +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 4\n"; +#endif + CGAL_assertion(q.id1()==1); + CGAL_assertion(!p.extra_t1.empty()); + return Point_on_triangle(p.extra_t1.count(0)==1?0:2,-1); + } + } + default: + { + switch(p.id2()) + { + case -1: + { + switch(q.id1()) + { + case -1: // G: (ip1, -1) - (-1, iq2) + //vertex of t1, special case t1 edge passed thru a vertex of t2 +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 5\n"; +#endif + CGAL_assertion(edge_id_t1 == 2); + CGAL_assertion(p.id1()==1); + CGAL_assertion(!q.extra_t1.empty()); + return Point_on_triangle(q.extra_t1.count(0)==1?0:2,-1); + default: + { +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 6\n"; +#endif + CGAL_assertion(q.id2()!=-1); // I: (ip1, -1) - (iq2, -1) + //H: (ip1,-1), (iq1, iq2) + CGAL_assertion(edge_id_t1==2); + // p and q are on the same edge of t1 + CGAL_assertion(p.id1()==q.id1() || p.id1()==(q.id1()+1)%3); + return Point_on_triangle((q.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3 , -1); + } + } + } + default: + { + switch(q.id1()) + { + case -1: // D: (ip1, ip2) - (-1, iq2) + { + if (q.id2() == p.id2() || q.id2() == (p.id2()+1)%3) + { +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 7\n"; +#endif + // points are on the same edge of t2 --> we shorten an already cut edge + typename Kernel::FT alpha = compute_alpha(p1, q1, + Pot::point_from_id(p2, q2, r2, p.id2()), + Pot::point_from_id(p2, q2, r2, (p.id2()+1)%3)); + + return Point_on_triangle(edge_id_t1, p.id2(), alpha); + } +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 8\n"; +#endif + // point of t1 + //std::cout << "q.extra_t1: "; for(int qet1 : q.extra_t1) std::cout << " " << qet1; std::cout << "\n"; + CGAL_assertion( q.extra_t1.count(p.id1())!=0 || q.extra_t1.count(3-p.id1()-edge_id_t1)!=0 ); + int eid1 = q.extra_t1.count(p.id1())!=0 ? p.id1() : 3-p.id1()-edge_id_t1; + return Point_on_triangle((eid1+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3, -1); // vertex of t1 + } + default: + { + switch(q.id2()) + { + case -1: // F: (ip1, ip2) - (iq1, -1) + { + // p and q are on the same edge of t1 + CGAL_assertion(q.id1()==p.id1() || q.id1()==(p.id1()+1)%3); +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 9\n"; +#endif + return Point_on_triangle((p.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3 , -1); + } + default: // E: (ip1, ip2) - (iq1, iq2) + { + if (p.id2()==q.id2()) + { +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 10\n"; +#endif + typename Kernel::FT alpha = compute_alpha(p1, q1, + Pot::point_from_id(p2, q2, r2, q.id2()), + Pot::point_from_id(p2, q2, r2, (q.id2()+1)%3)); + return Point_on_triangle(edge_id_t1, q.id2(), alpha); + } + // we are intersecting an edge of t1 + CGAL_assertion(p.id1()==q.id1() || edge_id_t1==2); + int eid1 = p.id1()==q.id1() ? p.id1() : 1; + return Point_on_triangle((eid1+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3, -1); // vertex of t1 + } + } + } + } + } + } + } + } +} + +template +void intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p1, + const typename Kernel::Point_3& q1, + const typename Kernel::Point_3& r1, + int edge_id, + const typename Kernel::Point_3& p2, + const typename Kernel::Point_3& q2, + const typename Kernel::Point_3& r2, + const Kernel& k, + std::list>& inter_pts) +{ +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " cutoff using e" << edge_id << ": " + << to_double(p1.x()) << " " << to_double(p1.y()) << " " << to_double(p1.z()) << " " + << to_double(q1.x()) << " " << to_double(q1.y()) << " " << to_double(q1.z()) << "\n"; +#endif + typedef typename std::list>::iterator Iterator; if(inter_pts.empty()) return; - typename Kernel::Coplanar_orientation_3 orient = k.coplanar_orientation_3_object(); - typename Kernel::Construct_line_3 line = k.construct_line_3_object(); + //orient(p1,q1,r1,r1) is POSITIVE + std::map*,Orientation> orientations; // TODO skip map + for (Point_on_triangle& pot : inter_pts) + { + orientations[ &pot ]=pot.orientation(p1,q1,r1,edge_id,p2,q2,r2,k); + if (pot.id1()==-1 && orientations[ &pot ]==COLLINEAR) + pot.extra_t1.insert(edge_id); + } - //orient(p,q,r,r) is POSITIVE - std::map orientations; - for (Iterator it=inter_pts.begin();it!=inter_pts.end();++it) - orientations[ &(*it) ]=orient(p,q,r,*it); +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " Orientations:"; + for (const Point_on_triangle& pot : inter_pts) + std::cout << " " << orientations[ &pot ]; + std::cout << "\n"; +#endif + CGAL_kernel_assertion_code(int pt_added = 0); - CGAL_kernel_assertion_code(int pt_added = 0;) + Iterator prev = std::prev(inter_pts.end()); - const typename Kernel::Point_3* prev = &(*std::prev(inter_pts.end())); Iterator stop = inter_pts.size() > 2 ? inter_pts.end() : std::prev(inter_pts.end()); for(Iterator it=inter_pts.begin(); it!=stop; ++it) { - const typename Kernel::Point_3& curr = *it; - Orientation or_prev = orientations[prev], - or_curr = orientations[&curr]; + Orientation or_prev = orientations[&(*prev)], + or_curr = orientations[&(*it)]; if((or_prev == POSITIVE && or_curr == NEGATIVE) || (or_prev == NEGATIVE && or_curr == POSITIVE)) { - typename Intersection_traits::result_type - obj = intersection(line(p,q), line(*prev,curr), k); + Point_on_triangle new_pt = intersection(*prev, *it, edge_id, p1, q1, p2, q2, r2, k); - // assert "not empty" - CGAL_kernel_assertion(bool(obj)); - - const typename Kernel::Point_3* inter = intersect_get(obj); - CGAL_kernel_assertion(inter != nullptr); - - prev = &(*inter_pts.insert(it,*inter)); - orientations[prev] = COLLINEAR; - CGAL_kernel_assertion_code(++pt_added;) + prev = inter_pts.insert(it,new_pt); + orientations[&(*prev)] = COLLINEAR; + CGAL_kernel_assertion_code(++pt_added); } - prev = &(*it); + prev = it; } CGAL_kernel_assertion(pt_added<3); @@ -96,35 +386,77 @@ intersection_coplanar_triangles(const typename K::Triangle_3& t1, const typename K::Triangle_3& t2, const K& k) { - const typename K::Point_3& p = t1.vertex(0), - q = t1.vertex(1), - r = t1.vertex(2); +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + auto to_string = [](const typename K::Triangle_3& t) + { + std::stringstream sstr; + sstr << "4 " + << to_double(t[0].x()) << " " << to_double(t[0].y()) << " " << to_double(t[0].z()) << " " + << to_double(t[1].x()) << " " << to_double(t[1].y()) << " " << to_double(t[1].z()) << " " + << to_double(t[2].x()) << " " << to_double(t[2].y()) << " " << to_double(t[2].z()) << " " + << to_double(t[0].x()) << " " << to_double(t[0].y()) << " " << to_double(t[0].z()) << "\n"; + return sstr.str(); + }; - std::list inter_pts; - inter_pts.push_back(t2.vertex(0)); - inter_pts.push_back(t2.vertex(1)); - inter_pts.push_back(t2.vertex(2)); + std::cout << "intersection_coplanar_triangles\n"; + std::ofstream("/tmp/t1.polylines.txt") << std::setprecision(17) << to_string(t1) << "\n"; + std::ofstream("/tmp/t2.polylines.txt") << std::setprecision(17) << to_string(t2) << "\n"; +#endif + const typename K::Point_3& p1 = t1.vertex(0), + q1 = t1.vertex(1), + r1 = t1.vertex(2); + const typename K::Point_3& p2 = t2.vertex(0), + q2 = t2.vertex(1), + r2 = t2.vertex(2); + + std::list> inter_pts; + inter_pts.push_back(Point_on_triangle(-1,0)); + inter_pts.push_back(Point_on_triangle(-1,1)); + inter_pts.push_back(Point_on_triangle(-1,2)); + +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + auto print_points = [&]() + { + for(auto p : inter_pts) std::cout << " (" << p.id1() << "," << p.id2() << ",[" << p.alpha << "]) "; std::cout <<"\n"; + }; + std::cout << " ipts size: " << inter_pts.size() << "\n"; + print_points(); +#endif //intersect t2 with the three half planes which intersection defines t1 - intersection_coplanar_triangles_cutoff(p,q,r,k,inter_pts); //line pq - intersection_coplanar_triangles_cutoff(q,r,p,k,inter_pts); //line qr - intersection_coplanar_triangles_cutoff(r,p,q,k,inter_pts); //line rp + intersection_coplanar_triangles_cutoff(p1,q1,r1,0,p2,q2,r2,k,inter_pts); //line pq +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " ipts size: " << inter_pts.size() << "\n"; + print_points(); +#endif + intersection_coplanar_triangles_cutoff(q1,r1,p1,1,p2,q2,r2,k,inter_pts); //line qr +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " ipts size: " << inter_pts.size() << "\n"; + print_points(); +#endif + intersection_coplanar_triangles_cutoff(r1,p1,q1,2,p2,q2,r2,k,inter_pts); //line rp +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " ipts size: " << inter_pts.size() << "\n"; + print_points(); +#endif + auto point = [&](const Point_on_triangle& pot){ return pot.point(p1,q1,r1,p2,q2,r2,k); }; switch(inter_pts.size()) { case 0: return intersection_return(); case 1: - return intersection_return(*inter_pts.begin()); + return intersection_return(point(*inter_pts.begin())); case 2: return intersection_return( - k.construct_segment_3_object()(*inter_pts.begin(), *std::next(inter_pts.begin())) ); + k.construct_segment_3_object()(point(*inter_pts.begin()), point(*std::next(inter_pts.begin()))) ); case 3: return intersection_return( - k.construct_triangle_3_object()(*inter_pts.begin(), *std::next(inter_pts.begin()), *std::prev(inter_pts.end())) ); + k.construct_triangle_3_object()(point(*inter_pts.begin()), point(*std::next(inter_pts.begin())), point(*std::prev(inter_pts.end()))) ); default: return intersection_return( - std::vector(inter_pts.begin(),inter_pts.end())); + std::vector(boost::make_transform_iterator(inter_pts.begin(), point), + boost::make_transform_iterator(inter_pts.end(), point))); } } diff --git a/Intersections_3/test/Intersections_3/triangle_3_triangle_3_intersection.cpp b/Intersections_3/test/Intersections_3/triangle_3_triangle_3_intersection.cpp index 0098bcd0142..f0875a55ee8 100644 --- a/Intersections_3/test/Intersections_3/triangle_3_triangle_3_intersection.cpp +++ b/Intersections_3/test/Intersections_3/triangle_3_triangle_3_intersection.cpp @@ -96,6 +96,13 @@ void test_coplanar_triangles(){ assert(CGAL::object_cast(&obj)!=nullptr); obj=CGAL::intersection(t2,t1); assert(CGAL::object_cast(&obj)!=nullptr); + // TK10 case C' + t1=Triangle(Point(88.7921, 89.0007, 1.25), Point(88.1912, 88.3997, 1.25), Point(89.8224, 90.031, 1.25)); + t2=Triangle(Point(88.0497, 88.2583, 1.25), Point(82.9292, 81.8747, 1.25), Point(91.1726, 91.3812, 1.25)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); //Intersection is a point //edges are collinear, one vertex in common t1=Triangle( Point(0,0,0),Point(0,1,0),Point(1,0,0) ); @@ -153,6 +160,13 @@ void test_coplanar_triangles(){ assert(CGAL::object_cast(&obj)!=nullptr); obj=CGAL::intersection(t2,t1); assert(CGAL::object_cast(&obj)!=nullptr); + // TK10 case D + t1=Triangle(Point(-34.893700000000003, -16.0351, 3.1334899999999998e-12), Point(-34.893700000000003, -18.5351, 3.1334899999999998e-12), Point(-42.393700000000003, -16.0351, 3.1334899999999998e-12)); + t2=Triangle(Point(-34.893700000000003, -32.0351, 3.1334899999999998e-12), Point(-34.893700000000003, -9.7851400000000002, 3.1334899999999998e-12), Point(-31.643699999999999, -17.201799999999999, 3.1334899999999998e-12)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); //Intersection is a polygon //David's star t1=Triangle( Point(0,0,0),Point(1,0,0),Point(0.5,1.5,0) ); @@ -181,6 +195,51 @@ void test_coplanar_triangles(){ obj=CGAL::intersection(t2,t1); assert(CGAL::object_cast(&obj)!=nullptr); assert(CGAL::object_cast(&obj)->size()==4); + // TK10 case A + t1=Triangle(Point(3.74861, 12.4822, 14.0112), Point(5.40582, 12.4822, 15.6895), Point(5.37748, 12.4822, 15.7206)); + t2=Triangle(Point(5.49972, 12.4822, 13.491), Point(5.27627, 12.4822, 15.8106), Point(5.32119, 12.4822, 15.8126)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + // TK10 case C + t1=Triangle(Point(5, -94.6659, 3.85175), Point(5, -94.5682, 3.08638), Point(5, -94.8182, 3.08638)); + t2=Triangle(Point(5, -94.4317, 3.76399), Point(5, -97.6182, 3.08638), Point(5, -94.5659, 2.99682)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + // TK10 case E + t1=Triangle(Point(-955.858, -45.032, -0.016), Point(-955.856, -45.032, -0.004), Point(-955.856, -45.032, -0.002)); + t2=Triangle(Point(-955.856, -45.032, 0.006), Point(-955.854, -45.032, -0.002), Point(-955.876, -45.032, -0.034)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + // TK10 case F + t1=Triangle(Point(141.172, 20.576, 155.764), Point(141.172, 20.588, 155.766), Point(141.172, 20.59, 155.766)); + t2=Triangle(Point(141.172, 20.602, 155.768), Point(141.172, 20.594, 155.766), Point(141.172, 20.574, 155.764)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + // TK10 case D + t1=Triangle(Point(152.864, 126.324, 0.950001), Point(152.77, 126.483, 0.950001), Point(153.072, 125.973, 0.950001)); + t2=Triangle(Point(153.322, 125.551, 0.950001), Point(152.218, 127.415, 0.950001), Point(153.66, 124.768, 0.950001)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); //Intersection is empty t1=Triangle( Point(0,0,0),Point(0,1,0),Point(1,0,0) ); t2=Triangle( Point(-0.1,-0.1,0),Point(-0.1,-0.9,0),Point(-1,-0.1,0) ); diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 9b439deb6d3..084a6578913 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -978,11 +978,42 @@ namespace CommonKernelFunctors { const Vector_3 ad = vector(a,d); const Vector_3 abad = cross_product(ab,ad); - const double x = CGAL::to_double(scalar_product(cross_product(ab,ac), abad)); - const double l_ab = CGAL::sqrt(CGAL::to_double(sq_distance(a,b))); - const double y = l_ab * CGAL::to_double(scalar_product(ac,abad)); + const Vector_3 abac = cross_product(ab,ac); - return FT(std::atan2(y, x) * 180 / CGAL_PI ); + // The dihedral angle we are interested in is the angle around the oriented + // edge ab which is the same (in absolute value) as the angle between the + // vectors ab^ac and ab^ad (cross-products). + // (abac points inside the tetra abcd if its orientation is positive and outside otherwise) + // + // We consider the vector abad in the basis defined by the three vectors + // (, , ) + // where denote the normalized vector u/|u|. + // + // In this orthonormal basis, the vector adab has the coordinates + // x = * abad + // y = * abad + // z = * abad + // We have x == 0, because abad and ab are orthogonal, and thus abad is in + // the plane (yz) of the new basis. + // + // In that basis, the dihedral angle is the angle between the y axis and abad + // which is the arctan of y/z, or atan2(z, y). + // + // (Note that ab^abac is in the plane abc, pointing outside the tetra if + // its orientation is positive and inside otherwise). + // + // For the normalization, abad appears in both scalar products + // in the quotient so we can ignore its norm. For the second + // terms of the scalar products, we are left with ab^abac and abac. + // Since ab and abac are orthogonal, the sinus of the angle between the + // two vectors is 1. + // So the norms are |ab|.|abac| vs |abac|, which is why we have a + // multiplication by |ab| in y below. + const double l_ab = CGAL::sqrt(CGAL::to_double(sq_distance(a,b))); + const double y = l_ab * CGAL::to_double(scalar_product(abac, abad)); + const double z = CGAL::to_double(scalar_product(cross_product(ab,abac),abad)); + + return FT(std::atan2(z, y) * 180 / CGAL_PI ); } }; @@ -2193,6 +2224,107 @@ namespace CommonKernelFunctors { } }; + template + class Construct_planes_intersection_point_3 + { + typedef typename K::Plane_3 Plane; + typedef typename K::Point_3 Point; + typename K::Construct_plane_3 construct_plane; + public: + typedef Point result_type; + + Point + operator()(const Point& p1, const Point& q1, const Point& r1, + const Point& p2, const Point& q2, const Point& r2, + const Point& p3, const Point& q3, const Point& r3) const + { + Plane plane1 = construct_plane(p1, q1, r1); + Plane plane2 = construct_plane(p2, q2, r2); + Plane plane3 = construct_plane(p3, q3, r3); + + const auto res = typename K::Intersect_3()(plane1, plane2, plane3); + CGAL_assertion(res!=std::nullopt); + const Point* e_pt = std::get_if(&(*res)); + CGAL_assertion(e_pt!=nullptr); + return *e_pt; + } + + Point + operator()(const Plane& plane1, const Plane& plane2, const Plane& plane3) const + { + const auto res = typename K::Intersect_3()(plane1, plane2, plane3); + CGAL_assertion(res!=std::nullopt); + const Point* e_pt = std::get_if(&(*res)); + CGAL_assertion(e_pt!=nullptr); + return *e_pt; + } + }; + + template + class Construct_coplanar_segments_intersection_point_3 + { + typedef typename K::Segment_3 Segment; + typedef typename K::Point_3 Point; + typename K::Construct_segment_3 construct_segment; + public: + typedef Point result_type; + + Point + operator()(const Point& p1, const Point& q1, + const Point& p2, const Point& q2) const + { + Segment s1 = construct_segment(p1, q1); + Segment s2 = construct_segment(p2, q2); + + const auto res = typename K::Intersect_3()(s1, s2); + CGAL_assertion(res!=std::nullopt); + const Point* e_pt = std::get_if(&(*res)); + CGAL_assertion(e_pt!=nullptr); + return *e_pt; + } + + Point + operator()(const Segment& s1, const Segment& s2) const + { + const auto res = typename K::Intersect_3()(s1, s2); + CGAL_assertion(res!=std::nullopt); + const Point* e_pt = std::get_if(&(*res)); + CGAL_assertion(e_pt!=nullptr); + return *e_pt; + } + }; + + template + class Compute_alpha_for_coplanar_triangle_intersection_3 + { + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + public: + typedef typename K::FT result_type; + result_type + operator()(const Point_3& p1, const Point_3& p2, // segment 1 + const Point_3& p3, const Point_3& p4) const // segment 2 + { + typename K::Construct_vector_3 vector = K().construct_vector_3_object(); + typename K::Construct_cross_product_vector_3 cross_product = + K().construct_cross_product_vector_3_object(); + + const Vector_3 v1 = vector(p1, p2); + const Vector_3 v2 = vector(p3, p4); + + CGAL_assertion(K().coplanar_3_object()(p1,p2,p3,p4)); + + const Vector_3 v3 = vector(p1, p3); + const Vector_3 v3v2 = cross_product(v3,v2); + const Vector_3 v1v2 = cross_product(v1,v2); + const typename K::FT sl = K().compute_squared_length_3_object()(v1v2); + CGAL_assertion(!certainly(is_zero(sl))); + + const typename K::FT t = ((v3v2.x()*v1v2.x()) + (v3v2.y()*v1v2.y()) + (v3v2.z()*v1v2.z())) / sl; + return t; // p1 + (p2-p1) * t + } + }; + template class Construct_point_on_2 { diff --git a/Kernel_23/include/CGAL/Kernel/interface_macros.h b/Kernel_23/include/CGAL/Kernel/interface_macros.h index 713e3773e56..a2314aef1b7 100644 --- a/Kernel_23/include/CGAL/Kernel/interface_macros.h +++ b/Kernel_23/include/CGAL/Kernel/interface_macros.h @@ -398,6 +398,12 @@ CGAL_Kernel_cons(Construct_plane_3, construct_plane_3_object) CGAL_Kernel_cons(Construct_plane_line_intersection_point_3, construct_plane_line_intersection_point_3_object) +CGAL_Kernel_cons(Construct_planes_intersection_point_3, + construct_planes_intersection_point_3_object) +CGAL_Kernel_cons(Construct_coplanar_segments_intersection_point_3, + construct_coplanar_segments_intersection_point_3_object) +CGAL_Kernel_cons(Compute_alpha_for_coplanar_triangle_intersection_3, + compute_alpha_for_coplanar_triangle_intersection_3_object) CGAL_Kernel_cons(Construct_point_on_2, construct_point_on_2_object) CGAL_Kernel_cons(Construct_point_on_3, diff --git a/Kernel_23/include/CGAL/Kernel_traits.h b/Kernel_23/include/CGAL/Kernel_traits.h index 4839184ff30..e12d38503bc 100644 --- a/Kernel_23/include/CGAL/Kernel_traits.h +++ b/Kernel_23/include/CGAL/Kernel_traits.h @@ -19,7 +19,6 @@ #include #include -#include namespace CGAL { diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h index eebd53cd03f..886832d0508 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h @@ -17,26 +17,19 @@ #ifndef CGAL__TEST_IO_H #define CGAL__TEST_IO_H -#include +#include #include -#ifndef TEST_FILENAME -# define TEST_FILENAME "Test_IO.out" -#endif - template void _test_io_for(const T& t) { - { - std::ofstream oFile(TEST_FILENAME, std::ios::out); - oFile << t << std::endl; - } + std::stringstream ss; + ss << t << std::endl; - std::ifstream iFile(TEST_FILENAME, std::ios::in); T u = t; - iFile >> u; - assert(!iFile.fail()); + ss >> u; + assert(! ss.fail() ); assert(u == t); } diff --git a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp index b39ce5c01e7..791ce36ac8c 100644 --- a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp +++ b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp @@ -10,10 +10,49 @@ struct query { double expected_angle; }; +void sign_test() +{ + K::Point_3 a(0,0,0), b(1,0,0), c(0,1, 0), d(0,0,1); + + assert( CGAL::approximate_dihedral_angle(a, b, c, d) > 0); + assert( CGAL::approximate_dihedral_angle(c, a, b, d) > 0); + assert( CGAL::approximate_dihedral_angle(a, d, b, c) > 0); + assert( CGAL::approximate_dihedral_angle(c, b, d, a) > 0); + assert( CGAL::approximate_dihedral_angle(d, b, a, c) > 0); + assert( CGAL::approximate_dihedral_angle(d, c, b, a) > 0); + + assert( CGAL::approximate_dihedral_angle(a, b, d, c) < 0); + assert( CGAL::approximate_dihedral_angle(c, a, d, b) < 0); + assert( CGAL::approximate_dihedral_angle(a, d, c, b) < 0); + assert( CGAL::approximate_dihedral_angle(c, b, a, d) < 0); + assert( CGAL::approximate_dihedral_angle(d, b, c, a) < 0); + assert( CGAL::approximate_dihedral_angle(d, c, a, b) < 0); +} + +auto almost_equal_angle(double a, double b) { + return (std::min)(std::abs(a - b), std::abs(a + 360 - b)) < 0.1; +} + +void test_regular_tetrahedron() +{ + auto half_root_of_2 = std::sqrt(2) / 2; + + // Regular tetrahedron + Point_3 a{ -1, 0, -half_root_of_2}; + Point_3 b{ 1, 0, -half_root_of_2}; + Point_3 c{ 0, 1, half_root_of_2}; + Point_3 d{ 0, -1, half_root_of_2}; + assert(orientation(a, b, c, d) == CGAL::POSITIVE); + assert(almost_equal_angle(CGAL::approximate_dihedral_angle(a, b, c, d), 70.5288)); +} + int main() { + std::cout.precision(17); + sign_test(); + test_regular_tetrahedron(); + Point_3 a = {0, 0, 0}; - Point_3 b = {0, 1, 0}; - Point_3 c = {1, 0, 0}; + Point_3 b = {0, -1, 0}; // ab is oriented so that it sees the plan xz positively. const query queries[] = { { { 1, 0, 0}, 0.}, @@ -26,11 +65,28 @@ int main() { { { 1, 0, -1}, -45.}, }; - for(auto query: queries) { - const auto& expected = query.expected_angle; - const auto& p = query.p; - auto approx = CGAL::approximate_dihedral_angle(a, b, c, p); - std::cout << approx << " -- " << expected << '\n'; - assert( std::abs(approx - expected) < 0.1 ); + auto cnt = 0u; + for(double yc = -10; yc < 10; yc += 0.1) { + // c can be any point in the half-plane xy, with x>0 + Point_3 c{1, yc, 0}; + // std::cout << "c = " << c << '\n'; + for(const auto& query : queries) { + for(double yp = -10; yp < 10; yp += 0.3) { + const auto& expected = query.expected_angle; + const Point_3 p{query.p.x(), yp, query.p.z()}; + // std::cout << "p = " << p << '\n'; + auto approx = CGAL::approximate_dihedral_angle(a, b, c, p); + // std::cout << approx << " -- " << expected << '\n'; + if(!almost_equal_angle(approx, expected)) { + std::cout << "ERROR:\n"; + std::cout << "CGAL::approximate_dihedral_angle(" << a << ", " << b << ", " << c << ", " << p << ") = " << approx << '\n'; + std::cout << "expected: " << expected << '\n'; + return 1; + } + ++cnt; + } + } } + std::cout << "OK (" << cnt << " tests)\n"; + assert(cnt > 10000); } diff --git a/Maintenance/test_handling/create_testresult_page b/Maintenance/test_handling/create_testresult_page index 3747a4a8313..edde28fff96 100755 --- a/Maintenance/test_handling/create_testresult_page +++ b/Maintenance/test_handling/create_testresult_page @@ -474,7 +474,7 @@ sub print_platform_descriptions() BOOST MPFR GMP -QT5 +QT LEDA CXXFLAGS LDFLAGS @@ -544,6 +544,7 @@ EOF print OUTPUT ">$pf_short"; my $index = 12; while ($index) { + $index--; print OUTPUT "?\n"; } } diff --git a/Maintenance/test_handling/to_zipped_format b/Maintenance/test_handling/to_zipped_format index d8c7c1cd433..fdf62712b02 100755 --- a/Maintenance/test_handling/to_zipped_format +++ b/Maintenance/test_handling/to_zipped_format @@ -51,7 +51,7 @@ sub reformat_results($) $_ = $line; open (PLATFORM_INFO,">${platform}.info") or return; open (PLATFORM_NEW_RESULTS,">${platform}.new_results") or return; - my ($CGAL_VERSION,$LEDA_VERSION,$COMPILER,$TESTER_NAME,$TESTER_ADDRESS,$GMP,$MPFR,$ZLIB,$OPENGL,$BOOST,$QT,$QT4,$QT5,$CMAKE) = ("-","-","-","-","-","-","-","-","-","-","-","-","-","-","-","no"); + my ($CGAL_VERSION,$LEDA_VERSION,$COMPILER,$TESTER_NAME,$TESTER_ADDRESS,$GMP,$MPFR,$ZLIB,$OPENGL,$BOOST,$QT,$CMAKE) = ("-","-","-","-","-","-","-","-","-","-","-","-","-","no"); my ($LDFLAGS,$CXXFLAGS) = ("", ""); while (! /^------/) { if(/^\s*$/) { @@ -97,10 +97,13 @@ sub reformat_results($) $QT="$1"; } if (/QT4_VERSION = '([^']+)'/) { - $QT4="$1"; + $QT="$1"; } if (/Qt5_VERSION = '([^']+)'/) { - $QT5="$1"; + $QT="$1"; + } + if (/Qt6_VERSION = '([^']+)'/) { + $QT="$1"; } if (/BOOST_VERSION = '([^']+)'/) { $BOOST="$1"; @@ -147,7 +150,7 @@ $CMAKE $BOOST $MPFR $GMP -$QT5 +$QT $LEDA_VERSION $CXXFLAGS $LDFLAGS diff --git a/Mesh_3/benchmark/Mesh_3/StdAfx.h b/Mesh_3/benchmark/Mesh_3/StdAfx.h index 57890430a5b..9648697498a 100644 --- a/Mesh_3/benchmark/Mesh_3/StdAfx.h +++ b/Mesh_3/benchmark/Mesh_3/StdAfx.h @@ -42,11 +42,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include diff --git a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h index 7e3af3de705..3ab3f0d3ba5 100644 --- a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h +++ b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -67,9 +66,9 @@ public: } private: - typedef typename boost::mpl::if_, - Function_*, - Function_>::type Stored_function; + typedef std::conditional_t, + Function_*, + Function_> Stored_function; /// Function to wrap Stored_function f_; diff --git a/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h b/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h index 45246e4463d..3d1c030ff08 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h +++ b/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h @@ -26,7 +26,6 @@ #include #include #include -#include namespace CGAL { diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index 9062dc1894f..bc9be8b3e5f 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -139,8 +139,8 @@ public: Protect_edges_sizing_field(C3T3& c3t3, const MeshDomain& domain, SizingFunction size=SizingFunction(), - const FT minimal_size = FT(), - std::size_t maximal_number_of_vertices = 0, + const FT minimal_size = FT(-1), + const std::size_t maximal_number_of_vertices = 0, Mesh_error_code* error_code = 0 #ifndef CGAL_NO_ATOMIC , std::atomic* stop_ptr = 0 @@ -455,17 +455,29 @@ private: return s; } + bool use_minimal_size() const + { + return minimal_size_ != FT(-1); + } + Weight minimal_weight() const + { + if (use_minimal_size()) + return minimal_weight_; + else + return Weight(0); + } + private: C3T3& c3t3_; const MeshDomain& domain_; SizingFunction size_; - FT minimal_size_; - Weight minimal_weight_; + const FT minimal_size_; + const Weight minimal_weight_; std::set treated_edges_; Vertex_set unchecked_vertices_; int refine_balls_iteration_nb; bool nonlinear_growth_of_balls; - std::size_t maximal_number_of_vertices_; + const std::size_t maximal_number_of_vertices_; Mesh_error_code* const error_code_; #ifndef CGAL_NO_ATOMIC /// Pointer to the atomic Boolean that can stop the process @@ -478,7 +490,7 @@ template Protect_edges_sizing_field:: Protect_edges_sizing_field(C3T3& c3t3, const MD& domain, Sf size, const FT minimal_size, - std::size_t maximal_number_of_vertices, + const std::size_t maximal_number_of_vertices, Mesh_error_code* error_code #ifndef CGAL_NO_ATOMIC , std::atomic* stop_ptr @@ -540,7 +552,7 @@ operator()(const bool refine) std::cerr << "refine_balls() done. Nb of points in triangulation: " << c3t3_.triangulation().number_of_vertices() << std::endl; #endif - CGAL_assertion(minimal_size_ > 0 || c3t3_.is_valid()); + CGAL_assertion(use_minimal_size() || c3t3_.is_valid()); } // debug_dump_c3t3("dump-mesh-after-protect_edges.binary.cgal", c3t3_); @@ -760,10 +772,10 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, while ( ! is_special(nearest_vh) && cwsr(c3t3_.triangulation().point(nearest_vh), - sq_d) == CGAL::SMALLER ) { - CGAL_assertion( minimal_size_ > 0 || sq_d > 0 ); + CGAL_assertion( use_minimal_size() || sq_d > 0); bool special_ball = false; - if(minimal_weight_ != Weight() && sq_d < minimal_weight_) + if(use_minimal_size() && sq_d < minimal_weight_) { sq_d = minimal_weight_; w = minimal_weight_; @@ -817,16 +829,16 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, const FT sq_d = tr.min_squared_distance(p, cp(c3t3_.triangulation().point(v))); - if(minimal_weight_ != Weight() && sq_d < minimal_weight_) { + if(use_minimal_size() && sq_d < minimal_weight()) { insert_a_special_ball = true; #if CGAL_MESH_3_PROTECTION_DEBUG & 1 nearest_point = c3t3_.triangulation().point(v); #endif - min_sq_d = minimal_weight_; + min_sq_d = minimal_weight(); if(! is_special(v)) { *out++ = v; - ch = change_ball_size(v, minimal_weight_, true)->cell(); // special ball + ch = change_ball_size(v, minimal_weight(), true)->cell(); // special ball } } else @@ -876,10 +888,10 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, if ( cwsr(it_wp, - sq_d) == CGAL::SMALLER ) { bool special_ball = false; - if(minimal_weight_ != Weight() && sq_d < minimal_weight_) + if(use_minimal_size() && sq_d < minimal_weight()) { - sq_d = minimal_weight_; - w = minimal_weight_; + sq_d = minimal_weight(); + w = minimal_weight(); special_ball = true; insert_a_special_ball = true; } @@ -933,13 +945,13 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, add_handle_to_unchecked = true; } - if( w < minimal_weight_) { + if( w < minimal_weight()) { #if CGAL_MESH_3_PROTECTION_DEBUG & 1 std::cerr << "smart_insert_point: weight " << w - << " was smaller than minimal weight (" << minimal_weight_ << ")\n"; + << " was smaller than minimal weight (" << minimal_weight() << ")\n"; #endif - w = minimal_weight_; + w = minimal_weight(); insert_a_special_ball = true; } Vertex_handle v = insert_point(p,w,dim,index, insert_a_special_ball); @@ -1174,7 +1186,7 @@ insert_balls(const Vertex_handle& vp, const FT d_signF = static_cast(d_sign); int n = static_cast(std::floor(FT(2)*(d-sq) / (sp+sq))+.5); - // if( minimal_weight_ != 0 && n == 0 ) return; + // if( minimal_weight() != 0 && n == 0 ) return; if(nonlinear_growth_of_balls && refine_balls_iteration_nb < 3) { @@ -1183,7 +1195,7 @@ insert_balls(const Vertex_handle& vp, // balls at corner. When the curve segment is long enough, pick a point // at the middle and choose a new size. if(n >= internal::max_nb_vertices_to_reevaluate_size && - d >= (internal::max_nb_vertices_to_reevaluate_size * minimal_weight_)) { + d >= (internal::max_nb_vertices_to_reevaluate_size * minimal_weight())) { #if CGAL_MESH_3_PROTECTION_DEBUG & 1 const Weighted_point& vq_wp = c3t3_.triangulation().point(vq); std::cerr << "Number of to-be-inserted balls is: " @@ -1436,9 +1448,9 @@ refine_balls() const Vertex_handle v = it->first; const FT new_size = it->second; // Set size of the ball to new value - if(minimal_size_ != FT() && new_size < minimal_size_) { + if(use_minimal_size() && new_size < minimal_size_) { if(!is_special(v)) { - change_ball_size(v, minimal_weight_, true); // special ball + change_ball_size(v, minimal_weight(), true); // special ball // Loop will have to be run again restart = true; @@ -1751,18 +1763,33 @@ is_sampling_dense_enough(const Vertex_handle& v1, const Vertex_handle& v2, FT size_v1 = get_radius(v1); FT size_v2 = get_radius(v2); - CGAL_assertion(get_dimension(v1) != 1 || - curve_index == domain_.curve_index(v1->index())); - CGAL_assertion(get_dimension(v2) != 1 || - curve_index == domain_.curve_index(v2->index())); + bool v1_valid_curve_index = true; + bool v2_valid_curve_index = true; + + if(use_minimal_size()) + { + v1_valid_curve_index = (get_dimension(v1) != 1 + || curve_index == domain_.curve_index(v1->index())); + v2_valid_curve_index = (get_dimension(v2) != 1 + || curve_index == domain_.curve_index(v2->index())); + } + else + { + CGAL_assertion(get_dimension(v1) != 1 || + curve_index == domain_.curve_index(v1->index())); + CGAL_assertion(get_dimension(v2) != 1 || + curve_index == domain_.curve_index(v2->index())); + } const Weighted_point& v1_wp = c3t3_.triangulation().point(v1); const Weighted_point& v2_wp = c3t3_.triangulation().point(v2); - FT arc_length = domain_.curve_segment_length(cp(v1_wp), + FT arc_length = (v1_valid_curve_index && v2_valid_curve_index) + ? domain_.curve_segment_length(cp(v1_wp), cp(v2_wp), curve_index, - orientation); + orientation) + : compute_distance(v1, v2); //curve polyline may not be consistent // Sufficient condition so that the curve portion between v1 and v2 is // inside the union of the two balls. diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h index 44e4f82b82d..ad023df618e 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h @@ -37,7 +37,6 @@ #include #include -#include #include #include @@ -172,9 +171,9 @@ template::value, + std::is_convertible_v, // Parallel # ifdef CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE @@ -209,7 +208,7 @@ template # endif - >::type // boost::if (parallel/sequential) + > // std::conditional (parallel/sequential) #else // !CGAL_LINKED_WITH_TBB diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h index 88a6e8ef555..5d32379ab0a 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -640,9 +639,9 @@ template class Base_ = Refine_facets_3_base, #ifdef CGAL_LINKED_WITH_TBB - class Container_ = typename boost::mpl::if_c // (parallel/sequential?) + class Container_ = std::conditional_t // (parallel/sequential?) < - std::is_convertible::value, + std::is_convertible_v, // Parallel # ifdef CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE Meshes::Filtered_deque_container @@ -679,7 +678,7 @@ template # endif - >::type // boost::if (parallel/sequential) + > // std::conditional (parallel/sequential) #else // !CGAL_LINKED_WITH_TBB diff --git a/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h b/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h index db2dde5b6d3..e8517c94945 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h +++ b/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h @@ -23,7 +23,6 @@ #include #include -#include #include #include diff --git a/Mesh_3/include/CGAL/Mesh_criteria_3.h b/Mesh_3/include/CGAL/Mesh_criteria_3.h index 96511da5520..c2d5d3d9b13 100644 --- a/Mesh_3/include/CGAL/Mesh_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_criteria_3.h @@ -70,22 +70,15 @@ public: // is not a problem template Mesh_criteria_3_impl(const CGAL_NP_CLASS& np) - :edge_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::edge_size_param), - parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::edge_sizing_field_param), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::sizing_field_param), FT(DBL_MAX)))), + :edge_criteria_(parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::edge_size_param), FT(DBL_MAX)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::edge_min_size_param), FT(0))), facet_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_angle_param), FT(0)), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_size_param), - parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::facet_sizing_field_param), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::sizing_field_param), FT(0)))), + parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::facet_size_param), FT(0)), parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::facet_distance_param), FT(0)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_topology_param), CGAL::FACET_VERTICES_ON_SURFACE), parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_min_size_param), FT(0))), - cell_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_radius_edge_ratio_param), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_radius_edge_param), FT(0))), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_size_param), - parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::cell_sizing_field_param), - parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::sizing_field_param), FT(0)))), + cell_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_radius_edge_ratio_param), FT(0)), + parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::cell_size_param), FT(0)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_min_size_param), FT(0))) { } diff --git a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp index 14390abda0d..9fa7eaad0c3 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp @@ -58,7 +58,9 @@ int main() facet_distance=field); // Mesh generation - C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria); + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + perturb(time_limit = 0, sliver_bound = 0), + exude(time_limit = 0, sliver_bound = 0)); // // Output // std::ofstream medit_file("out.mesh"); diff --git a/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp b/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp index b81befd7a56..8436b51c64d 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp @@ -75,28 +75,12 @@ int main() Mc ec1(edge_size = 1); assert( ec1.edge_criteria_object().sizing_field(bp1,1,index) == 1 ); - Mc ec2(edge_sizing_field = Esf(2)); + Mc ec2(edge_size = Esf(2)); assert( ec2.edge_criteria_object().sizing_field(bp1,1,index) == 2 ); - Mc ec3(edge_sizing_field = 3.); + Mc ec3(edge_size = 3.); assert( ec3.edge_criteria_object().sizing_field(bp1,1,index) == 3 ); - Mc ec4(edge_size = 4., - edge_sizing_field = Esf(5.)); - assert( ec4.edge_criteria_object().sizing_field(bp1,1,index) == 4. ); - - Mc ec5(sizing_field = 5.); - assert( ec5.edge_criteria_object().sizing_field(bp1,1,index) == 5 ); - - Mc ec6(sizing_field = 6., - edge_sizing_field = 7.); - assert( ec6.edge_criteria_object().sizing_field(bp1,1,index) == 7. ); - - Mc ec7(sizing_field = 7., - edge_size = 8.); - assert( ec7.edge_criteria_object().sizing_field(bp1,1,index) == 8. ); - - // ----------------------------------- // Test facet criteria // ----------------------------------- @@ -109,48 +93,29 @@ int main() cp(tr.point(ch, k+3)))); FT facet_size_ok = radius_facet*FT(10); - FT facet_size_nok = radius_facet/FT(10); Mc fc1(facet_size = facet_size_ok); assert( ! fc1.facet_criteria_object()(tr, f) ); - Mc fc2(facet_sizing_field = facet_size_ok); - assert( ! fc2.facet_criteria_object()(tr, f) ); - - Mc fc3(facet_sizing_field = Fsf(facet_size_ok)); + Mc fc3(facet_size = Fsf(facet_size_ok)); assert( ! fc3.facet_criteria_object()(tr, f) ); - Mc fc4(facet_sizing_field = facet_size_nok, - facet_size = facet_size_ok); - assert( ! fc4.facet_criteria_object()(tr, f) ); - - Mc fc5(sizing_field = facet_size_ok); - assert( ! fc5.facet_criteria_object()(tr, f) ); - - Mc fc6(facet_size = facet_size_ok, - facet_sizing_field = facet_size_nok, - sizing_field = facet_size_nok); - assert( ! fc6.facet_criteria_object()(tr, f) ); - - Mc fc7(facet_sizing_field = Fsf(facet_size_ok), - sizing_field = facet_size_nok); - assert( ! fc7.facet_criteria_object()(tr, f) ); - Mc fc8(facet_distance = 8.); Mc fc9(facet_angle = 9.); Mc fc10(facet_angle = 10.1, facet_distance = 10.2, facet_size = 10.3, - facet_min_size = 0.2, - facet_sizing_field = Fsf(10.4), - sizing_field = 10.5); + facet_min_size = 0.2); + Mc fc1Ob(facet_angle = 10.11, + facet_distance = 10.12, + facet_min_size = 0.3, + facet_size = Fsf(10.14)); // Test construction from int Mc fc11(facet_size = 11); Mc fc11b(facet_size = 11, facet_min_size = 1); - Mc fc12(facet_sizing_field = 12); - Mc fc12b(facet_sizing_field = 12, facet_min_size = 2); - Mc fc13(sizing_field = 13); + Mc fc12(facet_size = Fsf(12)); + Mc fc12b(facet_size = Fsf(12), facet_min_size = 1); // Test topological criterion creation Mc fc14(facet_topology = CGAL::FACET_VERTICES_ON_SURFACE); @@ -168,46 +133,27 @@ int main() cp(tr.point(ch, 3)))); FT cell_size_ok = radius_cell*FT(10); - FT cell_size_nok = radius_cell/FT(10); Mc cc1(cell_size = cell_size_ok); assert( ! cc1.cell_criteria_object()(tr, ch) ); - Mc cc2(cell_sizing_field = cell_size_ok); - assert( ! cc2.cell_criteria_object()(tr, ch) ); - - Mc cc3(cell_sizing_field = Fsf(cell_size_ok)); + Mc cc3(cell_size = Fsf(cell_size_ok)); assert( ! cc3.cell_criteria_object()(tr, ch) ); - Mc cc4(cell_sizing_field = cell_size_nok, - cell_size = cell_size_ok); - assert( ! cc4.cell_criteria_object()(tr, ch) ); - - Mc cc5(sizing_field = cell_size_ok); - assert( ! cc5.cell_criteria_object()(tr, ch) ); - - Mc cc6(cell_size = cell_size_ok, - cell_sizing_field = cell_size_nok, - sizing_field = cell_size_nok); - assert( ! cc6.cell_criteria_object()(tr, ch) ); - - Mc cc7(cell_sizing_field = Csf(cell_size_ok), - sizing_field = cell_size_nok); + Mc cc7(cell_size = Csf(cell_size_ok)); assert( ! cc7.cell_criteria_object()(tr, ch) ); Mc cc8(cell_radius_edge_ratio = 8.); Mc cc9(cell_radius_edge_ratio = 9.1, - sizing_field = Csf(9.2) ); + cell_size = Csf(9.2) ); Mc cc10(cell_radius_edge_ratio = 10.1, cell_size = 10.2, + cell_min_size = 0.1); + Mc cc10b(cell_radius_edge_ratio = 10.1, cell_min_size = 0.1, - cell_sizing_field = Csf(10.3), - sizing_field = 10.4); + cell_size = Csf(10.3)); // Test construction from int Mc cc11(cell_size = 11); Mc cc11b(cell_size = 11, cell_min_size = 1); - Mc cc12(cell_sizing_field = 12); - Mc cc12b(cell_sizing_field = 12, cell_min_size = 2); - Mc cc13(sizing_field = 13); } diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h index e6ff36dd0ce..a526ec5085d 100644 --- a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h +++ b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h @@ -33,7 +33,10 @@ template class Sphere_segment_rep typedef Sphere_segment_rep Rep; friend class Sphere_segment; public: -Sphere_segment_rep() { ps_ = pt_ = Point(); c_ = Circle(); } + +Sphere_segment_rep() : + ps_(), pt_(), c_() +{} Sphere_segment_rep(const Point& p1, const Point& p2, bool shorter_arc=true) : diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h index c02efa6dcc6..ef44403f9f5 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h @@ -15,7 +15,6 @@ #include #include #include -#include #include namespace CGAL { @@ -65,10 +64,10 @@ struct Cartesian_filter_K : public Base_ EK_rt exact_kernel()const{return sek.kernel();} // MSVC is too dumb to perform the empty base optimization. - typedef boost::mpl::and_< - internal::Do_not_store_kernel, - internal::Do_not_store_kernel, - internal::Do_not_store_kernel > Do_not_store_kernel; + typedef std::bool_constant< + internal::Do_not_store_kernel::value && + internal::Do_not_store_kernel::value && + internal::Do_not_store_kernel::value > Do_not_store_kernel; //TODO: C2A/C2E could be able to convert *this into this->kernel() or this->kernel2(). typedef KernelD_converter C2A; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h index 5c3a64287d2..122cfe90885 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h @@ -16,7 +16,6 @@ #include // bug, should be included by the next one #include #include -#include namespace CGAL { namespace SFA { // static filter adapter @@ -98,9 +97,9 @@ struct Cartesian_static_filters, R_, Derived_> : public R_ { template struct Functor : Inherit_functor {}; template struct Functor { typedef - //typename boost::mpl::if_ < - //std::is_same, - //typename Get_functor::type, + //std::conditional_t < + //std::is_same_v, + //typename Get_functor, SFA::Orientation_of_points_2 // >::type type; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/KernelD_converter.h b/NewKernel_d/include/CGAL/NewKernel_d/KernelD_converter.h index d62b8215cc5..edfb15ae9e9 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/KernelD_converter.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/KernelD_converter.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -80,12 +79,12 @@ class KernelD_converter_ // Explicit calls to boost::mpl functions to avoid parenthesis // warning on some versions of GCC - typedef typename boost::mpl::if_ < + typedef std::conditional_t < // If Point==Vector, keep only one conversion - boost::mpl::or_, + duplicate::value || // For iterator objects, the default is make_transforming_iterator - boost::mpl::bool_<(iterator_tag_traits::is_iterator && no_converter::value)> >, - Do_not_use,K1_Obj>::type argument_type; + (iterator_tag_traits::is_iterator && no_converter::value), + Do_not_use,K1_Obj> argument_type; //typedef typename KOC::argument_type K1_Obj; //typedef typename KOC::result_type K2_Obj; public: diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h index 6e6b496840e..67ea76e11fb 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h @@ -260,9 +260,9 @@ struct Lazy_cartesian : void set_dimension(int dim){ak.set_dimension(dim);ek.set_dimension(dim);} // For compilers that do not handle [[no_unique_address]] - typedef boost::mpl::and_< - internal::Do_not_store_kernel, - internal::Do_not_store_kernel > Do_not_store_kernel; + typedef std::bool_constant< + internal::Do_not_store_kernel::value && + internal::Do_not_store_kernel::value > Do_not_store_kernel; typedef typename EK_::Dimension Dimension; // ? typedef Lazy_cartesian Self; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h b/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h index 9ddd7953e24..50d9a8c8b00 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h @@ -83,8 +83,8 @@ template struct result_{typedef transforming_iterator struct result; template struct result : result_ {}; -template std::enable_if_t,Is_wrapper_iterator >::value,T> const& operator()(T const& t) const {return t;} -template std::enable_if_t,Is_wrapper_iterator >::value,T>& operator()(T& t) const {return t;} +template std::enable_if_t::value || Is_wrapper_iterator::value,T> const& operator()(T const& t) const {return t;} +template std::enable_if_t::value || Is_wrapper_iterator::value,T>& operator()(T& t) const {return t;} template typename T::Rep const& operator()(T const& t, std::enable_if_t::value >* = 0) const {return t.rep();} diff --git a/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h b/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h index a3255d25eb0..b3230858573 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -65,16 +64,16 @@ namespace CGAL { : Has_type_different_from, Null_functor> {}; template::type::value> - struct Provides_functors : boost::mpl::and_ < - Provides_functor::type>, - Provides_functors::type> > {}; + struct Provides_functors : std::bool_constant< + Provides_functor::type>::value && + Provides_functors::type>::value > {}; template struct Provides_functors : std::true_type {}; template::type::value> - struct Provides_types : boost::mpl::and_ < - Provides_type::type>, - Provides_types::type> > {}; + struct Provides_types : std::bool_constant< + Provides_type::type>::value && + Provides_types::type>::value > {}; template struct Provides_types : std::true_type {}; @@ -233,7 +232,7 @@ namespace CGAL { #undef CGAL_DECL_ITER_OBJ templatestruct Get_functor_category,B,C> : - boost::mpl::if_c::is_iterator, + std::conditional::is_iterator, Construct_iterator_tag, Construct_tag> {}; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/utils.h b/NewKernel_d/include/CGAL/NewKernel_d/utils.h index a1ac6faeddd..4296f179462 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/utils.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/utils.h @@ -38,7 +38,7 @@ template ::value /*false*/> struct Has_type_different_from : std::false_type {}; template struct Has_type_different_from -: boost::mpl::not_ > {}; +: std::bool_constant> {}; template struct Wrap_type { typedef T type; }; @@ -145,11 +145,11 @@ struct Has_type_different_from #define CGAL_KD_DEFAULT_FUNCTOR(Tg,Name,ReqTyp,ReqFun) \ template \ struct Get_functor::value \ || !Provides_types >::value \ || !Provides_functors >::value \ - , int, void>::type> \ + , int, void>> \ { \ typedef CGAL_STRIP_PAREN_ Name type; \ typedef K Bound_kernel; \ @@ -159,11 +159,11 @@ struct Has_type_different_from #define CGAL_KD_DEFAULT_TYPE(Tg,Name,ReqTyp,ReqFun) \ template \ struct Get_type::value \ || !Provides_types >::value \ || !Provides_functors >::value \ - , int, void>::type> \ + , int, void>> \ { \ typedef CGAL_STRIP_PAREN_ Name type; \ typedef K Bound_kernel; \ diff --git a/NewKernel_d/test/NewKernel_d/Epick_d.cpp b/NewKernel_d/test/NewKernel_d/Epick_d.cpp index 18ac1657ee6..5693977869a 100644 --- a/NewKernel_d/test/NewKernel_d/Epick_d.cpp +++ b/NewKernel_d/test/NewKernel_d/Epick_d.cpp @@ -509,8 +509,8 @@ void test3(){ ; CP_ cp_ Kinit(construct_point_d_object); CV_ cv_ Kinit(construct_vector_d_object); - typename boost::mpl::if_,Construct_point3_helper,CP_>::type cp(cp_); - typename boost::mpl::if_,Construct_point3_helper,CV_>::type cv(cv_); + std::conditional_t,Construct_point3_helper,CP_> cp(cp_); + std::conditional_t,Construct_point3_helper,CV_> cv(cv_); CCI ci Kinit(construct_cartesian_const_iterator_d_object); CC cc Kinit(compute_coordinate_d_object); CL cl Kinit(compare_lexicographically_d_object); diff --git a/Number_types/include/CGAL/Lazy_exact_nt.h b/Number_types/include/CGAL/Lazy_exact_nt.h index 3f06ef3fb32..d15c11a73bd 100644 --- a/Number_types/include/CGAL/Lazy_exact_nt.h +++ b/Number_types/include/CGAL/Lazy_exact_nt.h @@ -19,7 +19,6 @@ #include // for Root_of functor #include -#include #include #include @@ -383,9 +382,9 @@ public : // Also check that ET and AT are constructible from T? template - Lazy_exact_nt (T i, std::enable_if_t, std::is_enum >, - boost::mpl::not_ > >::value,void*> = 0) + Lazy_exact_nt (T i, std::enable_if_t< + (std::is_arithmetic_v || std::is_enum_v) && + !std::is_same_v,void*> = 0) : Base(new Lazy_exact_Cst(i)) {} Lazy_exact_nt (const ET & e) @@ -1179,12 +1178,11 @@ struct Coercion_traits< Lazy_exact_nt, Lazy_exact_nt > Are_implicit_interoperable; \ private: \ static const bool interoperable \ - =std::is_same< Are_implicit_interoperable, Tag_false>::value; \ + =std::is_same< Are_implicit_interoperable, Tag_false>::value; \ public: \ - typedef typename boost::mpl::if_c \ - ::type Type; \ - typedef typename boost::mpl::if_c >::type Cast; \ + typedef std::conditional_t Type; \ + typedef std::conditional_t > Cast; \ }; \ \ template \ diff --git a/Number_types/include/CGAL/Quotient.h b/Number_types/include/CGAL/Quotient.h index e91e22208a5..8c117c2fb6d 100644 --- a/Number_types/include/CGAL/Quotient.h +++ b/Number_types/include/CGAL/Quotient.h @@ -627,13 +627,13 @@ public: }; - typedef typename boost::mpl::if_c< - !std::is_same< typename Algebraic_structure_traits::Sqrt, - Null_functor >::value, + typedef std::conditional_t< + !std::is_same_v< typename Algebraic_structure_traits::Sqrt, + Null_functor >, typename INTERN_QUOTIENT::Sqrt_selector< Type, Is_exact >::Sqrt, Null_functor - >::type Sqrt; + > Sqrt; class Simplify : public CGAL::cpp98::unary_function< Type&, void > { diff --git a/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h b/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h index b0913afb1b6..c2175bc9439 100644 --- a/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h +++ b/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h @@ -204,10 +204,10 @@ public: typedef Sqrt_extension< COEFF_, ROOT_, ACDE_TAG,FP_TAG > Type; // Tag_true if COEFF and ROOT are exact - typedef typename ::boost::mpl::if_c< - bool( ::std::is_same::Is_exact,::CGAL::Tag_true>::value )&& - bool( ::std::is_same::Is_exact,::CGAL::Tag_true>::value ) - ,::CGAL::Tag_true,::CGAL::Tag_false>::type Is_exact; + typedef std::conditional_t< + std::is_same_v::Is_exact,::CGAL::Tag_true> && + std::is_same_v::Is_exact,::CGAL::Tag_true> + ,::CGAL::Tag_true,::CGAL::Tag_false> Is_exact; typedef typename Algebraic_structure_traits::Is_numerical_sensitive Is_numerical_sensitive; diff --git a/Number_types/include/CGAL/Sqrt_extension/Coercion_traits.h b/Number_types/include/CGAL/Sqrt_extension/Coercion_traits.h index 6b4344348d4..5b5ddfa45c6 100644 --- a/Number_types/include/CGAL/Sqrt_extension/Coercion_traits.h +++ b/Number_types/include/CGAL/Sqrt_extension/Coercion_traits.h @@ -178,7 +178,7 @@ template struct CT_ext_not_to_fwsqrt; // template struct Coercion_traits_for_level, B , CTL_SQRT_EXT> -:public ::boost::mpl::if_c< +:public std::conditional_t< // if B is fwsqrt ::boost::is_base_and_derived< Field_with_sqrt_tag, @@ -192,7 +192,7 @@ typename Algebraic_structure_traits::Algebraic_category >::value , //else take Intern::Coercion_traits not for fwsqrt INTERN_CT::CT_ext_not_to_fwsqrt< Sqrt_extension ,B> - >::type + > {}; // diff --git a/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h b/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h index 4a562530c75..6b87205b501 100644 --- a/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h +++ b/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h @@ -178,10 +178,10 @@ public: */ template explicit Sqrt_extension(const NTX& a, const NTX& b, const NTX& c, const bool is_smaller, - std::enable_if_t< boost::mpl::and_< - std::is_same< typename Fraction_traits::Numerator_type,NTX >, - std::is_same< typename Fraction_traits::Numerator_type,NTX > - >::value >* = 0 ) + std::enable_if_t< + std::is_same_v< typename Fraction_traits::Numerator_type,NTX > && + std::is_same_v< typename Fraction_traits::Numerator_type,NTX > + >* = 0 ) { typename Fraction_traits::Compose compose_nt; typename Fraction_traits::Compose compose_root; diff --git a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_Delaunay_triangulation_2.h b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_Delaunay_triangulation_2.h index 1232e426aed..c83be87df90 100644 --- a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_Delaunay_triangulation_2.h +++ b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_Delaunay_triangulation_2.h @@ -435,10 +435,9 @@ public: boost::zip_iterator< boost::tuple > last, bool is_large_point_set = true, std::enable_if_t < - boost::mpl::and_ < - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value >* = nullptr) + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > + >* = nullptr) { return insert_with_info< boost::tuple::type> >(first, last, is_large_point_set); } diff --git a/Periodic_3_mesh_3/include/CGAL/Implicit_to_labeled_subdomains_function_wrapper.h b/Periodic_3_mesh_3/include/CGAL/Implicit_to_labeled_subdomains_function_wrapper.h index a96c2eafa36..d821ab2fe3f 100644 --- a/Periodic_3_mesh_3/include/CGAL/Implicit_to_labeled_subdomains_function_wrapper.h +++ b/Periodic_3_mesh_3/include/CGAL/Implicit_to_labeled_subdomains_function_wrapper.h @@ -15,7 +15,6 @@ #include #include -#include #if defined(BOOST_MSVC) # pragma warning(push) @@ -47,9 +46,9 @@ public: } private: - typedef typename boost::mpl::if_, - Function_*, - Function_>::type Stored_function; + typedef std::conditional_t, + Function_*, + Function_> Stored_function; /// Function to wrap Stored_function f_; diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h index 2780d618393..bfb4b4e8716 100644 --- a/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h @@ -18,7 +18,6 @@ #include #include -#include namespace CGAL { @@ -46,9 +45,9 @@ public: } private: - typedef typename boost::mpl::if_, - Function_*, - Function_>::type Stored_function; + typedef std::conditional_t, + Function_*, + Function_> Stored_function; /// Function to wrap Stored_function f_; diff --git a/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp b/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp index f09fffd0d4f..87669ceb91d 100644 --- a/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp +++ b/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp @@ -230,7 +230,7 @@ int main() Periodic_mesh_criteria criteria(facet_angle = 30, facet_size = 0.05, facet_distance = 0.025, - cell_radius_edge = 2, + cell_radius_edge_ratio = 2, cell_size = 0.05); // Mesh generation diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h index 7eed15886cd..63fb9404469 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h @@ -31,7 +31,6 @@ #include #include -#include #include #include #include diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 35a7afcad80..f0636f1e14b 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -75,8 +75,8 @@ namespace internal { Point_set_3_index operator++ (int) { Point_set_3_index tmp(*this); ++value; return tmp; } Point_set_3_index operator-- (int) { Point_set_3_index tmp(*this); --value; return tmp; } }; -/// \endcond } // namespace internal +/// \endcond /*! diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index 2e680a744f8..789d44921d5 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -161,6 +161,8 @@ bool read_point_set(const std::string& fname, \param ps the point set \return `os` + + \relates Point_set_3 */ template std::ostream& operator<<(std::ostream& os, diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h b/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h index 9f605978f7c..5b625f8042e 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -148,6 +149,12 @@ struct Reconstruction_triangulation_default_geom_traits_3 : public BaseGt }; +template < class BaseGt > +struct Triangulation_structural_filtering_traits > { + typedef typename Triangulation_structural_filtering_traits::Use_structural_filtering_tag Use_structural_filtering_tag; +}; + + /// \internal /// The Reconstruction_triangulation_3 class /// provides the interface requested by the Poisson_reconstruction_function class: diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPAutorefinementVisitor.h b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPAutorefinementVisitor.h new file mode 100644 index 00000000000..ef2f124329b --- /dev/null +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPAutorefinementVisitor.h @@ -0,0 +1,27 @@ +/// \ingroup PkgPolygonMeshProcessingConcepts +/// \cgalConcept +/// +/// The concept `PMPAutorefinementVisitor` defines the requirements for the visitor +/// used in `CGAL::Polygon_mesh_processing::autorefine_triangle_soup()` to track +/// the creation of new triangles. +/// +/// \cgalRefines{CopyConstructible} +/// \cgalHasModelsBegin +/// \cgalHasModels{CGAL::Polygon_mesh_processing::Autorefinement::Default_visitor} +/// \cgalHasModelsEnd + +class PMPAutorefinementVisitor{ +public: + +/// @name Functions called only if at least one intersection has been found +/// @{ + /// called when the final number of output triangles is known, `nbt` being the total number of triangles in the output. + void number_of_output_triangles(std::size_t nbt); + /// called for triangle with no intersection, `tgt_id` is the position in the triangle container after calling + /// `autorefine_triangle_soup()`, while `src_id` was its position before calling the function. + void verbatim_triangle_copy(std::size_t tgt_id, std::size_t src_id); + /// called for each subtriangle created from a triangle with intersection, `tgt_id` is the position in the triangle container after calling + /// `autorefine_triangle_soup()` of the subtriangle, while `src_id` was the position of the original support triangle before calling the function. + void new_subtriangle(std::size_t tgt_id, std::size_t src_id); +/// @} +}; diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h index 8641c30c6ca..b1216f3281e 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h @@ -16,6 +16,7 @@ class PMPSizingField{ public: /// @name Types +/// These types are used for the documentation of the functions of the concept and not needed implementation wise. /// @{ /// Vertex descriptor type @@ -38,27 +39,30 @@ typedef unspecified_type FT; /// @name Functions /// @{ -/// a function that returns the sizing value at `v`. -FT at(const vertex_descriptor v) const; +/// returns the sizing value at `v` (used during tangential relaxation). +FT at(const vertex_descriptor v, const PolygonMesh& pmesh) const; -/// a function controlling edge split and edge collapse, -/// returning the ratio of the current edge length and the local target edge length between -/// the points of `va` and `vb` in case the current edge is too long, and `std::nullopt` otherwise. +/// returns the ratio of the current edge squared length and the local target edge squared length between +/// the points of `va` and `vb` in case the current edge is too long, and `std::nullopt` otherwise +/// (used for triggering edge splits and preventing some edge collapses). std::optional is_too_long(const vertex_descriptor va, - const vertex_descriptor vb) const; + const vertex_descriptor vb, + const PolygonMesh& pmesh) const; -/// a function controlling edge collapse by returning the ratio of the squared length of `h` and the -/// local target edge length if it is too short, and `std::nullopt` otherwise. +/// returns the ratio of the squared length of `h` and the +/// local target edge squared length if it is too short, and `std::nullopt` otherwise +/// (used for triggering edge collapses). std::optional is_too_short(const halfedge_descriptor h, const PolygonMesh& pmesh) const; -/// a function returning the location of the split point of the edge of `h`. +/// returns the position of the new vertex created when splitting the edge of `h`. Point_3 split_placement(const halfedge_descriptor h, const PolygonMesh& pmesh) const; -/// a function that updates the sizing field value at the vertex `v`. -void update(const vertex_descriptor v, - const PolygonMesh& pmesh); +/// function called after the addition of the split vertex `v` in `pmesh`. +/// This function can be used for example to update a pre-computed sizing field. +void register_split_vertex(const vertex_descriptor v, + const PolygonMesh& pmesh); /// @} }; diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index a8eae9eb255..ad143bf835d 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -113,6 +113,8 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage. - `CGAL::Polygon_mesh_processing::surface_intersection()` - `CGAL::Polygon_mesh_processing::clip()` - `CGAL::Polygon_mesh_processing::split()` +- `CGAL::Polygon_mesh_processing::autorefine_triangle_soup()` +- `CGAL::Polygon_mesh_processing::autorefine()` \cgalCRPSection{Meshing Functions} - `CGAL::Polygon_mesh_processing::remesh_planar_patches()` @@ -268,6 +270,7 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage. - `CGAL::Polygon_mesh_processing::triangle()` - `CGAL::Polygon_mesh_processing::region_growing_of_planes_on_faces()` - `CGAL::Polygon_mesh_processing::detect_corners_of_regions()` +- `CGAL::Polygon_mesh_processing::refine_mesh_at_isolevel()` \cgalCRPSection{I/O Functions} - \link PMP_IO_grp `CGAL::Polygon_mesh_processing::IO::read_polygon_mesh()`\endlink diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index 26d5d9c6450..ac3e94db114 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -229,7 +229,7 @@ it can try to equalize the angles between incident edges, or (and) move vertices Border vertices are considered constrained and do not move at any step of the procedure. No vertices are inserted at any time. Angle and area smoothing algorithms are based on Surazhsky and Gotsman \cgalCite{cgal:sg-hqct-04}. Since area smoothing considers only areas as a smoothing criterion, it may result in long and skinny -triangles. To paliate this phenomenon, area smoothing is followed by an (optional) step of Delaunay-based edge flips. +triangles. To palliate this phenomenon, area smoothing is followed by an (optional) step of Delaunay-based edge flips. In any case, area smoothing is guaranteed to improve the spatial distribution of the vertices over the area that is being smoothed. A simple example can be found in \ref Polygon_mesh_processing/mesh_smoothing_example.cpp. @@ -449,7 +449,7 @@ depicted in red); (iii) `clip_volume=true`: clipping of the volume bounded by th \cgalFigureEnd \cgalFigureBegin{coref_clip_compact, clip_compact.png} -Clipping a cube with a halfspace: compacity of the clipper (`clip_volume=false` in both cases). +Clipping a cube with a halfspace: compactivity of the clipper (`clip_volume=false` in both cases). From left to right: (i) initial cube and the plane defining the clipping halfspace, note that a whole face of the cube (2 triangles) is exactly contained in the plane; (ii) `use_compact_clipper=true`: clipping of the surface mesh with a compact halfspace: coplanar faces are part of the output; @@ -879,6 +879,19 @@ vertices at identical positions, can be used to repair this configuration. \section PMPGeometricRepair Geometric Repair **************************************** +\subsection PMPAutoref Self-intersection Resolution (Autorefinement) in Triangle Soups +Given a soup of triangles, a self-intersection is defined as the intersection of two triangles from the soup +such that the intersection is not defined by the convex hull of one, two or three shared vertices. +In other words, it is an intersection that happens in the interior of one of the two triangles, or in the interior +of one their edges, except if identical points are associated to different vertices of the triangle soup which +would then also includes overlaps of duplicated points. + +The function `CGAL::Polygon_mesh_processing::autorefine_triangle_soup()` provides a way to refine a triangle soup +using the intersections of the triangles from the soup. In particular, if some points are duplicated they will be +merged. Note that if a kernel with exact predicates but inexact constructions is used, some new self-intersections +might be introduced due to rounding issues of points coordinates. +To guarantee that the triangle soup is free from self-intersections, a kernel with exact constructions must be used. + \subsection PMPRemoveCapsNeedles Removal of Almost Degenerate Triangle Faces Triangle faces of a mesh made up of almost collinear points are badly shaped elements that might not be desirable to have in a mesh. The function diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt index 6fdeda48ca4..3aca69fb004 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt @@ -46,4 +46,7 @@ \example Polygon_mesh_processing/cc_compatible_orientations.cpp \example Polygon_mesh_processing/remesh_planar_patches.cpp \example Polygon_mesh_processing/remesh_almost_planar_patches.cpp +\example Polygon_mesh_processing/sample_example.cpp +\example Polygon_mesh_processing/soup_autorefinement.cpp +*/ */ diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index 590305c0c8a..455e1ce2be7 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -7,6 +7,7 @@ project(Polygon_mesh_processing_Examples) # CGAL and its components find_package(CGAL REQUIRED) +create_single_source_cgal_program("sample_example.cpp" ) create_single_source_cgal_program("extrude.cpp" ) create_single_source_cgal_program("polyhedral_envelope.cpp" ) create_single_source_cgal_program("polyhedral_envelope_of_triangle_soup.cpp" ) @@ -51,6 +52,9 @@ create_single_source_cgal_program("match_faces.cpp") create_single_source_cgal_program("cc_compatible_orientations.cpp") create_single_source_cgal_program("hausdorff_distance_remeshing_example.cpp") create_single_source_cgal_program("hausdorff_bounded_error_distance_example.cpp") +create_single_source_cgal_program("isotropic_remeshing_with_custom_sizing_example.cpp") +create_single_source_cgal_program("triangle_mesh_autorefinement.cpp") +create_single_source_cgal_program("soup_autorefinement.cpp") find_package(Eigen3 3.2.0 QUIET) #(requires 3.2.0 or greater) include(CGAL_Eigen3_support) @@ -75,6 +79,8 @@ if(TARGET CGAL::Eigen3_support) target_link_libraries(delaunay_remeshing_example PUBLIC CGAL::Eigen3_support) create_single_source_cgal_program("remesh_almost_planar_patches.cpp") target_link_libraries(remesh_almost_planar_patches PUBLIC CGAL::Eigen3_support) + create_single_source_cgal_program("geodesic_isolevel_refinement.cpp") + target_link_libraries(geodesic_isolevel_refinement PUBLIC CGAL::Eigen3_support) create_single_source_cgal_program("interpolated_corrected_curvatures_SM.cpp") target_link_libraries(interpolated_corrected_curvatures_SM PUBLIC CGAL::Eigen3_support) create_single_source_cgal_program("interpolated_corrected_curvatures_PH.cpp") @@ -129,6 +135,7 @@ if(TARGET CGAL::TBB_support) target_link_libraries(self_intersections_example PUBLIC CGAL::TBB_support) target_link_libraries(hausdorff_distance_remeshing_example PUBLIC CGAL::TBB_support) target_link_libraries(hausdorff_bounded_error_distance_example PUBLIC CGAL::TBB_support) + target_link_libraries(soup_autorefinement PUBLIC CGAL::TBB_support) create_single_source_cgal_program("corefinement_parallel_union_meshes.cpp") target_link_libraries(corefinement_parallel_union_meshes PUBLIC CGAL::TBB_support) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/cc_compatible_orientations.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/cc_compatible_orientations.cpp index 8a47239c5aa..646e94e9468 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/cc_compatible_orientations.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/cc_compatible_orientations.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example.cpp index c7e1fbdb21c..949fcc8dd64 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example.cpp @@ -7,14 +7,14 @@ #include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K::Point_3 Point; -typedef K::Vector_3 Vector; +typedef K::Point_3 Point; +typedef K::Vector_3 Vector; -typedef CGAL::Surface_mesh Surface_mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::face_descriptor face_descriptor; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; namespace PMP = CGAL::Polygon_mesh_processing; @@ -22,7 +22,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/eight.off"); - Surface_mesh mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example_Polyhedron.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example_Polyhedron.cpp index d21d675eb2b..4418c6096d1 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example_Polyhedron.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example_Polyhedron.cpp @@ -16,9 +16,9 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::Point_3 Point; typedef K::Vector_3 Vector; -typedef CGAL::Polyhedron_3 Polyhedron; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::face_descriptor face_descriptor; +typedef CGAL::Polyhedron_3 Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; namespace PMP = CGAL::Polygon_mesh_processing; @@ -26,7 +26,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/eight.off"); - Polyhedron mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_LCC.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_LCC.cpp index 232164a1b95..d4d774d1105 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_LCC.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_LCC.cpp @@ -12,7 +12,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; typedef CGAL::Linear_cell_complex_traits<3, Kernel> MyTraits; -typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper<2, 3, MyTraits>::type LCC; +typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper<2, 3, MyTraits>::type Mesh; namespace PMP = CGAL::Polygon_mesh_processing; @@ -21,7 +21,7 @@ int main(int argc, char* argv[]) const std::string filename1 = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/blobby.off"); const std::string filename2 = (argc > 2) ? argv[2] : CGAL::data_file_path("meshes/eight.off"); - LCC mesh1, mesh2; + Mesh mesh1, mesh2; if(!PMP::IO::read_polygon_mesh(filename1, mesh1) || !PMP::IO::read_polygon_mesh(filename2, mesh2)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp index aa7c2bd40ea..300d0182fdb 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp @@ -2,19 +2,19 @@ #include #include #include -#include +#include #include #include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef CGAL::Surface_mesh SM; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef Kernel::Vector_3 Vector; -typedef boost::property_map::type VPMap; -typedef SM::template Property_map VNMap; +typedef Kernel::Vector_3 Vector; +typedef boost::property_map::type VPMap; +typedef Mesh::template Property_map VNMap; struct Bottom { @@ -52,7 +52,7 @@ struct Top int main(int argc, char* argv[]) { - SM in, out; + Mesh in, out; std::string filename = (argc > 1) ? std::string(argv[1]) : CGAL::data_file_path("meshes/cube-ouvert.off"); double vlen = (argc > 2) ? std::stod(argv[2]) : 0.1; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/geodesic_isolevel_refinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/geodesic_isolevel_refinement.cpp new file mode 100644 index 00000000000..29f43453e87 --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/geodesic_isolevel_refinement.cpp @@ -0,0 +1,72 @@ +#include +#include + +#include + +#include +#include + +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point_3; +typedef CGAL::Surface_mesh Triangle_mesh; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::edge_descriptor edge_descriptor; + +typedef Triangle_mesh::Property_map Vertex_distance_map; +typedef CGAL::Heat_method_3::Surface_mesh_geodesic_distances_3 Heat_method; + +int main(int argc, char* argv[]) +{ + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/elephant.off"); + + Triangle_mesh tm; + if(!CGAL::IO::read_polygon_mesh(filename, tm) || + CGAL::is_empty(tm) || !CGAL::is_triangle_mesh(tm)) + { + std::cerr << "Invalid input file." << std::endl; + return EXIT_FAILURE; + } + + // default isovalues for cutting the mesh + std::vector isovalues = {0.001, 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 10}; + + if (argc>2) + { + isovalues.clear(); + for (int i=2; i("v:distance", 0).first; + + Heat_method hm(tm); + + //use heat method to compute approximated geodesic distances to the source vertex `s` + vertex_descriptor s = *(vertices(tm).first); + hm.add_source(s); + hm.estimate_geodesic_distances(vertex_distance); + + // property map to flag new cut edge added in the mesh + auto ecm = tm.add_property_map("e:is_constrained", 0).first; + + // refine the mesh along isovalues + for (double isovalue : isovalues) + CGAL::Polygon_mesh_processing::refine_mesh_at_isolevel(tm, vertex_distance, isovalue, CGAL::parameters::edge_is_constrained_map(ecm)); + + // split the mesh in connected components bounded by the isocurves + std::vector edges_split; + CGAL::Polygon_mesh_processing::split_connected_components(tm, edges_split, CGAL::parameters::edge_is_constrained_map(ecm)); + + assert(argc!=1 || edges_split.size() == 22); + + // export each submesh in a file + for(std::size_t i=0; i Polyhedron; +typedef CGAL::Polyhedron_3 Mesh; -typedef Polyhedron::Vertex_handle Vertex_handle; -typedef Polyhedron::Halfedge_handle Halfedge_handle; -typedef Polyhedron::Facet_handle Facet_handle; +typedef Mesh::Vertex_handle Vertex_handle; +typedef Mesh::Halfedge_handle Halfedge_handle; +typedef Mesh::Facet_handle Facet_handle; namespace PMP = CGAL::Polygon_mesh_processing; @@ -24,7 +24,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/mech-holes-shark.off"); - Polyhedron poly; + Mesh poly; if(!PMP::IO::read_polygon_mesh(filename, poly)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example_LCC.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example_LCC.cpp index be7b6166e4e..89825600510 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example_LCC.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example_LCC.cpp @@ -14,11 +14,11 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; typedef CGAL::Linear_cell_complex_traits<3, Kernel> MyTraits; -typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper<2, 3, MyTraits>::type LCC; +typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper<2, 3, MyTraits>::type Mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; -typedef boost::graph_traits::face_descriptor face_descriptor; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; namespace PMP = CGAL::Polygon_mesh_processing; @@ -26,7 +26,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/mech-holes-shark.off"); - LCC mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_PH.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_PH.cpp index 09bc213068d..678597ad255 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_PH.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_PH.cpp @@ -7,17 +7,17 @@ #include #include -#include +#include namespace PMP = CGAL::Polygon_mesh_processing; typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic_kernel; -typedef CGAL::Polyhedron_3 Polyhedron; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef CGAL::Polyhedron_3 Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; int main(int argc, char* argv[]) { - Polyhedron polyhedron; + Mesh polyhedron; const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/sphere.off"); @@ -29,11 +29,11 @@ int main(int argc, char* argv[]) } // define property map to store curvature value and directions - boost::property_map>::type + boost::property_map>::type mean_curvature_map = get(CGAL::dynamic_vertex_property_t(), polyhedron), Gaussian_curvature_map = get(CGAL::dynamic_vertex_property_t(), polyhedron); - boost::property_map>>::type + boost::property_map>>::type principal_curvatures_and_directions_map = get(CGAL::dynamic_vertex_property_t>(), polyhedron); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_SM.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_SM.cpp index 74a678ea062..ac8378781fe 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_SM.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_SM.cpp @@ -11,12 +11,12 @@ namespace PMP = CGAL::Polygon_mesh_processing; typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic_kernel; -typedef CGAL::Surface_mesh Surface_Mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; int main(int argc, char* argv[]) { - Surface_Mesh smesh; + Mesh smesh; const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/sphere.off"); @@ -29,7 +29,7 @@ int main(int argc, char* argv[]) // creating and tying surface mesh property maps for curvatures (with defaults = 0) bool created = false; - Surface_Mesh::Property_map + Mesh::Property_map mean_curvature_map, Gaussian_curvature_map; boost::tie(mean_curvature_map, created) = @@ -41,7 +41,7 @@ int main(int argc, char* argv[]) assert(created); // we use a tuple of 2 scalar values and 2 vectors for principal curvatures and directions - Surface_Mesh::Property_map> + Mesh::Property_map> principal_curvatures_and_directions_map; boost::tie(principal_curvatures_and_directions_map, created) = @@ -67,4 +67,5 @@ int main(int argc, char* argv[]) << ", GC = " << Gaussian_curvature_map[v] << "\n" << ", PC = [ " << PC.min_curvature << " , " << PC.max_curvature << " ]\n"; } + return 0; } diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_vertex.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_vertex.cpp index bdcdba6b7fd..dc78152059b 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_vertex.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_vertex.cpp @@ -6,17 +6,18 @@ #include #include +#include namespace PMP = CGAL::Polygon_mesh_processing; typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic_kernel; -typedef CGAL::Surface_mesh Surface_Mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; int main(int argc, char* argv[]) { // instantiating and reading mesh - Surface_Mesh smesh; + Mesh smesh; const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/sphere.off"); @@ -47,4 +48,5 @@ int main(int argc, char* argv[]) << ", GC = " << g << "\n" << ", PC = [ " << p.min_curvature << " , " << p.max_curvature << " ]\n"; } + return 0; } diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp new file mode 100644 index 00000000000..53d70af603f --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Surface_mesh Mesh; + +namespace PMP = CGAL::Polygon_mesh_processing; + +// a sizing fied that is increasing the size of edge along the y-axis +// starting at a minimum size at y-max and ending at a maximum size at +// y-min, with a linear interpolation of sizes in between the two extreme +// sizing values +struct My_sizing_field +{ + double min_size, max_size; + double ymin, ymax; + + My_sizing_field(double min_size, double max_size, double ymin, double ymax) + : min_size(min_size) + , max_size(max_size) + , ymin(ymin) + , ymax(ymax) + {} + + double at(K::Point_3 p) const + { + double y=p.y(); + return CGAL::square( (y-ymin)/(ymax-ymin) * (min_size - max_size) + max_size ); + } + double at(const Mesh::Vertex_index v, const Mesh& mesh) const { return at(mesh.point(v)); } + + std::optional is_too_long(const Mesh::Vertex_index va, + const Mesh::Vertex_index vb, + const Mesh& mesh) const + { + // TODO: no mesh as parameters? + K::Point_3 mp = CGAL::midpoint(mesh.point(va), mesh.point(vb)); + double sql_at = at(mp); + double sql = CGAL::squared_distance(mesh.point(va), mesh.point(vb)); + if (sql > sql_at) + return sql / sql_at; + return std::nullopt; + } + + std::optional is_too_short(const Mesh::Halfedge_index h, + const Mesh& mesh) const + { + K::Point_3 mp = CGAL::midpoint(mesh.point(source(h, mesh)), mesh.point(target(h, mesh))); + double sql_at = at(mp); + double sql = CGAL::squared_distance(mesh.point(source(h, mesh)), mesh.point(target(h, mesh))); + if (sql < sql_at) + return sql / sql_at; + return std::nullopt; + } + + K::Point_3 split_placement(const Mesh::Halfedge_index h, + const Mesh& mesh) const + { + return CGAL::midpoint(mesh.point(source(h, mesh)), mesh.point(target(h, mesh))); + } + + void register_split_vertex(const Mesh::Vertex_index, const Mesh&) {} +}; + + +int main(int argc, char* argv[]) +{ + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/elk.off"); + + Mesh mesh; + if (!PMP::IO::read_polygon_mesh(filename, mesh) || !CGAL::is_triangle_mesh(mesh)) { + std::cerr << "Not a valid input file." << std::endl; + return 1; + } + + std::cout << "Start remeshing of " << filename + << " (" << num_faces(mesh) << " faces)..." << std::endl; + + CGAL::Bbox_3 bb = PMP::bbox(mesh); + My_sizing_field sizing_field(0.1, 30, bb.ymin(), bb.ymax()); + unsigned int nb_iter = 5; + + PMP::isotropic_remeshing( + faces(mesh), + sizing_field, + mesh, + CGAL::parameters::number_of_iterations(nb_iter) + .number_of_relaxation_steps(3) + ); + + CGAL::IO::write_polygon_mesh("custom_remesh_out.off", mesh, CGAL::parameters::stream_precision(17)); + + std::cout << "Remeshing done." << std::endl; + + return 0; +} diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/orient_polygon_soup_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/orient_polygon_soup_example.cpp index f603925bb6b..072ec4c6360 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/orient_polygon_soup_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/orient_polygon_soup_example.cpp @@ -15,7 +15,7 @@ #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Polyhedron_3 Polyhedron; +typedef CGAL::Polyhedron_3 Mesh; // Optional visitor for orientating a polygon soup to demonstrate usage for some functions. // inherits from the default class as some functions are not overloaded @@ -59,12 +59,12 @@ int main(int argc, char* argv[]) Visitor visitor; CGAL::Polygon_mesh_processing::orient_polygon_soup(points, polygons, CGAL::parameters::visitor(visitor)); - Polyhedron mesh; + Mesh mesh; CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, polygons, mesh); // Number the faces because 'orient_to_bound_a_volume' needs a face <--> index map int index = 0; - for(Polyhedron::Face_iterator fb=mesh.facets_begin(), fe=mesh.facets_end(); fb!=fe; ++fb) + for(Mesh::Face_iterator fb=mesh.facets_begin(), fe=mesh.facets_end(); fb!=fe; ++fb) fb->id() = index++; if(CGAL::is_closed(mesh)) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/point_inside_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/point_inside_example.cpp index 93b158ce192..1a8b207cd6b 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/point_inside_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/point_inside_example.cpp @@ -12,14 +12,14 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::Point_3 Point; -typedef CGAL::Polyhedron_3 Polyhedron; +typedef CGAL::Polyhedron_3 Mesh; namespace PMP = CGAL::Polygon_mesh_processing; -double max_coordinate(const Polyhedron& poly) +double max_coordinate(const Mesh& poly) { double max_coord = -std::numeric_limits::infinity(); - for(Polyhedron::Vertex_handle v : vertices(poly)) + for(Mesh::Vertex_handle v : vertices(poly)) { Point p = v->point(); max_coord = (std::max)(max_coord, CGAL::to_double(p.x())); @@ -33,14 +33,14 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/eight.off"); - Polyhedron poly; + Mesh poly; if(!PMP::IO::read_polygon_mesh(filename, poly) || CGAL::is_empty(poly) || !CGAL::is_triangle_mesh(poly)) { std::cerr << "Invalid input." << std::endl; return 1; } - CGAL::Side_of_triangle_mesh inside(poly); + CGAL::Side_of_triangle_mesh inside(poly); double size = max_coordinate(poly); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope.cpp index afbb938afb5..5cc9379992f 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope.cpp @@ -9,13 +9,13 @@ int main(int argc, char* argv[]) { typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; - typedef CGAL::Surface_mesh Surface_mesh; - typedef boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef CGAL::Surface_mesh Mesh; + typedef boost::graph_traits::vertex_descriptor vertex_descriptor; typedef CGAL::Polyhedral_envelope Envelope; std::ifstream in((argc>1) ? argv[1] : CGAL::data_file_path("meshes/blobby.off")); - Surface_mesh tmesh; + Mesh tmesh; in >> tmesh; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope_mesh_containment.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope_mesh_containment.cpp index 4e814c7dccd..ede5edf61e8 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope_mesh_containment.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope_mesh_containment.cpp @@ -13,19 +13,19 @@ int main(int argc, char* argv[]) { typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; - typedef CGAL::Surface_mesh Surface_mesh; + typedef CGAL::Surface_mesh Mesh; typedef CGAL::Polyhedral_envelope Envelope; std::ifstream in((argc>1) ? argv[1] : CGAL::data_file_path("meshes/blobby.off")); - Surface_mesh tmesh; + Mesh tmesh; in >> tmesh; // remesh the input using the longest edge size as target edge length - Surface_mesh query = tmesh; - Surface_mesh::Edge_iterator longest_edge_it = + Mesh query = tmesh; + Mesh::Edge_iterator longest_edge_it = std::max_element(edges(query).begin(), edges(query).end(), - [&query](Surface_mesh::Edge_index e1, Surface_mesh::Edge_index e2) + [&query](Mesh::Edge_index e1, Mesh::Edge_index e2) { return PMP::edge_length(halfedge(e1, query), query) < PMP::edge_length(halfedge(e2, query), query); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/random_perturbation_SM_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/random_perturbation_SM_example.cpp index 742685e7485..e043f6a9a77 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/random_perturbation_SM_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/random_perturbation_SM_example.cpp @@ -10,9 +10,9 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::Point_3 Point; -typedef CGAL::Surface_mesh Surface_mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::face_descriptor face_descriptor; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; namespace PMP = CGAL::Polygon_mesh_processing; @@ -20,7 +20,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/eight.off"); - Surface_mesh mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/refine_fair_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/refine_fair_example.cpp index 23053a6766c..30f1ed16a14 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/refine_fair_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/refine_fair_example.cpp @@ -13,8 +13,8 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef CGAL::Polyhedron_3 Polyhedron; -typedef Polyhedron::Vertex_handle Vertex_handle; +typedef CGAL::Polyhedron_3 Mesh; +typedef Mesh::Vertex_handle Vertex_handle; namespace PMP = CGAL::Polygon_mesh_processing; @@ -34,7 +34,7 @@ void extract_k_ring(Vertex_handle v, { v = qv[current_index++]; - Polyhedron::Halfedge_around_vertex_circulator e(v->vertex_begin()), e_end(e); + Mesh::Halfedge_around_vertex_circulator e(v->vertex_begin()), e_end(e); do { Vertex_handle new_v = e->opposite()->vertex(); if (D.insert(std::make_pair(new_v, dist_v + 1)).second) @@ -47,14 +47,14 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/blobby.off"); - Polyhedron poly; + Mesh poly; if(!PMP::IO::read_polygon_mesh(filename, poly) || !CGAL::is_triangle_mesh(poly)) { std::cerr << "Invalid input." << std::endl; return 1; } - std::vector new_facets; + std::vector new_facets; std::vector new_vertices; PMP::refine(poly, faces(poly), @@ -68,7 +68,7 @@ int main(int argc, char* argv[]) refined_off.close(); std::cout << "Refinement added " << new_vertices.size() << " vertices." << std::endl; - Polyhedron::Vertex_iterator v = poly.vertices_begin(); + Mesh::Vertex_iterator v = poly.vertices_begin(); std::advance(v, 82/*e.g.*/); std::vector region; extract_k_ring(v, 12/*e.g.*/, region); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_almost_planar_patches.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_almost_planar_patches.cpp index e3924c3e095..381183d0c99 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_almost_planar_patches.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_almost_planar_patches.cpp @@ -14,13 +14,13 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; -typedef CGAL::Surface_mesh Surface_mesh; +typedef CGAL::Surface_mesh Mesh; namespace PMP = CGAL::Polygon_mesh_processing; int main() { - Surface_mesh sm; + Mesh sm; CGAL::IO::read_polygon_mesh(CGAL::data_file_path("meshes/fandisk.off"), sm); //apply a perturbation to input vertices so that points are no longer coplanar @@ -51,7 +51,7 @@ int main() edge_is_constrained_map(CGAL::make_random_access_property_map(ecm))); // run the remeshing algorithm using filled properties - Surface_mesh out; + Mesh out; PMP::remesh_almost_planar_patches(sm, out, nb_regions, nb_corners, diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_planar_patches.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_planar_patches.cpp index 9f591e6a269..92aa3b15c6f 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_planar_patches.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_planar_patches.cpp @@ -12,12 +12,12 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; -typedef CGAL::Surface_mesh Surface_mesh; +typedef CGAL::Surface_mesh Mesh; namespace PMP = CGAL::Polygon_mesh_processing; int main() { - Surface_mesh sm; + Mesh sm; CGAL::IO::read_polygon_mesh(CGAL::data_file_path("meshes/cube_quad.off"), sm); // triangulate faces; @@ -25,8 +25,8 @@ int main() std::cout << "Input mesh has " << faces(sm).size() << " faces" << std::endl; assert(faces(sm).size()==12); - Surface_mesh::Property_map ecm = - sm.add_property_map("ecm",false).first; + Mesh::Property_map ecm = + sm.add_property_map("ecm",false).first; // detect sharp edges of the cube PMP::detect_sharp_edges(sm, 60, ecm); @@ -37,7 +37,7 @@ int main() assert(faces(sm).size()>100); // decimate the mesh - Surface_mesh out; + Mesh out; PMP::remesh_planar_patches(sm, out); CGAL::IO::write_polygon_mesh("cube_decimated.off", out, CGAL::parameters::stream_precision(17)); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp new file mode 100644 index 00000000000..fa60ae6538f --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp @@ -0,0 +1,47 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_3 Point; + +typedef CGAL::Point_set_3 Point_set; + +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char* argv[]) +{ + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/eight.off"); + + Mesh mesh; + if(!PMP::IO::read_polygon_mesh(filename, mesh)) + { + std::cerr << "Invalid input." << std::endl; + return 1; + } + + const int points_per_face = (argc > 2) ? std::stoi(argv[2]) : 10; + + std::vector points; + PMP::sample_triangle_mesh(mesh, + std::back_inserter(points), + CGAL::parameters::number_of_points_per_face(points_per_face)); + + + Point_set point_set; + PMP::sample_triangle_mesh(mesh, + point_set.point_back_inserter()); + + std::cout << point_set.number_of_points() << std::endl; + return 0; +} diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp new file mode 100644 index 00000000000..a76e1254f6e --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point; + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char** argv) +{ + const std::string filename = argc == 1 ? CGAL::data_file_path("meshes/elephant.off") + : std::string(argv[1]); + + std::vector input_points; + std::vector> input_triangles; + CGAL::IO::read_polygon_soup(filename, input_points, input_triangles); + PMP::repair_polygon_soup(input_points, input_triangles); + PMP::triangulate_polygons(input_points, input_triangles); + + CGAL::Real_timer t; + t.start(); + PMP::autorefine_triangle_soup(input_points, input_triangles, + CGAL::parameters::concurrency_tag(CGAL::Parallel_if_available_tag())); + t.stop(); + std::cout << "#points = " << input_points.size() << " and #triangles = " << input_triangles.size() << " in " << t.time() << " sec." << std::endl; + CGAL::IO::write_polygon_soup("autorefined.off", input_points, input_triangles, CGAL::parameters::stream_precision(17)); + + return 0; +} diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example.cpp index a7afc963ed7..28d770626e2 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example.cpp @@ -9,7 +9,7 @@ #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Polyhedron_3 Polyhedron; +typedef CGAL::Polyhedron_3 Mesh; namespace PMP = CGAL::Polygon_mesh_processing; @@ -17,7 +17,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/quads_to_stitch.off"); - Polyhedron mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example_OM.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example_OM.cpp index b731e8c0220..cf97918fd3b 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example_OM.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example_OM.cpp @@ -10,8 +10,8 @@ #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; - typedef OpenMesh::PolyMesh_ArrayKernelT< > Mesh; + int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/quads_to_stitch.off"); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangle_mesh_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangle_mesh_autorefinement.cpp new file mode 100644 index 00000000000..65db52fef2c --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangle_mesh_autorefinement.cpp @@ -0,0 +1,29 @@ +#include +#include + +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point; + +typedef CGAL::Surface_mesh Mesh; + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char** argv) +{ + Mesh mesh; + + const std::string filename = argc == 1 ? CGAL::data_file_path("meshes/elephant.off") + : std::string(argv[1]); + CGAL::IO::read_polygon_mesh(filename, mesh); + + PMP::autorefine(mesh); + + CGAL::IO::write_polygon_mesh("autorefined.off", mesh, CGAL::parameters::stream_precision(17)); + + return 0; +} diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_example.cpp index 7587d012363..9c7ef677bc0 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_example.cpp @@ -11,7 +11,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; -typedef CGAL::Surface_mesh Surface_mesh; +typedef CGAL::Surface_mesh Mesh; namespace PMP = CGAL::Polygon_mesh_processing; @@ -20,7 +20,7 @@ int main(int argc, char* argv[]) const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/P.off"); const char* outfilename = (argc > 2) ? argv[2] : "P_tri.off"; - Surface_mesh mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Error: Invalid input." << std::endl; @@ -41,7 +41,7 @@ int main(int argc, char* argv[]) PMP::triangulate_faces(mesh); // Confirm that all faces are triangles. - for(boost::graph_traits::face_descriptor f : faces(mesh)) + for(boost::graph_traits::face_descriptor f : faces(mesh)) { if(!CGAL::is_triangle(halfedge(f, mesh), mesh)) std::cerr << "Error: non-triangular face left in mesh." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp index 9b246f7678d..84695b32e32 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp @@ -6,15 +6,14 @@ #include #include -#include #include #include #include typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef Kernel::Point_3 Point; -typedef CGAL::Surface_mesh Surface_mesh; -typedef boost::graph_traits::face_descriptor face_descriptor; +typedef Kernel::Point_3 Point; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::face_descriptor face_descriptor; class Insert_iterator { @@ -41,7 +40,7 @@ public: }; -struct Visitor : public CGAL::Polygon_mesh_processing::Triangulate_faces::Default_visitor +struct Visitor : public CGAL::Polygon_mesh_processing::Triangulate_faces::Default_visitor { typedef std::unordered_map Container; @@ -78,7 +77,7 @@ int main(int argc, char* argv[]) const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/P.off"); std::ifstream input(filename); - Surface_mesh mesh; + Mesh mesh; if (!input || !(input >> mesh) || mesh.is_empty()) { std::cerr << "Not a valid off file." << std::endl; @@ -87,7 +86,7 @@ int main(int argc, char* argv[]) std::unordered_map t2q; - Surface_mesh copy; + Mesh copy; CGAL::copy_face_graph(mesh, copy, CGAL::parameters::face_to_face_output_iterator(Insert_iterator(t2q))); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp index bd4181c3ff4..e07c803b83e 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp @@ -12,7 +12,7 @@ #include typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef CGAL::Surface_mesh Surface_mesh; +typedef CGAL::Surface_mesh Mesh; namespace PMP = CGAL::Polygon_mesh_processing; namespace params = CGAL::parameters; @@ -21,7 +21,7 @@ int main(int argc, char** argv) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/blobby.off"); - Surface_mesh mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; @@ -29,8 +29,8 @@ int main(int argc, char** argv) } // property map to assign a volume id for each face - Surface_mesh::Property_map vol_id_map = - mesh.add_property_map().first; + Mesh::Property_map vol_id_map = + mesh.add_property_map().first; // fill the volume id map std::vector err_codes; @@ -39,7 +39,7 @@ int main(int argc, char** argv) std::cout << "Found " << nb_vol << " volumes\n"; // write each volume in an OFF file - typedef CGAL::Face_filtered_graph Filtered_graph; + typedef CGAL::Face_filtered_graph Filtered_graph; Filtered_graph vol_mesh(mesh, 0, vol_id_map); for(std::size_t id = 0; id < nb_vol; ++id) { @@ -49,11 +49,12 @@ int main(int argc, char** argv) if(id > 0) vol_mesh.set_selected_faces(id, vol_id_map); - Surface_mesh out; + Mesh out; CGAL::copy_face_graph(vol_mesh, out); std::ostringstream oss; oss << "vol_" << id <<".off"; std::ofstream os(oss.str().data()); os << out; } + return 0; } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h index a61edc699d0..e673ac9dfbb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h @@ -38,6 +38,8 @@ namespace Polygon_mesh_processing * Edges too long with respect to the local target edge length are split in two, while * edges that are too short are collapsed. * +* This class depends on the \eigen library. +* * \cgalModels{PMPSizingField} * * \sa `isotropic_remeshing()` @@ -213,13 +215,13 @@ private: } public: - FT at(const vertex_descriptor v) const + FT at(const vertex_descriptor v, const PolygonMesh& /* pmesh */) const { CGAL_assertion(get(m_vertex_sizing_map, v)); return get(m_vertex_sizing_map, v); } - std::optional is_too_long(const vertex_descriptor va, const vertex_descriptor vb) const + std::optional is_too_long(const vertex_descriptor va, const vertex_descriptor vb, const PolygonMesh& /* pmesh */) const { const FT sqlen = sqlength(va, vb); FT sqtarg_len = CGAL::square(4./3. * (CGAL::min)(get(m_vertex_sizing_map, va), @@ -251,7 +253,7 @@ public: get(m_vpmap, source(h, pmesh))); } - void update(const vertex_descriptor v, const PolygonMesh& pmesh) + void register_split_vertex(const vertex_descriptor v, const PolygonMesh& pmesh) { // calculating it as the average of two vertices on other ends // of halfedges as updating is done during an edge split diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h index f2d93e83f01..21600e50bff 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include #include diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h index 8177a02d178..e8901ebd727 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h @@ -28,8 +28,8 @@ struct Non_manifold_feature_map typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; typedef dynamic_edge_property_t Edge_to_id_tag; typedef dynamic_vertex_property_t Vertex_to_id_tag; - typedef typename boost::property_map::type Edge_to_nm_id; - typedef typename boost::property_map::type Vertex_to_nm_id; + typedef typename boost::property_map::const_type Edge_to_nm_id; + typedef typename boost::property_map::const_type Vertex_to_nm_id; Edge_to_nm_id e_nm_id; Vertex_to_nm_id v_nm_id; std::vector< std::vector > non_manifold_edges; @@ -39,7 +39,7 @@ struct Non_manifold_feature_map {} template - Non_manifold_feature_map(PolygonMesh& pm, Vpm vpm) + Non_manifold_feature_map(const PolygonMesh& pm, Vpm vpm) : e_nm_id(get(Edge_to_id_tag(), pm)) , v_nm_id(get(Vertex_to_id_tag(), pm)) { @@ -99,6 +99,14 @@ struct Non_manifold_feature_map } } } + + void clear() + { + non_manifold_edges.clear(); + non_manifold_vertices.clear(); + e_nm_id = Edge_to_nm_id(); + v_nm_id = Vertex_to_nm_id(); + } }; } } // end of CGAL::Polygon_mesh_processing diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Uniform_sizing_field.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Uniform_sizing_field.h index a4144ceee65..d14f4be9666 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Uniform_sizing_field.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Uniform_sizing_field.h @@ -102,12 +102,12 @@ private: } public: - FT at(const vertex_descriptor /* v */) const + FT at(const vertex_descriptor /* v */, const PolygonMesh& /* pmesh */) const { return m_size; } - std::optional is_too_long(const vertex_descriptor va, const vertex_descriptor vb) const + std::optional is_too_long(const vertex_descriptor va, const vertex_descriptor vb, const PolygonMesh& /* pmesh */) const { const FT sqlen = sqlength(va, vb); if (sqlen > m_sq_long) @@ -133,7 +133,7 @@ public: get(m_vpmap, source(h, pmesh))); } - void update(const vertex_descriptor /* v */, const PolygonMesh& /* pmesh */) + void register_split_vertex(const vertex_descriptor /* v */, const PolygonMesh& /* pmesh */) {} private: diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h new file mode 100644 index 00000000000..a3606f816a7 --- /dev/null +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -0,0 +1,1414 @@ +// Copyright (c) 2023 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Sebastien Loriot +// + +#ifndef CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H +#define CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CGAL_AUTOREF_USE_PROGRESS_DISPLAY +#include +#endif + +// output +#include +#include +#include + + +#ifdef CGAL_PMP_AUTOREFINE_USE_DEFAULT_VERBOSE +#define CGAL_PMP_AUTOREFINE_VERBOSE(X) std::cout << X << "\n"; +#endif + +#ifndef CGAL_PMP_AUTOREFINE_VERBOSE +#define CGAL_PMP_AUTOREFINE_VERBOSE(MSG) +#endif + +#ifdef CGAL_LINKED_WITH_TBB +#include +#if TBB_INTERFACE_VERSION < 12010 && !defined(TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS) +#define CGAL_HAS_DEFINED_TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS +#define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS 1 +#endif +#include +#include +#ifdef CGAL_AUTOREF_SET_POINT_IDS_USING_MUTEX +#include +#endif +#endif + +#include + +//#define CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS +//#define CGAL_AUTOREFINE_DEBUG_COUNTERS +//#define CGAL_AUTOREF_DEBUG_DEPTH + +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS +#include +#endif + +#if defined(CGAL_AUTOREFINE_DEBUG_COUNTERS) || defined(CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS) +#include +#endif + +namespace CGAL { +namespace Polygon_mesh_processing { + +namespace Autorefinement { + +/** \ingroup PMP_corefinement_grp + * %Default visitor model of `PMPAutorefinementVisitor`. + * All of its functions have an empty body. This class can be used as a + * base class if only some of the functions of the concept require to be + * overridden. + */ +struct Default_visitor +{ + inline void number_of_output_triangles(std::size_t /*nbt*/) {} + inline void verbatim_triangle_copy(std::size_t /*tgt_id*/, std::size_t /*src_id*/) {} + inline void new_subtriangle(std::size_t /*tgt_id*/, std::size_t /*src_id*/) {} +}; + +} // end of Autorefinement visitor + + +#ifndef DOXYGEN_RUNNING +namespace autorefine_impl { + +enum Segment_inter_type { NO_INTERSECTION=0, + POINT_INTERSECTION, + POINT_P, + POINT_Q, + POINT_R, + POINT_S, + COPLANAR_SEGMENT_PQ, + COPLANAR_SEGMENT_RS, + COPLANAR_SEGMENT_PS, + COPLANAR_SEGMENT_QS, + COPLANAR_SEGMENT_PR, + COPLANAR_SEGMENT_QR, + }; + +// test intersection in the interior of segment pq and rs with pq and rs being coplanar segments +// note that for coplanar cases, we might report identical endpoints +template +Segment_inter_type +do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, + std::size_t ri, std::size_t si, + const std::vector& points, + const typename K::Vector_3& /* plane_normal */, + const K& k = K()) +{ + typename K::Collinear_are_ordered_along_line_3 cln_order = k.collinear_are_ordered_along_line_3_object(); + typename K::Coplanar_orientation_3 cpl_orient=k.coplanar_orientation_3_object(); + + const typename K::Point_3& p=points[pi]; + const typename K::Point_3& q=points[qi]; + const typename K::Point_3& r=points[ri]; + const typename K::Point_3& s=points[si]; + + // first handle case of shared endpoints + if (pi==ri) + { + if (si==qi || cpl_orient(p, q, s)!=COLLINEAR) return NO_INTERSECTION; + // can be s, q or nothing + if (cln_order(p,s,q)) + return POINT_S; + if (cln_order(p,q,s)) + return POINT_Q; + return NO_INTERSECTION; + } + else + { + if(pi==si) + { + if (qi==ri || cpl_orient(p, q, r)!=COLLINEAR) return NO_INTERSECTION; + // can be r, q or nothing + if (cln_order(p,r,q)) + return POINT_R; + if (cln_order(p,q,r)) + return POINT_Q; + return NO_INTERSECTION; + } + else + { + if (qi==ri) + { + if (pi==si || cpl_orient(p, q, s)!=COLLINEAR) return NO_INTERSECTION; + // can be p, s or nothing + if (cln_order(p,s,q)) + return POINT_S; + if (cln_order(q,p,s)) + return POINT_P; + return NO_INTERSECTION; + } + else + { + if (qi==si) + { + if (pi==ri || cpl_orient(p, q, r)!=COLLINEAR) return NO_INTERSECTION; + // can be p, r or nothing + if (cln_order(p,r,q)) + return POINT_R; + if (cln_order(q,p,r)) + return POINT_P; + return NO_INTERSECTION; + } + } + } + } + + // supporting_line intersects: points are coplanar + ::CGAL::Orientation pqr = cpl_orient(p, q, r); + ::CGAL::Orientation pqs = cpl_orient(p, q, s); + + if(pqr == COLLINEAR && pqs == COLLINEAR) + { + // segments are collinear + bool r_in_pq = cln_order(p, r, q), + s_in_pq = cln_order(p, s, q), + p_in_rs = cln_order(r, p, s); + + if (r_in_pq) + { + // intersection could be rs, pr or qr + if (s_in_pq) + return COPLANAR_SEGMENT_RS; + if (p_in_rs) + return COPLANAR_SEGMENT_PR; + CGAL_assertion(cln_order(r, q, s)); + return COPLANAR_SEGMENT_QR; + } + else + { + if (s_in_pq) + { + // intersection could be ps or qs + if (p_in_rs) + return COPLANAR_SEGMENT_PS; + CGAL_assertion(cln_order(r, q, s)); + return COPLANAR_SEGMENT_QS; + } + else + if (p_in_rs) + { + CGAL_assertion(cln_order(r, q, s)); + return COPLANAR_SEGMENT_PQ; + } + } + return NO_INTERSECTION; + } + + if(pqr != pqs) + { + ::CGAL::Orientation rsp = cpl_orient(r, s, p); + + if (rsp==COLLINEAR) + { + if (pqr==COLLINEAR || pqs==COLLINEAR) + { + throw std::runtime_error("no expected #1"); + } + return POINT_P; + } + ::CGAL::Orientation rsq = cpl_orient(r, s, q); + if (rsq==COLLINEAR) + { + if (pqr==COLLINEAR || pqs==COLLINEAR) + { + throw std::runtime_error("no expected #2"); + } + return POINT_Q; + } + if (rsp!=rsq) + { + if (pqr==COLLINEAR) return POINT_R; + if (pqs==COLLINEAR) return POINT_S; + return POINT_INTERSECTION; + } + } + + return NO_INTERSECTION; +} + +// imported from Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h +template +void coplanar_intersections(const std::array& t1, + const std::array& t2, + std::vector& inter_pts) +{ + const typename K::Point_3& p1 = t1[0], q1 = t1[1], r1 = t1[2]; + const typename K::Point_3& p2 = t2[0], q2 = t2[1], r2 = t2[2]; + + std::list> l_inter_pts; + l_inter_pts.push_back(Intersections::internal::Point_on_triangle(-1,0)); + l_inter_pts.push_back(Intersections::internal::Point_on_triangle(-1,1)); + l_inter_pts.push_back(Intersections::internal::Point_on_triangle(-1,2)); + + //intersect t2 with the three half planes which intersection defines t1 + K k; + Intersections::internal::intersection_coplanar_triangles_cutoff(p1,q1,r1,0,p2,q2,r2,k,l_inter_pts); //line p1q1 + Intersections::internal::intersection_coplanar_triangles_cutoff(q1,r1,p1,1,p2,q2,r2,k,l_inter_pts); //line q1r1 + Intersections::internal::intersection_coplanar_triangles_cutoff(r1,p1,q1,2,p2,q2,r2,k,l_inter_pts); //line r1p1 + + for (const Intersections::internal::Point_on_triangle& pot : l_inter_pts) + inter_pts.push_back( pot.point(p1,q1,r1,p2,q2,r2,k) ); +} + +// imported from Polygon_mesh_processing/internal/Corefinement/intersect_triangle_segment_3.h +template +void +find_intersection(const typename K::Point_3& p, const typename K::Point_3& q, //segment + const typename K::Point_3& a, const typename K::Point_3& b, const typename K::Point_3& c, //triangle + std::vector& inter_pts, + bool is_p_coplanar=false, bool is_q_coplanar=false) // note that in coref this was wrt a halfedge not p/q +{ + Orientation ab=orientation(p,q,a,b); + Orientation bc=orientation(p,q,b,c); + Orientation ca=orientation(p,q,c,a); + + if ( ab==POSITIVE || bc==POSITIVE || ca==POSITIVE ) + return; + + int nb_coplanar=(ab==COPLANAR?1:0) + (bc==COPLANAR?1:0) + (ca==COPLANAR?1:0); + + if (is_p_coplanar) + { + inter_pts.push_back(p); + return; + } + if (is_q_coplanar) + { + inter_pts.push_back(q); + return; + } + + if (nb_coplanar!=2) + { + inter_pts.push_back( + typename K::Construct_plane_line_intersection_point_3()(a, b, c, p, q) + ); + } + else + { + if (ab!=COPLANAR) + { + // intersection is c + inter_pts.push_back(c); + return; + } + + if (bc!=COPLANAR) + { + // intersection is a + inter_pts.push_back(a); + return; + } + CGAL_assertion(ca!=COPLANAR); + // intersection is b + inter_pts.push_back(b); + } +} + +template +void test_edge(const typename K::Point_3& p, const typename K::Point_3& q, + const typename K::Point_3& a, const typename K::Point_3& b, const typename K::Point_3& c, + const Orientation abcp, + const Orientation abcq, + std::vector& inter_pts) +{ + switch ( abcp ) { + case POSITIVE: + switch ( abcq ) { + case POSITIVE: + // the segment lies in the positive open halfspaces defined by the + // triangle's supporting plane + break; + case NEGATIVE: + // p sees the triangle in counterclockwise order + find_intersection(p,q,a,b,c,inter_pts); + break; + //case COPLANAR: + default: + // q belongs to the triangle's supporting plane + // p sees the triangle in counterclockwise order + find_intersection(p,q,a,b,c,inter_pts,false,true); + } + break; + case NEGATIVE: + switch ( abcq ) { + case POSITIVE: + // q sees the triangle in counterclockwise order + find_intersection(q,p,a,b,c,inter_pts); + break; + case NEGATIVE: + // the segment lies in the negative open halfspaces defined by the + // triangle's supporting plane + break; + // case COPLANAR: + default: + // q belongs to the triangle's supporting plane + // p sees the triangle in clockwise order + find_intersection(q,p,a,b,c,inter_pts,true,false); + } + break; + default: + //case COPLANAR: // p belongs to the triangle's supporting plane + switch ( abcq ) { + case POSITIVE: + // q sees the triangle in counterclockwise order + find_intersection(q,p,a,b,c,inter_pts,false, true); + break; + case NEGATIVE: + // q sees the triangle in clockwise order + find_intersection(p,q,a,b,c,inter_pts,true); + break; + //case COPLANAR: + default: + // the segment is coplanar with the triangle's supporting plane + // we test whether the segment intersects the triangle in the common + // supporting plane + //if ( ::CGAL::Intersections::internal::do_intersect_coplanar(a,b,c,p,q,K()) ) + //{ + //handle coplanar intersection + // nothing done as coplanar case handle in collect_intersections + // and other intersection points will be collected with non-coplanar edges + //} + break; + } + } +} + +template +bool collect_intersections(const std::array& t1, + const std::array& t2, + std::vector& inter_pts) +{ + // test edges of t1 vs t2 + std::array ori; + for (int i=0; i<3; ++i) + ori[i] = orientation(t2[0],t2[1],t2[2],t1[i]); + + if (ori[0]== COPLANAR && ori[1]==COPLANAR && ori[2]==COPLANAR) + { + coplanar_intersections(t1, t2, inter_pts); +#ifdef CGAL_AUTOREF_DEBUG_DEPTH + for (auto p : inter_pts) + if (depth(p)>2) throw std::runtime_error("Depth is not 4: "+std::to_string(depth(p))); +#endif + + return true; + } + + for (int i=0; i<3; ++i) + { + int j=(i+1)%3; + test_edge(t1[i], t1[j], t2[0], t2[1], t2[2], ori[i], ori[j], inter_pts); + } + + // test edges of t2 vs t1 + for (int i=0; i<3; ++i) + ori[i] = orientation(t1[0],t1[1],t1[2],t2[i]); + for (int i=0; i<3; ++i) + { + int j=(i+1)%3; + test_edge(t2[i], t2[j], t1[0], t1[1], t1[2], ori[i], ori[j], inter_pts); + } + + // because we don't handle intersection type and can have edge-edge edge-vertex duplicates + std::sort(inter_pts.begin(), inter_pts.end()); + auto last = std::unique(inter_pts.begin(), inter_pts.end()); + inter_pts.erase(last, inter_pts.end()); + +#ifdef CGAL_AUTOREF_DEBUG_DEPTH + for (auto p : inter_pts) + if (depth(p)>2) throw std::runtime_error("Depth is not 2: "+std::to_string(depth(p))); +#endif + + return false; +} + +template +void generate_subtriangles(std::size_t ti, + std::vector>& segments, + std::vector& points, + const std::vector& in_triangle_ids, + const std::set >& intersecting_triangles, + const std::set >& coplanar_triangles, + const std::vector>& triangles, + PointVector& new_triangles + ) +{ + typedef CGAL::Projection_traits_3 P_traits; + typedef CGAL::No_constraint_intersection_tag Itag; + + typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_2; + //typedef CGAL::Constrained_triangulation_plus_2 CDT; + typedef CDT_2 CDT; + + const std::array& t = triangles[ti]; + + // positive triangle normal + typename EK::Vector_3 n = normal(t[0], t[1], t[2]); + typename EK::Point_3 o(CGAL::ORIGIN); + + bool orientation_flipped = false; + if ( typename EK::Less_xyz_3()(o+n,o) ) + { + n=-n; + orientation_flipped = true; + } + + P_traits cdt_traits(n); + CDT cdt(cdt_traits); + cdt.insert_outside_affine_hull(t[0]); + cdt.insert_outside_affine_hull(t[1]); + typename CDT::Vertex_handle v = cdt.tds().insert_dim_up(cdt.infinite_vertex(), orientation_flipped); + v->set_point(t[2]); + +#ifdef CGAL_AUTOREFINE_DEBUG_COUNTERS + struct Counter + { + int c1=0; + int c2=0; + int c3=0; + int c4=0; + int c5=0; + int total=0; + ~Counter() + { + std::cout << "intersection of 3 planes: " << c1 << "\n"; + std::cout << "coplanar segment intersection : " << c2 << "\n"; + std::cout << "coplanar segment overlap: " << c3 << "\n"; + std::cout << "no intersection: " << c4 << "\n"; + std::cout << "intersection filtered with bboxes: " << c5 << "\n"; + std::cout << "# pairs of segments : " << total << "\n"; + std::cout << "time computing segment intersections: " << timer1.time() << "\n"; + std::cout << "time sorting intersection points: " << timer2.time() << "\n"; + std::cout << "time for cdt of constraints: " << timer3.time() << "\n"; + std::cout << "time coplanar segment intersections: " << timer4.time() << "\n"; + std::cout << "time of do_coplanar_segments_intersect: " << timer5.time() << "\n"; + std::cout << "time of triplane intersection: " << timer6.time() << "\n"; + } + CGAL::Real_timer timer1, timer2, timer3, timer4, timer5, timer6; + }; + + static Counter counter; +#define CGAL_AUTOREF_COUNTER_INSTRUCTION(X) X +#else +#define CGAL_AUTOREF_COUNTER_INSTRUCTION(X) +#endif + + // pre-compute segment intersections + if (!segments.empty()) + { + std::size_t nbs = segments.size(); + + std::vector< std::vector > points_on_segments(nbs); + + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer1.start();) + + std::map point_id_map; + + for (std::size_t pid=0; pidsecond; + }; + + std::vector point_boxes(points.size()); + for (std::size_t i = 0; i segment_boxes(nbs); + for (std::size_t i = 0; i(segments[i].first, segments[i].second, + segments[j].first, segments[j].second, + points, n); + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer5.stop();) + + switch(seg_inter_type) + { + case POINT_P: + { + points_on_segments[j].push_back(segments[i].first); + break; + } + case POINT_Q: + { + points_on_segments[j].push_back(segments[i].second); + break; + } + case POINT_R: + { + points_on_segments[i].push_back(segments[j].first); + break; + } + case POINT_S: + { + points_on_segments[i].push_back(segments[j].second); + break; + } + case POINT_INTERSECTION: + { + if ( coplanar_triangles.count(CGAL::make_sorted_pair(in_triangle_ids[i], in_triangle_ids[j])) == 0 + && coplanar_triangles.count(CGAL::make_sorted_pair(ti, in_triangle_ids[j])) == 0 + && coplanar_triangles.count(CGAL::make_sorted_pair(in_triangle_ids[i], ti)) == 0) + { + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer6.start();) + typename EK::Point_3 pt = typename EK::Construct_planes_intersection_point_3()( + triangles[in_triangle_ids[i]][0], triangles[in_triangle_ids[i]][1],triangles[in_triangle_ids[i]][2], + triangles[in_triangle_ids[j]][0], triangles[in_triangle_ids[j]][1],triangles[in_triangle_ids[j]][2], + triangles[ti][0], triangles[ti][1],triangles[ti][2]); + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer6.stop();) + + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c1;) + std::size_t pid = get_point_id(pt); + points_on_segments[i].push_back(pid); + points_on_segments[j].push_back(pid); + } + else + { + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c2;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer4.start();) + typename EK::Point_3 pt = typename EK::Construct_coplanar_segments_intersection_point_3()( + points[segments[i].first], points[segments[i].second], + points[segments[j].first], points[segments[j].second]); + + std::size_t pid = get_point_id(pt); + points_on_segments[i].push_back(pid); + points_on_segments[j].push_back(pid); + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer4.stop();) + } + break; + } + case COPLANAR_SEGMENT_PQ: + { + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) + points_on_segments[j].push_back(segments[i].first); + points_on_segments[j].push_back(segments[i].second); + break; + } + case COPLANAR_SEGMENT_RS: + { + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) + points_on_segments[i].push_back(segments[j].first); + points_on_segments[i].push_back(segments[j].second); + break; + } + case COPLANAR_SEGMENT_PR: + { + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) + points_on_segments[i].push_back(segments[j].first); + points_on_segments[j].push_back(segments[i].first); + break; + } + case COPLANAR_SEGMENT_QS: + { + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) + points_on_segments[i].push_back(segments[j].second); + points_on_segments[j].push_back(segments[i].second); + break; + } + case COPLANAR_SEGMENT_PS: + { + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) + points_on_segments[i].push_back(segments[j].second); + points_on_segments[j].push_back(segments[i].first); + break; + } + case COPLANAR_SEGMENT_QR: + { + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) + points_on_segments[i].push_back(segments[j].first); + points_on_segments[j].push_back(segments[i].second); + break; + } + case NO_INTERSECTION: + { + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c4;) + } + } + } + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.total;) + } + } + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer1.stop();) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer2.start();) + std::size_t nb_new_segments=0; + for (std::size_t i = 0; itgt[coord]) + { + std::swap(src_id, tgt_id); + std::swap(src, tgt); + } + + points_on_segments[i].push_back(src_id); + std::swap(points_on_segments[i].front(), points_on_segments[i].back()); + std::sort(std::next(points_on_segments[i].begin()), points_on_segments[i].end(), + [&](std::size_t id1, std::size_t id2) + { + if (id1==id2) return false; + return points[id1][coord](points.begin(), points.end()).size()); + CGAL_assertion(points.size()==point_id_map.size()); + } + + for (std::pair& s : segments) + if (s.second < s.first) + std::swap(s.first,s.second); + std::sort(segments.begin(), segments.end()); + auto last = std::unique(segments.begin(), segments.end()); + segments.erase(last, segments.end()); + + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer3.start();) + if (segments.empty()) + cdt.insert(points.begin(), points.end()); + else + cdt.insert_constraints(points.begin(), points.end(), segments.begin(), segments.end()); + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer3.stop();) + + for (typename CDT::Face_handle fh : cdt.finite_face_handles()) + { + if (orientation_flipped) + new_triangles.push_back( { CGAL::make_array(fh->vertex(0)->point(), + fh->vertex(cdt.cw(0))->point(), + fh->vertex(cdt.ccw(0))->point()), ti } ); + else + new_triangles.push_back( { CGAL::make_array(fh->vertex(0)->point(), + fh->vertex(cdt.ccw(0))->point(), + fh->vertex(cdt.cw(0))->point()), ti } ); + } +} + +} // end of autorefine_impl +#endif + +/** +* \ingroup PMP_corefinement_grp +* +* refines a soup of triangles so that no pair of triangles intersects. +* Output triangles may share a common edge or a common vertex (but with the same indexed position in `points`). +* Note that points in `soup_points` can only be added (intersection points) at the end of the container, with the initial order preserved. +* Note that if `soup_points` contains two or more identical points then only the first copy (following the order in the `soup_points`) +* will be used in `soup_triangles`. +* `soup_triangles` will be updated to contain both the input triangles and the new subdivided triangles. Degenerate triangles will be removed. +* Also triangles in `soup_triangles` will be triangles without intersection first, followed by triangles coming from a subdivision induced +* by an intersection. The named parameter `visitor()` can be used to track +* +* @tparam PointRange a model of the concept `RandomAccessContainer` +* whose value type is the point type +* @tparam TriangleRange a model of the concepts `RandomAccessContainer`, `BackInsertionSequence` and `Swappable`, whose +* value type is a model of the concept `RandomAccessContainer` whose value type is convertible to `std::size_t` and that +* is constructible from an `std::initializer_list` of size 3. +* @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" +* +* @param soup_points points of the soup of polygons +* @param soup_triangles each element in the range describes a triangle using the indexed position of the points in `soup_points` +* @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below +* +* \cgalNamedParamsBegin +* \cgalParamNBegin{concurrency_tag} +* \cgalParamDescription{a tag indicating if the task should be done using one or several threads.} +* \cgalParamType{Either `CGAL::Sequential_tag`, or `CGAL::Parallel_tag`, or `CGAL::Parallel_if_available_tag`} +* \cgalParamDefault{`CGAL::Sequential_tag`} +* \cgalParamNEnd +* \cgalParamNBegin{point_map} +* \cgalParamDescription{a property map associating points to the elements of the range `soup_points`} +* \cgalParamType{a model of `ReadWritePropertyMap` whose value type is a point type} +* \cgalParamDefault{`CGAL::Identity_property_map`} +* \cgalParamNEnd +* \cgalParamNBegin{geom_traits} +* \cgalParamDescription{an instance of a geometric traits class} +* \cgalParamType{a class model of `Kernel`} +* \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`} +* \cgalParamExtra{The geometric traits class must be compatible with the point type.} +* \cgalParamNEnd +* \cgalParamNBegin{visitor} +* \cgalParamDescription{a visitor used to track the creation of new faces} +* \cgalParamType{a class model of `PMPAutorefinementVisitor`} +* \cgalParamDefault{`Autorefinement::Default_visitor`} +* \cgalParamExtra{The visitor will be copied.} +* \cgalParamNEnd +* \cgalNamedParamsEnd +* +*/ +template +void autorefine_triangle_soup(PointRange& soup_points, + TriangleRange& soup_triangles, + const NamedParameters& np = parameters::default_values()) +{ + using parameters::choose_parameter; + using parameters::get_parameter; + + typedef typename GetPolygonSoupGeomTraits::type GT; + typedef typename GetPointMap::const_type Point_map; + Point_map pm = choose_parameter(get_parameter(np, internal_np::point_map)); + + typedef typename internal_np::Lookup_named_param_def < + internal_np::concurrency_tag_t, + NamedParameters, + Sequential_tag + > ::type Concurrency_tag; + + // visitor + typedef typename internal_np::Lookup_named_param_def < + internal_np::visitor_t, + NamedParameters, + Autorefinement::Default_visitor//default + > ::type Visitor; + Visitor visitor(choose_parameter(get_parameter(np, internal_np::visitor))); + + + constexpr bool parallel_execution = std::is_same_v; + +#ifndef CGAL_LINKED_WITH_TBB + static_assert (!parallel_execution, + "Parallel_tag is enabled but TBB is unavailable."); +#endif + + typedef std::size_t Input_TID; + typedef std::pair Pair_of_triangle_ids; + + // no need for a concurrent vector as the called function itself + // takes care of sequentially writing into the output iterator + std::vector si_pairs; + + // collect intersecting pairs of triangles + CGAL_PMP_AUTOREFINE_VERBOSE("collect intersecting pairs"); + triangle_soup_self_intersections(soup_points, soup_triangles, std::back_inserter(si_pairs), np); + + if (si_pairs.empty()) + { + if constexpr (!std::is_same_v) + { + visitor.number_of_output_triangles(soup_triangles.size()); + for(std::size_t i=0; i is_degen(soup_triangles.size(), false); + + for (const Pair_of_triangle_ids& p : si_pairs) + if (p.first==p.second) // bbox inter reports (f,f) for degenerate faces + is_degen[p.first] = true; + + // assign an id per triangle involved in an intersection + // + the faces involved in the intersection + std::vector tri_inter_ids(soup_triangles.size(), -1); + std::vector intersected_faces; + int tiid=-1; + for (const Pair_of_triangle_ids& p : si_pairs) + { + if (tri_inter_ids[p.first]==-1 && !is_degen[p.first]) + { + tri_inter_ids[p.first]=++tiid; + intersected_faces.push_back(p.first); + } + if (tri_inter_ids[p.second]==-1 && !is_degen[p.second]) + { + tri_inter_ids[p.second]=++tiid; + intersected_faces.push_back(p.second); + } + } + + // init the vector of triangles used for the autorefinement of triangles + typedef CGAL::Exact_predicates_exact_constructions_kernel EK; + std::vector< std::array > triangles(tiid+1); + Cartesian_converter to_exact; + + for(Input_TID f : intersected_faces) + { + triangles[tri_inter_ids[f]]= CGAL::make_array( + to_exact( get(pm, soup_points[soup_triangles[f][0]]) ), + to_exact( get(pm, soup_points[soup_triangles[f][1]]) ), + to_exact( get(pm, soup_points[soup_triangles[f][2]]) ) ); + } + + std::vector< std::vector > > all_segments(triangles.size()); + std::vector< std::vector > all_points(triangles.size()); + std::vector< std::vector > all_in_triangle_ids(triangles.size()); + + CGAL_PMP_AUTOREFINE_VERBOSE("compute intersections"); +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS + Real_timer t; + t.start(); +#endif + std::set > intersecting_triangles; + std::set > coplanar_triangles; + //TODO: PARALLEL_FOR #2 + for (const Pair_of_triangle_ids& p : si_pairs) + { + int i1 = tri_inter_ids[p.first], + i2 = tri_inter_ids[p.second]; + + if (i1==-1 || i2==-1) continue; //skip degenerate faces + + const std::array& t1 = triangles[i1]; + const std::array& t2 = triangles[i2]; + + std::vector inter_pts; + bool triangles_are_coplanar = autorefine_impl::collect_intersections(t1, t2, inter_pts); + + CGAL_assertion( + CGAL::do_intersect(EK::Triangle_3(t1[0], t1[1], t1[2]), EK::Triangle_3(t2[0], t2[1], t2[2])) + != inter_pts.empty()); + + if (!inter_pts.empty()) + { + std::size_t nbi = inter_pts.size(); + switch(nbi) + { + case 1: + all_points[i1].push_back(inter_pts[0]); + all_points[i2].push_back(inter_pts[0]); + break; + case 2: + all_segments[i1].push_back(CGAL::make_array(inter_pts[0], inter_pts[1])); + all_segments[i2].push_back(CGAL::make_array(inter_pts[0], inter_pts[1])); + all_in_triangle_ids[i1].push_back(i2); + all_in_triangle_ids[i2].push_back(i1); + break; + default: + for (std::size_t i=0;i>> all_segments_ids(all_segments.size()); + + auto deduplicate_inserted_segments = [&](std::size_t ti) + { + if (!all_segments[ti].empty()) + { + std::map point_id_map; + + + auto get_point_id = [&](const EK::Point_3& pt) + { + auto insert_res = point_id_map.insert(std::make_pair(pt, all_points[ti].size())); + if (insert_res.second) + all_points[ti].push_back(pt); + return insert_res.first->second; + }; + + + if (!all_points[ti].empty()) + { + using EPoint_3 = EK::Point_3; // workaround for MSVC 2022 bug + std::vector tmp; + tmp.swap(all_points[ti]); + for (const EPoint_3& pt : tmp) + get_point_id(pt); + } + + std::size_t nbs = all_segments[ti].size(); + std::vector> filtered_segments; + std::vector filtered_in_triangle_ids; + filtered_segments.reserve(nbs); + std::set> segset; + for (std::size_t si=0; si(0, triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + deduplicate_inserted_segments(ti); + } + ); + } + else +#endif + for (std::size_t ti = 0; ti < triangles.size(); ++ti) { + deduplicate_inserted_segments(ti); + } + +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS + t.stop(); + std::cout << t.time() << " sec. for #3" << std::endl; + t.reset(); +#endif + + CGAL_PMP_AUTOREFINE_VERBOSE("triangulate faces"); + // now refine triangles +#ifdef CGAL_LINKED_WITH_TBB + std::conditional_t, std::size_t>>, + std::vector, std::size_t>>> new_triangles; +#else + std::vector, std::size_t>> new_triangles; +#endif + +#ifdef CGAL_AUTOREF_USE_PROGRESS_DISPLAY + boost::timer::progress_display pd(triangles.size()); +#endif + + auto refine_triangles = [&](std::size_t ti) + { + if (all_segments[ti].empty() && all_points[ti].empty()) + new_triangles.push_back({triangles[ti], ti}); + else + { + autorefine_impl::generate_subtriangles(ti, all_segments_ids[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, coplanar_triangles, triangles, new_triangles); + } + +#ifdef CGAL_AUTOREF_USE_PROGRESS_DISPLAY + ++pd; +#endif + }; + +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS + t.start(); +#endif +#ifdef CGAL_LINKED_WITH_TBB + if (parallel_execution) + { + tbb::parallel_for(tbb::blocked_range(0, triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + refine_triangles(ti); + } + ); + } + else +#endif + for (std::size_t ti = 0; ti < triangles.size(); ++ti) { + refine_triangles(ti); + } + +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS + t.stop(); + std::cout << t.time() << " sec. for #1" << std::endl; + t.reset(); +#endif + + // brute force output: create a soup, orient and to-mesh + CGAL_PMP_AUTOREFINE_VERBOSE("create output soup"); + + Cartesian_converter to_input; + +#ifdef CGAL_LINKED_WITH_TBB + typedef std::conditional_t, + std::map> Point_id_map; +#else + typedef std::map Point_id_map; +#endif + Point_id_map point_id_map; + +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + std::vector exact_soup_points; +#endif + + // TODO: parallel_for? + // for input points, we on purpose keep duplicated points and isolated points + for (std::size_t pid = 0; pidfirst); +#endif + } + + TriangleRange soup_triangles_out; + soup_triangles_out.reserve(soup_triangles.size()); + + if constexpr (!std::is_same_v) + { + std::size_t nbt=0; + for (Input_TID f=0; f tri_inter_ids_inverse(triangles.size()); + for (Input_TID f=0; fsecond; + }; + +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS + t.start(); +#endif + + std::size_t offset = soup_triangles_out.size(); +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS + std::string mode = "parallel"; +#endif + +// It might be possible to optimise the hardcoded value below +// but the less triangles the faster will anyway be the operation. +// So it's probably not critical. +#ifdef CGAL_LINKED_WITH_TBB + if(parallel_execution && new_triangles.size() > 50) + { +#ifdef CGAL_AUTOREF_SET_POINT_IDS_USING_MUTEX + //option 1 (using a mutex) + CGAL_MUTEX point_container_mutex; + /// Lambda concurrent_get_point_id() + auto concurrent_get_point_id = [&](const EK::Point_3& pt) + { + auto insert_res = point_id_map.insert(std::make_pair(pt, -1)); + + if (insert_res.second) + { + CGAL_SCOPED_LOCK(point_container_mutex); + insert_res.first->second=soup_points.size(); + soup_points.push_back(to_input(pt)); +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + exact_soup_points.push_back(pt); +#endif + } + return insert_res.first; + }; + + soup_triangles_out.resize(offset + new_triangles.size()); + //use map iterator triple for triangles to create them concurrently and safely + std::vector> triangle_buffer(new_triangles.size()); + tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) { + const std::array& t = new_triangles[ti].first; + visitor.new_subtriangle(offset+ti, tri_inter_ids_inverse[new_triangles[ti].second]); + triangle_buffer[ti] = CGAL::make_array(concurrent_get_point_id(t[0]), concurrent_get_point_id(t[1]), concurrent_get_point_id(t[2])); + } + } + ); + tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + { + soup_triangles_out[offset + ti] = + { triangle_buffer[ti][0]->second, + triangle_buffer[ti][1]->second, + triangle_buffer[ti][2]->second }; + } + } + ); +#else + //option 2 (without mutex) + /// Lambda concurrent_get_point_id() + tbb::concurrent_vector iterators; + auto concurrent_get_point_id = [&](const EK::Point_3& pt) + { + auto insert_res = point_id_map.insert(std::make_pair(pt, -1)); + if (insert_res.second) + iterators.push_back(insert_res.first); + return insert_res.first; + }; + + //use map iterator triple for triangles to create them concurrently and safely + soup_triangles_out.resize(offset + new_triangles.size()); + std::vector> triangle_buffer(new_triangles.size()); + tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + { + const std::array& t = new_triangles[ti].first; + visitor.new_subtriangle(offset+ti, tri_inter_ids_inverse[new_triangles[ti].second]); + triangle_buffer[ti] = CGAL::make_array(concurrent_get_point_id(t[0]), concurrent_get_point_id(t[1]), concurrent_get_point_id(t[2])); + } + } + ); + + // the map is now filled we can safely set the point ids + std::size_t pid_offset=soup_points.size(); + soup_points.resize(pid_offset+iterators.size()); +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + exact_soup_points.resize(soup_points.size()); +#endif + + tbb::parallel_for(tbb::blocked_range(0, iterators.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + { + soup_points[pid_offset+ti] = to_input(iterators[ti]->first); +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + exact_soup_points[pid_offset+ti] = iterators[ti]->first; +#endif + iterators[ti]->second=pid_offset+ti; + } + } + ); + + tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + { + soup_triangles_out[offset + ti] = + { triangle_buffer[ti][0]->second, + triangle_buffer[ti][1]->second, + triangle_buffer[ti][2]->second }; + } + } + ); +#endif + } + else +#endif + { +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS + mode = "sequential"; +#endif + soup_triangles_out.reserve(offset + new_triangles.size()); + for (const std::pair, std::size_t>& t_and_id : new_triangles) + { + visitor.new_subtriangle(soup_triangles_out.size(), tri_inter_ids_inverse[t_and_id.second]); + soup_triangles_out.push_back({ get_point_id(t_and_id.first[0]), + get_point_id(t_and_id.first[1]), + get_point_id(t_and_id.first[2]) }); + } + } + + + +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS + t.stop(); + std::cout << t.time() << " sec. for #4 (" << mode << ")" << std::endl; + t.reset(); +#endif + +#ifndef CGAL_NDEBUG + CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); + CGAL_assertion( !does_triangle_soup_self_intersect(exact_soup_points, soup_triangles_out) ); +#else +#ifdef CGAL_DEBUG_PMP_AUTOREFINE + CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); + if (does_triangle_soup_self_intersect(exact_soup_points, soup_triangles_out)) + throw std::runtime_error("ERROR: invalid output, there is most probably a bug"); +#endif +#endif + using std::swap; + swap(soup_triangles, soup_triangles_out); + + CGAL_PMP_AUTOREFINE_VERBOSE("done"); +} + +/** + * \ingroup PMP_corefinement_grp + * refines a triangle mesh so that no triangles intersects in their interior. + * + * Note that this function is only provided as a shortcut for calling `autorefine_triangle_soup()` + * with a mesh. For any advance usage the aforementioned function should be called directly. + * + * @tparam TriangleMesh a model of `HalfedgeListGraph`, `FaceListGraph`, and `MutableFaceGraph` + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * @param tm input triangulated surface mesh + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * @warning `clear(tm)` will be called before filling `tm` with the refined mesh. + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{concurrency_tag} + * \cgalParamDescription{a tag indicating if the task should be done using one or several threads.} + * \cgalParamType{Either `CGAL::Sequential_tag`, or `CGAL::Parallel_tag`, or `CGAL::Parallel_if_available_tag`} + * \cgalParamDefault{`CGAL::Sequential_tag`} + * \cgalParamNEnd + * \cgalParamNBegin{geom_traits} + * \cgalParamDescription{an instance of a geometric traits class} + * \cgalParamType{a class model of `PMPSelfIntersectionTraits`} + * \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`} + * \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.} + * \cgalParamNEnd + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `tm`} + * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and `%Point_3` as value type} + * \cgalParamDefault{`boost::get(CGAL::vertex_point, tm)`} + * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` + * must be available in `TriangleMesh`.} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + */ +template +void +autorefine( TriangleMesh& tm, + const NamedParameters& np = parameters::default_values()) +{ + using parameters::choose_parameter; + using parameters::get_parameter; + + typedef typename GetGeomTraits::type GT; + // GT traits = choose_parameter(get_parameter(np, internal_np::geom_traits)); + + std::vector soup_points; + std::vector > soup_triangles; + + polygon_mesh_to_polygon_soup(tm, soup_points, soup_triangles, np); + + autorefine_triangle_soup(soup_points, soup_triangles, np); + + clear(tm); + repair_polygon_soup(soup_points, soup_triangles); + + duplicate_non_manifold_edges_in_polygon_soup(soup_points, soup_triangles); + polygon_soup_to_polygon_mesh(soup_points, soup_triangles, tm); +} + + +} } // end of CGAL::Polygon_mesh_processing + +#ifdef CGAL_LINKED_WITH_TBB +#ifdef CGAL_HAS_DEFINED_TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS +#undef TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS +#endif +#endif + +#endif // CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h index 8b41ff2ecdb..b3aaf70604f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h @@ -747,7 +747,7 @@ struct Triangle_structure_sampler_for_triangle_soup * @tparam TriangleMesh a model of the concepts `EdgeListGraph` and `FaceListGraph` * @tparam PointOutputIterator a model of `OutputIterator` * holding objects of the same point type as - * the value type of the point type associated to the mesh `tm`, i.e. the value type of the vertex + * the value type of the point type associated to the mesh `tm`, i.e., the value type of the vertex * point map property map, if provided, or the value type of the internal point property map otherwise * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * @@ -1570,7 +1570,7 @@ bounded_error_squared_Hausdorff_distance_impl(const TriangleMesh1& tm1, candidate_triangles.pop(); // Only process the triangle if it can contribute to the Hausdorff distance, - // i.e. if its upper bound is higher than the currently known best lower bound + // i.e., if its upper bound is higher than the currently known best lower bound // and the difference between the bounds to be obtained is larger than the // user-given error. const auto& triangle_bounds = triangle_and_bounds.bounds; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_traversal_traits_with_transformation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_traversal_traits_with_transformation.h index 83884277136..7dad2004ecd 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_traversal_traits_with_transformation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_traversal_traits_with_transformation.h @@ -27,7 +27,6 @@ #include #include -#include namespace CGAL { diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index 4a15d9e59c7..68f0c9e5e6c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -388,12 +387,12 @@ struct TweakedGetVertexPointMap typedef typename std::is_same::value_type>::type Use_default_tag; - typedef typename boost::mpl::if_< - Use_default_tag, + typedef std::conditional_t< + Use_default_tag::value, Default_map, Dummy_default_vertex_point_map::vertex_descriptor > - >::type type; + > type; }; template diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h index c1696428d75..30d201d1ef5 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h @@ -246,7 +246,7 @@ namespace internal { get(ecmap, e) || get(fpm, face(h,pmesh))!=get(fpm, face(opposite(h,pmesh),pmesh)) ) { - if (sizing.is_too_long(source(h, pmesh), target(h, pmesh))) + if (sizing.is_too_long(source(h, pmesh), target(h, pmesh), pmesh)) { return false; } @@ -400,7 +400,7 @@ namespace internal { for(edge_descriptor e : edge_range) { const halfedge_descriptor he = halfedge(e, mesh_); - std::optional sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_)); + std::optional sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_), mesh_); if(sqlen != std::nullopt) long_edges.emplace(he, sqlen.value()); } @@ -433,16 +433,16 @@ namespace internal { std::cout << " refinement point : " << refinement_point << std::endl; #endif //update sizing field with the new point - sizing.update(vnew, mesh_); + sizing.register_split_vertex(vnew, mesh_); //check sub-edges //if it was more than twice the "long" threshold, insert them - std::optional sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_)); + std::optional sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_), mesh_); if(sqlen_new != std::nullopt) long_edges.emplace(hnew, sqlen_new.value()); const halfedge_descriptor hnext = next(hnew, mesh_); - sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_)); + sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_), mesh_); if (sqlen_new != std::nullopt) long_edges.emplace(hnext, sqlen_new.value()); @@ -500,7 +500,7 @@ namespace internal { if (!is_split_allowed(e)) continue; const halfedge_descriptor he = halfedge(e, mesh_); - std::optional sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_)); + std::optional sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_), mesh_); if(sqlen != std::nullopt) long_edges.emplace(halfedge(e, mesh_), sqlen.value()); } @@ -550,16 +550,16 @@ namespace internal { halfedge_added(hnew_opp, status(opposite(he, mesh_))); //update sizing field with the new point - sizing.update(vnew, mesh_); + sizing.register_split_vertex(vnew, mesh_); //check sub-edges //if it was more than twice the "long" threshold, insert them - std::optional sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_)); + std::optional sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_), mesh_); if(sqlen_new != std::nullopt) long_edges.emplace(hnew, sqlen_new.value()); const halfedge_descriptor hnext = next(hnew, mesh_); - sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_)); + sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_), mesh_); if (sqlen_new != std::nullopt) long_edges.emplace(hnext, sqlen_new.value()); @@ -580,7 +580,7 @@ namespace internal { if (snew == PATCH) { - std::optional sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_)); + std::optional sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_), mesh_); if(sql != std::nullopt) long_edges.emplace(hnew2, sql.value()); } @@ -603,7 +603,7 @@ namespace internal { if (snew == PATCH) { - std::optional sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_)); + std::optional sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_), mesh_); if (sql != std::nullopt) long_edges.emplace(hnew2, sql.value()); } @@ -747,7 +747,7 @@ namespace internal { for(halfedge_descriptor ha : halfedges_around_target(va, mesh_)) { vertex_descriptor va_i = source(ha, mesh_); - std::optional sqha = sizing.is_too_long(vb, va_i); + std::optional sqha = sizing.is_too_long(vb, va_i, mesh_); if (sqha != std::nullopt) { collapse_ok = false; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Sizing_field_base.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Sizing_field_base.h index f13135cd873..c06f0568e68 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Sizing_field_base.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Sizing_field_base.h @@ -60,13 +60,14 @@ public: typedef typename K::FT FT; public: - virtual FT at(const vertex_descriptor v) const = 0; + virtual FT at(const vertex_descriptor v, const PolygonMesh&) const = 0; virtual std::optional is_too_long(const vertex_descriptor va, - const vertex_descriptor vb) const = 0; + const vertex_descriptor vb, + const PolygonMesh&) const = 0; virtual std::optional is_too_short(const halfedge_descriptor h, const PolygonMesh& pmesh) const = 0; virtual Point_3 split_placement(const halfedge_descriptor h, const PolygonMesh& pmesh) const = 0; - virtual void update(const vertex_descriptor v, const PolygonMesh& pmesh) = 0; + virtual void register_split_vertex(const vertex_descriptor v, const PolygonMesh& pmesh) = 0; }; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h index 26e205ea43d..a996edae648 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h @@ -29,7 +29,6 @@ #include #include -#include #include #include @@ -1427,18 +1426,16 @@ bool do_intersect(const TriangleMesh& tm, const Polyline& polyline, const CGAL_NP_CLASS& np = parameters::default_values() #ifndef DOXYGEN_RUNNING - , const std::enable_if_t< - ! boost::mpl::or_< - typename std::is_same::type, // Added to please MSVC 2015 - typename boost::mpl::not_::type>::type, // not a range - typename boost::has_range_iterator< + , const std::enable_if_t || // Added to please MSVC 2015 + !boost::has_range_iterator::value || // not a range + boost::has_range_iterator< typename boost::mpl::eval_if< boost::has_range_iterator, boost::range_value, - std::false_type - >::type - >::type // not a range of a range - >::value + std::false_type>::type + >::value + ) >* = 0 #endif ) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index ef361b17529..b99ed460a6f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -30,7 +30,6 @@ #include #include -#include #include #include diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h new file mode 100644 index 00000000000..d86b470a260 --- /dev/null +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h @@ -0,0 +1,174 @@ +// Copyright (c) 2021-2023 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Sebastien Loriot + +#ifndef CGAL_POLYGON_MESH_PROCESSING_REFINE_MESH_AT_ISOLEVEL_H +#define CGAL_POLYGON_MESH_PROCESSING_REFINE_MESH_AT_ISOLEVEL_H + +#include + +#include +#include + +#include +#include + +namespace CGAL { +namespace Polygon_mesh_processing { + +/*! + * \ingroup PkgPolygonMeshProcessingRef + * + * refines `pm` by adding new vertices on edges having their incident vertices associated with + * values respectively larger and smaller than `isovalue` in `value_map`. + * The placement of new vertices on edges will be done by linear interpolation + * using the aforementioned values. + * New vertices will be associated `isovalue` in `value_map` when created. + * Additionally, new edges will be added by connecting new vertices created sharing + * a common incident face. Note that in case more than two new vertices are added + * on a face boundary, no edges will be created in that face. + * + * @tparam PolygonMesh a model of the concepts `EdgeListGraph` and `FaceListGraph` + * @tparam ValueMap a model of the concept `ReadWritePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and with its value type being the type of the coordinates of points associated with vertices + * in the vertex map provided to the `vertex_point_map()` named parameter. + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" for `pm` + * + * @param pm the polygon mesh to be refined. + * @param value_map the property map containing a value at each vertex for a given function defined over the mesh. + * @param isovalue the value used to refine + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{edge_is_constrained_map} + * \cgalParamDescription{an output property map associating `true` to all edges connecting vertices on the isolevel, + * and `false` for all other edges.} + * \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%edge_descriptor` + * as key type and `bool` as value type} + * \cgalParamDefault{No marks on edges will be put} + * \cgalParamNEnd + * + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `pm`} + * \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and `%Point_3` as value type} + * \cgalParamDefault{`boost::get(CGAL::vertex_point, pm)`} + * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` + * must be available in `PolygonMesh`.} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + */ +template +void refine_mesh_at_isolevel(PolygonMesh& pm, + ValueMap value_map, + typename boost::property_traits::value_type isovalue, + const NamedParameters& np = parameters::default_values()) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::property_traits::value_type FT; + + using parameters::choose_parameter; + using parameters::get_parameter; + using parameters::is_default_parameter; + + typedef Static_boolean_property_map Default_ECM; + typedef typename internal_np::Lookup_named_param_def::type ECM; + typedef typename GetVertexPointMap < PolygonMesh, NamedParameters>::type VPM; + + VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), + get_property_map(vertex_point, pm)); + + ECM ecm = choose_parameter(get_parameter(np, internal_np::edge_is_constrained), Default_ECM()); + + std::unordered_map > faces_to_split; + std::vector to_split; + std::unordered_set vertices_on_isoline; + for (edge_descriptor e : edges(pm)) + { + vertex_descriptor src = source(e, pm), tgt = target(e, pm); + + if (get(value_map, src)==isovalue) + { + vertices_on_isoline.insert(src); + if (get(value_map, tgt)==isovalue) + { + put(ecm, e, true); // special case for faces entirely on an isovalue + continue; + } + continue; + } + if (get(value_map, tgt)==isovalue) + { + vertices_on_isoline.insert(tgt); + continue; + } + if ( (get(value_map, tgt) < isovalue) != (get(value_map, src) < isovalue) ) + { + to_split.push_back(e); + } + } + + for (edge_descriptor e : to_split) + { + vertex_descriptor src = source(e, pm), tgt = target(e, pm); + FT ds = get(value_map, src); + FT dt = get(value_map, tgt); + FT alpha = (isovalue - dt) / (ds - dt); + halfedge_descriptor hnew = CGAL::Euler::split_edge(halfedge(e, pm), pm); + put(vpm, target(hnew, pm), barycenter(get(vpm,src), alpha, get(vpm, tgt), 1-alpha)); + put(value_map, target(hnew, pm) , isovalue); + face_descriptor f = face(hnew, pm); + if (f!=boost::graph_traits::null_face()) + faces_to_split[f].push_back(hnew); + hnew=pm.prev(opposite(hnew, pm)); + f = face(hnew, pm); + if (f!=boost::graph_traits::null_face()) + faces_to_split[f].push_back(hnew); + } + + for (vertex_descriptor vh : vertices_on_isoline) + { + for (halfedge_descriptor h : halfedges_around_target(vh, pm)) + { + face_descriptor f = face(h, pm); + if (f!=boost::graph_traits::null_face()) + faces_to_split[f].push_back(h); + } + } + + for (const auto& p : faces_to_split) + { + if(p.second.size()!=2) continue; + + std::pair res = edge(target(p.second[0],pm), + target(p.second[1],pm), pm); + if (res.second) + { + // no split as the edge already exists (the two vertices are on the isolevel) + put(ecm, res.first, true); + continue; + } + + halfedge_descriptor hnew = CGAL::Euler::split_face(p.second[0], p.second[1], pm); + put(ecm, edge(hnew, pm), true); + } +} + +} } // end of CGAL::Polygon_mesh_processing + + +#endif diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h index 03171af70bc..33514d6f2de 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h @@ -299,7 +299,7 @@ template void mark_constrained_edges( - TriangleMesh& tm, + const TriangleMesh& tm, EdgeIsConstrainedMap edge_is_constrained, double coplanar_cos_threshold, const VertexPointMap& vpm) @@ -319,7 +319,7 @@ template std::size_t mark_corner_vertices( - TriangleMesh& tm, + const TriangleMesh& tm, EdgeIsConstrainedMap& edge_is_constrained, VertexCornerIdMap& vertex_corner_id, double coplanar_cos_threshold, @@ -546,7 +546,7 @@ template std::pair -tag_corners_and_constrained_edges(TriangleMesh& tm, +tag_corners_and_constrained_edges(const TriangleMesh& tm, double coplanar_cos_threshold, VertexCornerIdMap& vertex_corner_id, EdgeIsConstrainedMap& edge_is_constrained, diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index 3d085dbb27f..183fc299f70 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -530,7 +530,8 @@ self_intersections_impl(const FaceRange& face_range, * @tparam FaceRange a model of `ConstRange` with value type `boost::graph_traits::%face_descriptor`. * @tparam TriangleMesh a model of `FaceListGraph` * @tparam FacePairOutputIterator a model of `OutputIterator` holding objects of type - * `std::pair::%face_descriptor, boost::graph_traits::%face_descriptor>` + * `std::pair::%face_descriptor, boost::graph_traits::%face_descriptor>`. + * It does not need to be thread-safe. * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * * @param face_range the range of faces to check for self-intersection. @@ -596,7 +597,8 @@ self_intersections(const FaceRange& face_range, * Possible values are `Sequential_tag`, `Parallel_tag`, and `Parallel_if_available_tag`. * @tparam TriangleMesh a model of `FaceListGraph` * @tparam FacePairOutputIterator a model of `OutputIterator` holding objects of type - * `std::pair::%face_descriptor, boost::graph_traits::%face_descriptor>` + * `std::pair::%face_descriptor, boost::graph_traits::%face_descriptor>`. + * It does not need to be thread-safe. * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * * @param tmesh the triangulated surface mesh to be checked diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/tangential_relaxation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/tangential_relaxation.h index 6693524324a..145d5a24135 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/tangential_relaxation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/tangential_relaxation.h @@ -288,9 +288,9 @@ void tangential_relaxation(const VertexRange& vertices, const double tri_area = gt_area(get(vpm, v), get(vpm, v1), get(vpm, v2)); const double face_weight = tri_area - / (1. / 3. * (sizing.at(v) - + sizing.at(v1) - + sizing.at(v2))); + / (1. / 3. * (sizing.at(v, tm) + + sizing.at(v1, tm) + + sizing.at(v2, tm))); weight += face_weight; const Point_3 centroid = gt_centroid(get(vpm, v), get(vpm, v1), get(vpm, v2)); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h index f1b88540a60..a608179f49a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h @@ -30,7 +30,6 @@ #include #include -#include #include #include @@ -79,12 +78,12 @@ template::type >::type, + typename boost::property_map< TriangleMesh, vertex_point_t>::type >, Default, - VertexPointMap>::type> > >, + VertexPointMap>>>>, bool UseParallelPlaneOptimization=true> class Polygon_mesh_slicer { diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt index d9ea1a1cf37..44e32386664 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt @@ -65,6 +65,7 @@ create_single_source_cgal_program("triangulate_hole_with_cdt_2_test.cpp") create_single_source_cgal_program("test_pmp_polyhedral_envelope.cpp") create_single_source_cgal_program("test_pmp_np_function.cpp") create_single_source_cgal_program("test_degenerate_pmp_clip_split_corefine.cpp") +create_single_source_cgal_program("test_isolevel_refinement.cpp") # create_single_source_cgal_program("test_pmp_repair_self_intersections.cpp") find_package(Eigen3 3.2.0 QUIET) #(requires 3.2.0 or greater) @@ -105,6 +106,7 @@ if(TARGET CGAL::TBB_support) target_link_libraries(test_pmp_distance PUBLIC CGAL::TBB_support) target_link_libraries(orient_polygon_soup_test PUBLIC CGAL::TBB_support) target_link_libraries(self_intersection_surface_mesh_test PUBLIC CGAL::TBB_support) + target_link_libraries(test_autorefinement PUBLIC CGAL::TBB_support) else() message(STATUS "NOTICE: Intel TBB was not found. Tests will use sequential code.") endif() diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp index 02b5e000a5e..f3c541ab65c 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cmd b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cmd index a2ffe2c2539..8c848a2f106 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cmd +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cmd @@ -1,28 +1,28 @@ -data-autoref/test_01.off 0 0 4 1 4 0 -data-autoref/test_02.off 1 5 13 1 5 0 -data-autoref/test_03.off 4 8 18 0 18 0 -data-autoref/test_04.off 1 5 17 0 17 0 -data-autoref/test_05.off 1 5 17 0 17 0 -data-autoref/test_06.off 3 55 141 1 76 0 -data-autoref/test_07.off 1 4 10 1 4 0 -data-autoref/test_08.off 1 31 87 1 52 0 -data-autoref/test_09.off 1 4 5 1 4 0 -data-autoref/test_10.off 1 3 13 0 13 0 -data-autoref/test_11.off 1 3 12 0 12 0 -data-autoref/test_12.off 2 2 11 1 11 0 -data-autoref/test_13.off 1 5 16 1 8 0 -data-autoref/test_14.off 1 5 16 1 12 0 -data-autoref/test_15.off 3 8 16 1 12 0 -data-autoref/test_16.off 1 2 6 1 4 0 -data-autoref/test_17.off 1 2 6 1 4 0 -data-autoref/triple_inter_exception/triple.off 0 0 0 0 0 1 -data-autoref/triple_inter_exception/cubes_cpln_1.off 0 0 0 0 0 1 -data-autoref/triple_inter_exception/cubes_cpln_2.off 0 0 0 0 0 1 -data-autoref/triple_inter_exception/cubes_cpln_3.off 0 0 0 0 0 1 -data-autoref/open_01.off 1 65 1377 1 1313 0 -data-autoref/open_02.off 1 33 595 1 562 0 -data-autoref/cpln_01.off 18 42 48 1 30 0 -data-autoref/cpln_02.off 28 56 40 1 24 0 -data-autoref/cpln_03.off 15 35 42 1 27 0 -data-autoref/four_cubes.off 12 94 184 1 78 0 -data-autoref/spiral.off 7 14 26 0 26 0 +data-autoref/test_01.off 0 0 4 1 4 0 4 2 +data-autoref/test_02.off 1 5 13 1 5 0 10 17 +data-autoref/test_03.off 4 8 18 0 18 0 14 20 +data-autoref/test_04.off 1 5 17 0 17 0 13 20 +data-autoref/test_05.off 1 5 17 0 17 0 13 20 +data-autoref/test_06.off 3 55 141 1 76 0 92 248 +data-autoref/test_07.off 1 4 10 1 4 0 8 12 +data-autoref/test_08.off 1 31 87 1 52 0 57 148 +data-autoref/test_09.off 1 4 5 1 4 0 4 4 +data-autoref/test_10.off 1 3 13 0 13 0 10 13 +data-autoref/test_11.off 1 3 12 0 12 0 9 12 +data-autoref/test_12.off 2 2 11 1 11 0 9 6 +data-autoref/test_13.off 1 5 16 1 8 0 16 22 +data-autoref/test_14.off 1 5 16 1 12 0 16 22 +data-autoref/test_15.off 3 8 16 1 12 0 16 24 +data-autoref/test_16.off 1 2 6 1 4 0 6 2 +data-autoref/test_17.off 1 2 6 1 4 0 6 2 +data-autoref/triple_inter_exception/triple.off 0 0 0 0 0 1 15 18 +data-autoref/triple_inter_exception/cubes_cpln_1.off 0 0 0 0 0 1 66 224 +data-autoref/triple_inter_exception/cubes_cpln_2.off 0 0 0 0 0 1 54 196 +data-autoref/triple_inter_exception/cubes_cpln_3.off 0 0 0 0 0 1 61 204 +data-autoref/open_01.off 1 65 1377 1 1313 0 1317 2622 +data-autoref/open_02.off 1 33 595 1 562 0 565 1056 +data-autoref/cpln_01.off 18 42 48 1 30 0 30 88 +data-autoref/cpln_02.off 28 56 40 1 24 0 24 72 +data-autoref/cpln_03.off 15 35 42 1 27 0 27 76 +data-autoref/four_cubes.off 12 94 184 1 78 0 106 352 +data-autoref/spiral.off 7 14 26 0 26 0 19 31 diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cpp index 9c908d7ec24..3af3402a5f2 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cpp @@ -3,6 +3,10 @@ #include #include +#include +#include + +#include #include #include @@ -13,23 +17,64 @@ typedef CGAL::Surface_mesh Mesh; namespace PMP = CGAL::Polygon_mesh_processing; template -struct My_visitor : +struct My_exp_visitor : public CGAL::Polygon_mesh_processing::Corefinement::Default_visitor { void after_subface_creations(TriangleMesh&){++(*i);} - My_visitor() + My_exp_visitor() : i (new int(0) ) {} std::shared_ptr i; }; -void test(const char* fname, std::size_t nb_polylines, std::size_t total_nb_points, - std::size_t nb_vertices_after_autorefine, bool all_fixed, std::size_t nb_vertices_after_fix, - bool triple_intersection) +struct My_visitor { - std::cout << "Running tests on " << fname << "\n"; + My_visitor(std::size_t nb_input, std::size_t expected_nb_output) + : nb_input(nb_input) + , expected_nb_output(expected_nb_output) + {} + + ~My_visitor() + { + for(std::size_t i=0; i tgt_check; +}; + +void test_coref_based(const char* fname, std::size_t nb_polylines, std::size_t total_nb_points, + std::size_t nb_vertices_after_autorefine, bool all_fixed, std::size_t nb_vertices_after_fix, + bool triple_intersection) +{ + std::cout << "Running tests (coref based) on " << fname << "\n"; std::ifstream input(fname); Mesh mesh; @@ -41,7 +86,7 @@ void test(const char* fname, std::size_t nb_polylines, std::size_t total_nb_poin input.close(); std::size_t nb_vertices_before_autorefine = num_vertices(mesh); -// Testing surface_self_intersection() +// Testing PMP::experimental::surface_self_intersection() try{ std::vector< std::vector >polylines; PMP::experimental::surface_self_intersection(mesh, std::back_inserter(polylines)); @@ -57,9 +102,9 @@ void test(const char* fname, std::size_t nb_polylines, std::size_t total_nb_poin assert( triple_intersection ); } -// Testing autorefine() +// Testing PMP::experimental::autorefine() try{ - My_visitor visitor; + My_exp_visitor visitor; PMP::experimental::autorefine(mesh, CGAL::parameters::visitor(visitor)); mesh.collect_garbage(); @@ -72,7 +117,7 @@ void test(const char* fname, std::size_t nb_polylines, std::size_t total_nb_poin assert( triple_intersection ); } -// Testing autorefine_and_remove_self_intersections() +// Testing PMP::experimental::autorefine_and_remove_self_intersections() try{ input.open(fname); mesh.clear(); @@ -89,10 +134,42 @@ void test(const char* fname, std::size_t nb_polylines, std::size_t total_nb_poin } } +template +void test(const char* fname, std::size_t nb_vertices_after_autorefine, std::size_t expected_nb_output, Tag tag) +{ + std::cout << "Running tests on " << fname; + if (std::is_same_v) + std::cout << " (Sequential)\n"; + else + std::cout << " (Parallel)\n"; + + std::vector points; + std::vector< std::vector > triangles; + if (!CGAL::IO::read_polygon_soup(fname, points, triangles)) + { + std::cerr << " Input mesh is not a valid file." << std::endl; + exit(EXIT_FAILURE); + } + +// Testing autorefine() + My_visitor visitor(triangles.size(), expected_nb_output); + PMP::autorefine_triangle_soup(points, triangles, CGAL::parameters::visitor(visitor).concurrency_tag(tag)); + assert( nb_vertices_after_autorefine==points.size()); + assert( expected_nb_output==triangles.size()); + assert( !PMP::does_triangle_soup_self_intersect(points, triangles) ); +// CGAL::IO::write_polygon_soup("/tmp/debug.off", points, triangles); +} + int main(int argc, const char** argv) { // file nb_polylines total_nb_points nb_vertices_after_autorefine all_fixed nb_vertices_after_fix triple_intersection - for (int i=0;i<(argc-1)/7; ++i) - test(argv[1+7*i], atoi(argv[1+7*i+1]), atoi(argv[1+7*i+2]), - atoi(argv[1+7*i+3]), atoi(argv[1+7*i+4])==0?false:true, atoi(argv[1+7*i+5]), atoi(argv[1+7*i+6])==0?false:true); + for (int i=0;i<(argc-1)/9; ++i) + { + test_coref_based(argv[1+9*i], atoi(argv[1+9*i+1]), atoi(argv[1+9*i+2]), + atoi(argv[1+9*i+3]), atoi(argv[1+9*i+4])==0?false:true, atoi(argv[1+9*i+5]), atoi(argv[1+9*i+6])==0?false:true); + test(argv[1+9*i], atoi(argv[1+9*i+7]), atoi(argv[1+9*i+8]), CGAL::Sequential_tag()); +#ifdef CGAL_LINKED_WITH_TBB + test(argv[1+9*i], atoi(argv[1+9*i+7]), atoi(argv[1+9*i+8]), CGAL::Parallel_tag()); +#endif + } } diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_isolevel_refinement.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_isolevel_refinement.cpp new file mode 100644 index 00000000000..9e07c831435 --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_isolevel_refinement.cpp @@ -0,0 +1,68 @@ +#include +#include + +#include +#include + +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point_3; +typedef CGAL::Surface_mesh Triangle_mesh; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::edge_descriptor edge_descriptor; + +typedef Triangle_mesh::Property_map Vertex_distance_map; + +int main() +{ + const std::string filename = CGAL::data_file_path("meshes/elephant.off"); + + Triangle_mesh tm; + if(!CGAL::IO::read_polygon_mesh(filename, tm) || + CGAL::is_empty(tm) || !CGAL::is_triangle_mesh(tm)) + { + std::cerr << "Invalid input file." << std::endl; + return EXIT_FAILURE; + } + //property map for the distance values to the source set + Vertex_distance_map vertex_distance = tm.add_property_map("v:distance", 5).first; + std::vector zero_vids={ + /*a closed polyline*/ 2144,145,2690,1752,339,215,1395,338,77,2145,2052,2054,343,1936,22,1751,214,1499,142,358,2694,1750,301,65,59,2650,2060,205,2651,2061,2490,1939,898,13,298, + /*two adjacent triangles*/ 532, 185, 534, 2735, + /*another patch with missing crossed edges*/134,73,1883,2533,72,532,185,131,534 + }; + + std::vector minus_vids = {132, 364}; + + for (int i : zero_vids) + put(vertex_distance, Triangle_mesh::Vertex_index(i), 0); + for (int i : minus_vids) + put(vertex_distance, Triangle_mesh::Vertex_index(i), -5); + + // property map to flag new cut edge added in the mesh + auto ecm = tm.add_property_map("e:is_constrained", 0).first; + + CGAL::Polygon_mesh_processing::refine_mesh_at_isolevel(tm, vertex_distance, 0, CGAL::parameters::edge_is_constrained_map(ecm)); + + std::ofstream debug("edges.polylines.txt"); + for (Triangle_mesh::Edge_index e : edges(tm)) + if (get(ecm, e)) + debug << "2 " << tm.point(source(e, tm)) << " " << tm.point(target(e, tm)) << "\n"; + debug.close(); + + // split the mesh in connected components bounded by the isocurves + std::vector edges_split; + CGAL::Polygon_mesh_processing::split_connected_components(tm, edges_split, CGAL::parameters::edge_is_constrained_map(ecm)); + + // export each submesh in a file + for(std::size_t i=0; i patch_vertices; // use all param - read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); + read_poly_with_borders("elephant_quad_hole_no_DT3.off", poly, border_reps); CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole (poly, border_reps[0], CGAL::parameters:: @@ -345,7 +345,7 @@ void test_triangulate_refine_and_fair_hole_compile() { sparse_linear_solver(Default_solver())); // default solver - read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); + read_poly_with_borders("elephant_quad_hole_no_DT3.off", poly, border_reps); CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole (poly, border_reps[0], CGAL::parameters:: @@ -354,7 +354,7 @@ void test_triangulate_refine_and_fair_hole_compile() { weight_calculator(CGAL::Weights::Uniform_weight())); // default solver and weight - read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); + read_poly_with_borders("elephant_quad_hole_no_DT3.off", poly, border_reps); CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole (poly, border_reps[0], CGAL::parameters:: @@ -376,11 +376,11 @@ void generate_elephant_with_hole() { Halfedge_handle nh=opposite(halfedge(fd,poly), poly); CGAL::Euler::remove_face(halfedge(fd, poly), poly); - std::ofstream output("elephant_triangle_hole.off"); + std::ofstream output("elephant_triangle_hole_no_DT3.off"); output << poly; output.close(); CGAL::Euler::remove_face(nh, poly); - output.open("elephant_quad_hole.off"); + output.open("elephant_quad_hole_no_DT3.off"); output << poly; return; } @@ -396,8 +396,8 @@ typedef CGAL::Surface_mesh Polyhedron; generate_elephant_with_hole(); std::vector input_files; - input_files.push_back("elephant_triangle_hole.off"); - input_files.push_back("elephant_quad_hole.off"); + input_files.push_back("elephant_triangle_hole_no_DT3.off"); + input_files.push_back("elephant_quad_hole_no_DT3.off"); input_files.push_back(CGAL::data_file_path("meshes/mech-holes-shark.off")); // std::cerr.precision(15); for(std::vector::iterator it = input_files.begin(); it != input_files.end(); ++it) { diff --git a/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp b/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp index a50aef4180b..9f6f4c9b5a2 100644 --- a/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp +++ b/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp @@ -19,7 +19,6 @@ public: } QValidator::State validate ( QString & input, int & pos ) const { - fixup(input); return QDoubleValidator::validate(input, pos); } }; @@ -59,7 +58,7 @@ public: void DoubleEdit::setRange(double rmin, double rmax) { - this->validator->setRange(rmin, rmax, this->validator->decimals()); + this->validator->setRange(rmin, rmax, -1); } double DoubleEdit::getValue() diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index 563885a376c..91390c759dd 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -9,6 +9,10 @@ #include "Scene_polylines_item.h" #include "Scene_points_with_normal_item.h" +// Since we want to do visualization and interruption, it's better to use the sorted priority queue, +// even if it is slower +#define CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + #include #include @@ -35,13 +39,13 @@ using TS_Oracle = CGAL::Alpha_wraps_3::internal::Triangle_soup_oracle; using SS_Oracle = CGAL::Alpha_wraps_3::internal::Segment_soup_oracle; using Oracle = CGAL::Alpha_wraps_3::internal::Point_set_oracle; -using Wrapper = CGAL::Alpha_wraps_3::internal::Alpha_wrap_3; +using Wrapper = CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3; // Here is the pipeline for the interruption box: // - The main window is connected to a wrapping thread, which performs the wrapping. // - The wrapping has a visitor, AW3_interrupter_visitor, which has a shared_ptr to a Boolean -// - When the user clicks the box, the Boolean is switched to *false*, and the visitor throws -// - The wrapping thread catches the exception, and creates the wip mesh +// - When the user clicks the box, the Boolean is switched to *false* +// - The wrapping thread creates the wip mesh // Here is the pipeline for the iterative visualization: // - The main window is connected to a wrapping thread, which performs the wrapping. @@ -113,10 +117,10 @@ public: if(!points || !faces || !fcolors || !vcolors) return; - // If the next top of the queue has vertices on the bbox, don't draw (as to avoid producing + // If the next top of the queue has vertices on the bbox, don't draw (try to avoid producing // spikes in the visualization) // const auto& gate = wrapper.queue().top(); -// if(wrapper.triangulation().number_of_vertices() > 500 && gate.is_artificial_facet()) +// if(wrapper.triangulation().number_of_vertices() > 500 && gate.is_permissive_facet()) // return; // Skip some... @@ -201,9 +205,6 @@ public: } }; -// Use a throw to get out of the AW3 refinement loop -class Out_of_patience_exception : public std::exception { }; - template struct AW3_interrupter_visitor : BaseVisitor @@ -215,15 +216,10 @@ struct AW3_interrupter_visitor : BaseVisitor(base) { } - // Only overload this one because it gives a better state of the wrap (for other visitor calls, - // we often get tetrahedral spikes because there are artificial gates in the queue) - template - void before_Steiner_point_insertion(const Wrapper& wrapper, const Point& p) + template + constexpr bool go_further(const Wrapper&) { - if(*should_stop) - throw Out_of_patience_exception(); - - return BaseVisitor::before_Steiner_point_insertion(wrapper, p); + return !(*should_stop); } }; @@ -273,25 +269,14 @@ public: QElapsedTimer elapsed_timer; elapsed_timer.start(); - // try-catch because the stop visitor currently uses a throw - try - { - wrapper(alpha, offset, wrap, - CGAL::parameters::do_enforce_manifoldness(enforce_manifoldness) - .visitor(visitor)); + wrapper(alpha, offset, wrap, + CGAL::parameters::do_enforce_manifoldness(enforce_manifoldness) + .visitor(visitor)); + if(wrapper.queue().empty()) Q_EMIT done(this); - } - catch(const Out_of_patience_exception&) - { - if(enforce_manifoldness) - wrapper.make_manifold(); - - // extract the wrap in its current state - wrapper.extract_surface(wrap, CGAL::get(CGAL::vertex_point, wrap), !enforce_manifoldness); - + else Q_EMIT interrupted(this); - } std::cout << "Wrapping took " << elapsed_timer.elapsed() / 1000. << "s" << std::endl; } @@ -562,8 +547,6 @@ public Q_SLOTS: triangles.emplace_back(get(vpm, target(h, *pMesh)), get(vpm, target(next(h, *pMesh), *pMesh)), get(vpm, source(h, *pMesh))); - - m_wrap_bbox += triangles.back().bbox(); } continue; @@ -586,8 +569,6 @@ public Q_SLOTS: triangles.emplace_back(soup_item->points()[p[0]], soup_item->points()[p[1]], soup_item->points()[p[2]]); - - m_wrap_bbox += triangles.back().bbox(); } continue; @@ -614,8 +595,6 @@ public Q_SLOTS: triangles.emplace_back(get(vpm, target(h, *pMesh)), get(vpm, target(next(h, *pMesh), *pMesh)), get(vpm, source(h, *pMesh))); - - m_wrap_bbox += triangles.back().bbox(); } segments.reserve(segments.size() + selection_item->selected_edges.size()); @@ -623,16 +602,12 @@ public Q_SLOTS: { segments.emplace_back(get(vpm, target(halfedge(e, *pMesh), *pMesh)), get(vpm, target(opposite(halfedge(e, *pMesh), *pMesh), *pMesh))); - - m_wrap_bbox += segments.back().bbox(); } points.reserve(points.size() + selection_item->selected_vertices.size()); for(const auto& v : selection_item->selected_vertices) { points.push_back(get(vpm, v)); - - m_wrap_bbox += points.back().bbox(); } continue; @@ -671,6 +646,22 @@ public Q_SLOTS: std::cout << segments.size() << " edges" << std::endl; std::cout << points.size() << " points" << std::endl; + if(!triangles.empty()) + m_wrap_bbox = triangles.front().bbox(); + else if(!segments.empty()) + m_wrap_bbox = segments.front().bbox(); + else if(!points.empty()) + m_wrap_bbox = points.front().bbox(); + + for(const Kernel::Triangle_3& tr : triangles) + m_wrap_bbox += tr.bbox(); + for(const Kernel::Segment_3& sg : segments) + m_wrap_bbox += sg.bbox(); + for(const Kernel::Point_3& pt : points) + m_wrap_bbox += pt.bbox(); + + std::cout << "Bbox:\n" << m_wrap_bbox << std::endl; + // The relative value uses the bbox of the full scene and not that of selected items to wrap // This is intentional, both because it's tedious to make it otherwise, and because it seems // to be simpler to compare between "all wrapped" / "some wrapped" @@ -703,8 +694,8 @@ public Q_SLOTS: const bool use_message_box = ui.enableMessageBox->isChecked(); - std::cout << "Wrapping edges? " << std::boolalpha << wrap_segments << std::endl; std::cout << "Wrapping faces? " << std::boolalpha << wrap_triangles << std::endl; + std::cout << "Wrapping edges? " << std::boolalpha << wrap_segments << std::endl; if(!wrap_triangles) { @@ -756,15 +747,11 @@ public Q_SLOTS: if(alpha <= 0. || offset <= 0.) { - print_message("Warning: alpha/offset must be strictly positive - nothing to wrap"); + print_message("Warning: alpha/offset must be strictly positive"); QApplication::restoreOverrideCursor(); return; } - // Switch from 'wait' to 'busy' - QApplication::restoreOverrideCursor(); - QApplication::setOverrideCursor(Qt::BusyCursor); - for(int index : this->scene->selectionIndices()) { Scene_surface_mesh_item* sm_item = qobject_cast(this->scene->item(index)); @@ -824,6 +811,10 @@ public Q_SLOTS: // Create message box with stop button if(use_message_box) { + // Switch from 'wait' to 'busy' + QApplication::restoreOverrideCursor(); + QApplication::setOverrideCursor(Qt::BusyCursor); + m_message_box = new QMessageBox(QMessageBox::NoIcon, "Wrapping", "Wrapping in progress...", @@ -841,6 +832,8 @@ public Q_SLOTS: } // Actual start + QApplication::setOverrideCursor(Qt::WaitCursor); + wrapper_thread->start(); CGAL::Three::Three::getMutex()->lock(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index 521576aa657..47f220f6e58 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -624,6 +624,8 @@ void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, ui.approx->setRange(diag * 10e-7, // min diag); // max ui.approx->setValue(approx); + ui.approx->setToolTip(tr("Approximation error: in [%1; %2]") + .arg(diag * 10e-7).arg(diag)); ui.protect->setEnabled(features_protection_available); ui.protect->setChecked(features_protection_available); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp index abc82f15033..d48aef5bb1f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp @@ -134,6 +134,8 @@ Meshing_thread* cgal_code_mesh_3(QList pMeshes, param.manifold = manifold; param.protect_features = protect_features || protect_borders; param.use_sizing_field_with_aabb_tree = polylines.empty() && protect_features; + param.image_3_ptr = nullptr; + param.weights_ptr = nullptr; typedef ::Mesh_function Mesh_function; @@ -237,6 +239,8 @@ Meshing_thread* cgal_code_mesh_3(const QList pMeshes, param.manifold = manifold; param.protect_features = protect_features || protect_borders; param.use_sizing_field_with_aabb_tree = protect_features; + param.image_3_ptr = nullptr; + param.weights_ptr = nullptr; typedef ::Mesh_function Mesh_function; @@ -292,7 +296,8 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, param.manifold = manifold; param.detect_connected_components = false; // to avoid random values // in the debug displays - + param.image_3_ptr = nullptr; + param.weights_ptr = nullptr; typedef ::Mesh_function Mesh_function; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h index dfd31aadd84..8bc5a6c3ff6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h @@ -138,20 +138,40 @@ QStringList Mesh_parameters:: log() const { - return QStringList() - << QString("edge max size: %1").arg(edge_sizing) - << QString("edge min size: %1").arg(edge_min_sizing) - << QString("facet min angle: %1").arg(facet_angle) - << QString("facet max size: %1").arg(facet_sizing) - << QString("facet min size: %1").arg(facet_min_sizing) - << QString("facet approx error: %1").arg(facet_approx) - << QString("tet shape (radius-edge): %1").arg(tet_shape) - << QString("tet max size: %1").arg(tet_sizing) - << QString("tet min size: %1").arg(tet_min_sizing) - << QString("detect connected components: %1") - .arg(detect_connected_components) - << QString("use weights: %1").arg(weights_ptr != nullptr) - << QString("protect features: %1").arg(protect_features); + QStringList res("Mesh criteria"); + + // doubles + if(edge_sizing > 0) + res << QString("edge max size: %1").arg(edge_sizing); + if(edge_min_sizing > 0) + res << QString("edge min size: %1").arg(edge_min_sizing); + if(facet_angle > 0) + res << QString("facet min angle: %1").arg(facet_angle); + if(facet_sizing > 0) + res << QString("facet max size: %1").arg(facet_sizing); + if(facet_min_sizing > 0) + res << QString("facet min size: %1").arg(facet_min_sizing); + if(facet_approx > 0) + res << QString("facet approx error: %1").arg(facet_approx); + if(tet_shape > 0) + res << QString("tet shape (radius-edge): %1").arg(tet_shape); + if(tet_sizing > 0) + res << QString("tet max size: %1").arg(tet_sizing); + if(tet_min_sizing > 0) + res << QString("tet min size: %1").arg(tet_min_sizing); + + // booleans + res << QString("protect features: %1").arg(protect_features); + if(image_3_ptr != nullptr) + { + res << QString("detect connected components: %1") + .arg(detect_connected_components); + res << QString("use weights: %1").arg(weights_ptr != nullptr); + } + res << QString("use aabb tree: %1").arg(use_sizing_field_with_aabb_tree); + res << QString("manifold: %1").arg(manifold); + + return res; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt index 2e030be7f6d..8c27fa77cad 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt @@ -13,6 +13,13 @@ target_link_libraries( PUBLIC scene_surface_mesh_item scene_polygon_soup_item scene_points_with_normal_item) +polyhedron_demo_plugin(point_set_from_sampling_plugin + Point_set_from_sampling_plugin) +target_link_libraries( + point_set_from_sampling_plugin + PUBLIC scene_surface_mesh_item scene_polygon_soup_item + scene_points_with_normal_item) + polyhedron_demo_plugin(diff_between_meshes_plugin Diff_between_meshes_plugin) target_link_libraries(diff_between_meshes_plugin PUBLIC scene_surface_mesh_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp new file mode 100644 index 00000000000..aa6ea4c1ba0 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp @@ -0,0 +1,150 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Scene_points_with_normal_item.h" +#include "Scene_surface_mesh_item.h" +#include "Scene_polygon_soup_item.h" + +#include +#include "Messages_interface.h" + +#include +#include + +using namespace CGAL::Three; +class Polyhedron_demo_point_set_from_sampling_plugin : + public QObject, + public Polyhedron_demo_plugin_interface +{ + Q_OBJECT + Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + +public: + void init(QMainWindow* mainWindow, + CGAL::Three::Scene_interface* scene_interface, Messages_interface*); + + bool applicable(QAction*) const { + const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex(); + + return qobject_cast(scene->item(index)) + || qobject_cast(scene->item(index)); + } + + QList actions() const; + +public Q_SLOTS: + void createPointSet(); + +private: + CGAL::Three::Scene_interface* scene; + QAction* actionPointSetFromSampling; + + +}; // end Polyhedron_demo_point_set_from_sampling_plugin + +void Polyhedron_demo_point_set_from_sampling_plugin::init(QMainWindow* mainWindow, + CGAL::Three::Scene_interface* scene_interface, + Messages_interface*) +{ + scene = scene_interface; + actionPointSetFromSampling = new QAction(tr("Create Point Set from Sampling"), mainWindow); + actionPointSetFromSampling->setObjectName("actionPointSetFromSampling"); + connect(actionPointSetFromSampling, SIGNAL(triggered()), + this, SLOT(createPointSet())); +} + +QList Polyhedron_demo_point_set_from_sampling_plugin::actions() const { + return QList() << actionPointSetFromSampling; +} + + + +void Polyhedron_demo_point_set_from_sampling_plugin::createPointSet() +{ + QApplication::setOverrideCursor(Qt::WaitCursor); + const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex(); + + Scene_points_with_normal_item* points = new Scene_points_with_normal_item(); + + + if (points){ + points->setColor(Qt::blue); + }else{ + QApplication::restoreOverrideCursor(); + return; + } + Scene_surface_mesh_item* sm_item = + qobject_cast(scene->item(index)); + + if (sm_item){ + if(! CGAL::is_triangle_mesh(*sm_item->polyhedron())){ + CGAL::Three::Three::error(QString("The mesh must have triangle faces")); + QApplication::restoreOverrideCursor(); + return; + } + int nf = num_faces(*sm_item->polyhedron()); + + bool ok; + int nb = 0; + nb = QInputDialog::getInt(QApplication::activeWindow(), "Sampling", + "Number of sample points:", + nf , 0, (std::numeric_limits::max)(), 1, &ok); + + points->setName(QString("%1 (sampled)").arg(sm_item->name())); + if( ok & (nb > 0)){ + points->point_set()->reserve(nb); + CGAL::Polygon_mesh_processing::sample_triangle_mesh(*sm_item->polyhedron(), + points->point_set()->point_back_inserter(), + CGAL::parameters::number_of_points_on_faces(nb) + .do_sample_vertices(false) + .do_sample_edges(false)); + scene->addItem(points); + } + } + + Scene_polygon_soup_item* soup_item = + qobject_cast(scene->item(index)); + + if (soup_item){ + int nf = static_cast(soup_item->polygons().size()); + + for(const auto& f : soup_item->polygons()){ + if(f.size() != 3){ + CGAL::Three::Three::error(QString("The polygons must be triangles")); + QApplication::restoreOverrideCursor(); + return; + } + } + + bool ok; + int nb = 0; + nb = QInputDialog::getInt(QApplication::activeWindow(), "Sampling", + "Number of sample points:", + nf , 0, (std::numeric_limits::max)(), 1, &ok); + points->setName(QString("%1 (sampled)").arg(soup_item->name())); + if( ok & (nb > 0)){ + points->point_set()->reserve(nb); + CGAL::Polygon_mesh_processing::sample_triangle_soup(soup_item->points(), + soup_item->polygons(), + points->point_set()->point_back_inserter(), + CGAL::parameters::number_of_points_on_faces(nb) + .do_sample_vertices(false) + .do_sample_edges(false)); + scene->addItem(points); + } + } + + + QApplication::restoreOverrideCursor(); +} + + +#include "Point_set_from_sampling_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp index 1a0a9e34f35..d651bdcd61b 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp @@ -614,12 +614,20 @@ endPointSet(const QMatrix4x4& transform_matrix) Point_set* new_ps = new_item->point_set(); CGAL::qglviewer::Vec c = aff_transformed_item->center(); + QMatrix3x3 normal_matrix = transform_matrix.normalMatrix(); + for(Point_set::Index idx : *new_ps) { QVector3D vec = transform_matrix.map(QVector3D(new_ps->point(idx).x() - c.x, new_ps->point(idx).y() - c.y, new_ps->point(idx).z() - c.z)); new_ps->point(idx) = Kernel::Point_3(vec.x(), vec.y(), vec.z()); + if (new_ps->has_normal_map()) { + QVector3D n(new_ps->normal(idx).x(), new_ps->normal(idx).y(), new_ps->normal(idx).z()); + new_ps->normal(idx) = Kernel::Vector_3(normal_matrix(0, 0) * n[0] + normal_matrix(0, 1) * n[1] + normal_matrix(0, 2) * n[2], + normal_matrix(1, 0) * n[0] + normal_matrix(1, 1) * n[1] + normal_matrix(1, 2) * n[2], + normal_matrix(2, 0) * n[0] + normal_matrix(2, 1) * n[1] + normal_matrix(2, 2) * n[2]); + } } new_item->setName(aff_transformed_item->name()); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt index 2651b3601e7..232e6f364d6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt @@ -133,7 +133,11 @@ target_link_libraries( qt6_wrap_ui( repairUI_FILES RemoveNeedlesDialog.ui SelfSnapDialog.ui) polyhedron_demo_plugin(repair_polyhedron_plugin Repair_polyhedron_plugin ${repairUI_FILES} KEYWORDS PMP) -target_link_libraries(repair_polyhedron_plugin PUBLIC scene_points_with_normal_item scene_surface_mesh_item) +target_link_libraries(repair_polyhedron_plugin PUBLIC scene_points_with_normal_item scene_surface_mesh_item scene_polygon_soup_item) +if(TARGET CGAL::TBB_support) + target_link_libraries(repair_polyhedron_plugin PUBLIC CGAL::TBB_support) +endif() + if(TARGET CGAL::Eigen3_support) qt6_wrap_ui(isotropicRemeshingUI_FILES Isotropic_remeshing_dialog.ui) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp index c4c68388d8c..b0ac1f85996 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp @@ -1,6 +1,7 @@ #include #include "Scene_surface_mesh_item.h" +#include "Scene_polygon_soup_item.h" #include "Scene_points_with_normal_item.h" #include #include @@ -19,6 +20,8 @@ #include #include #include +#include +#include #include "ui_RemoveNeedlesDialog.h" #include "ui_SelfSnapDialog.h" @@ -52,8 +55,9 @@ public: actionDuplicateNMVertices = new QAction(tr("Duplicate Non-Manifold Vertices"), mw); actionExtractNMVertices = new QAction(tr("Extract Non-Manifold Vertices"), mw); actionMergeDuplicatedVerticesOnBoundaryCycles = new QAction(tr("Merge Duplicated Vertices on Boundary Cycles"), mw); - actionAutorefine = new QAction(tr("Autorefine Mesh"), mw); - actionAutorefineAndRMSelfIntersections = new QAction(tr("Autorefine and Remove Self-Intersections"), mw); + actionAutorefine = new QAction(tr("Autorefine Mesh (Deprecated)"), mw); + actionNewAutorefine = new QAction(tr("Autorefine"), mw); + actionAutorefineAndRMSelfIntersections = new QAction(tr("Autorefine and Remove Self-Intersections (Deprecated)"), mw); actionRemoveNeedlesAndCaps = new QAction(tr("Remove Needles And Caps")); actionSnapBorders = new QAction(tr("Snap Boundaries")); @@ -65,6 +69,7 @@ public: actionExtractNMVertices->setObjectName("actionExtractNMVertices"); actionMergeDuplicatedVerticesOnBoundaryCycles->setObjectName("actionMergeDuplicatedVerticesOnBoundaryCycles"); actionAutorefine->setObjectName("actionAutorefine"); + actionNewAutorefine->setObjectName("actionNewAutorefine"); actionAutorefineAndRMSelfIntersections->setObjectName("actionAutorefineAndRMSelfIntersections"); actionRemoveNeedlesAndCaps->setObjectName("actionRemoveNeedlesAndCaps"); actionSnapBorders->setObjectName("actionSnapBorders"); @@ -77,6 +82,7 @@ public: actionExtractNMVertices->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); actionMergeDuplicatedVerticesOnBoundaryCycles->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); actionAutorefine->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); + actionNewAutorefine->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); actionAutorefineAndRMSelfIntersections->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); actionSnapBorders->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); @@ -93,16 +99,29 @@ public: << actionExtractNMVertices << actionMergeDuplicatedVerticesOnBoundaryCycles << actionAutorefine + << actionNewAutorefine << actionAutorefineAndRMSelfIntersections << actionRemoveNeedlesAndCaps << actionSnapBorders; } - bool applicable(QAction*) const + bool applicable(QAction* action) const { - int item_id = scene->mainSelectionIndex(); - return qobject_cast(scene->item(item_id)); + if (action!=actionNewAutorefine) + { + int item_id = scene->mainSelectionIndex(); + return qobject_cast(scene->item(item_id)); + } + for (Scene_interface::Item_id index : scene->selectionIndices()) + { + if (qobject_cast(scene->item(index))) + return true; + if (qobject_cast(scene->item(index))) + return true; + } + return false; } + template void on_actionRemoveIsolatedVertices_triggered(Scene_interface::Item_id index); template @@ -120,6 +139,8 @@ public: template void on_actionAutorefine_triggered(Scene_interface::Item_id index); template + void on_actionNewAutorefine_triggered(const std::vector& indices); + template void on_actionAutorefineAndRMSelfIntersections_triggered(Scene_interface::Item_id index); public Q_SLOTS: @@ -131,6 +152,7 @@ public Q_SLOTS: void on_actionExtractNMVertices_triggered(); void on_actionMergeDuplicatedVerticesOnBoundaryCycles_triggered(); void on_actionAutorefine_triggered(); + void on_actionNewAutorefine_triggered(); void on_actionAutorefineAndRMSelfIntersections_triggered(); void on_actionRemoveNeedlesAndCaps_triggered(); void on_actionSnapBorders_triggered(); @@ -144,6 +166,7 @@ private: QAction* actionExtractNMVertices; QAction* actionMergeDuplicatedVerticesOnBoundaryCycles; QAction* actionAutorefine; + QAction* actionNewAutorefine; QAction* actionAutorefineAndRMSelfIntersections; QAction* actionRemoveNeedlesAndCaps; QAction* actionSnapBorders; @@ -421,6 +444,78 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionAutorefine_triggered() QApplication::restoreOverrideCursor(); } +template +void Polyhedron_demo_repair_polyhedron_plugin::on_actionNewAutorefine_triggered(const std::vector& indices) +{ + namespace PMP = CGAL::Polygon_mesh_processing; + Polygon_soup::Points points; + Polygon_soup::Polygons polygons; + + if (indices.size()==1) + { + if (Scene_surface_mesh_item* smi_ptr = qobject_cast(scene->item(indices[0]))) + PMP::polygon_mesh_to_polygon_soup(*smi_ptr->polyhedron(), points, polygons); + else if (Scene_polygon_soup_item* spi_ptr = qobject_cast(scene->item(indices[0]))) + { + points = spi_ptr->points(); + polygons = spi_ptr->polygons(); + } + } + else + { + for (Scene_interface::Item_id id : indices) + { + Polygon_soup::Points l_points; + Polygon_soup::Polygons l_polygons; + + if (Scene_surface_mesh_item* smi_ptr = qobject_cast(scene->item(id))) + PMP::polygon_mesh_to_polygon_soup(*smi_ptr->polyhedron(), l_points, l_polygons); + else if (Scene_polygon_soup_item* spi_ptr = qobject_cast(scene->item(id))) + { + l_points = spi_ptr->points(); + l_polygons = spi_ptr->polygons(); + } + std::size_t offset=points.size(); + points.insert(points.end(), l_points.begin(), l_points.end()); + std::size_t psize=polygons.size(); + polygons.insert(polygons.end(), l_polygons.begin(), l_polygons.end()); + for (std::size_t i=psize; iload(points, polygons); + QString name = scene->item(indices[0])->name(); + for (std::size_t k=1; kitem(indices[k])->name(); + new_item->setName(name+" autorefined"); + + scene->addItem(new_item); + new_item->invalidateOpenGLBuffers(); + Q_EMIT new_item->itemChanged(); +} + +void Polyhedron_demo_repair_polyhedron_plugin::on_actionNewAutorefine_triggered() +{ + std::vector indices; + for (Scene_interface::Item_id index : scene->selectionIndices()) + { + if (qobject_cast(scene->item(index))) + indices.push_back(index); + else if (qobject_cast(scene->item(index))) + indices.push_back(index); + } + QApplication::setOverrideCursor(Qt::WaitCursor); + on_actionNewAutorefine_triggered(indices); + QApplication::restoreOverrideCursor(); +} + template void Polyhedron_demo_repair_polyhedron_plugin::on_actionAutorefineAndRMSelfIntersections_triggered(Scene_interface::Item_id index) { diff --git a/Polyhedron/demo/Polyhedron/Plugins/Tetrahedral_remeshing/Tetrahedral_remeshing_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Tetrahedral_remeshing/Tetrahedral_remeshing_plugin.cpp index 05875d4e6ca..a64a44fa331 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Tetrahedral_remeshing/Tetrahedral_remeshing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Tetrahedral_remeshing/Tetrahedral_remeshing_plugin.cpp @@ -12,6 +12,7 @@ #include "C3t3_type.h" #include +#include #include #include @@ -80,6 +81,7 @@ public Q_SLOTS: Scene_c3t3_item* c3t3_item = qobject_cast(scene->item(index)); + const auto& c3t3 = c3t3_item->c3t3(); if (c3t3_item) { @@ -100,18 +102,37 @@ public Q_SLOTS: bool protect = ui.protect_checkbox->isChecked(); bool smooth_edges = ui.smoothEdges_checkBox->isChecked(); + // collect constraints + using Vertex_handle = Tr::Vertex_handle; + using Vertex_pair = std::pair; + using Constraints_set = std::unordered_set>; + using Constraints_pmap = CGAL::Boolean_property_map; + // wait cursor QApplication::setOverrideCursor(Qt::WaitCursor); QElapsedTimer time; time.start(); + Constraints_set constraints; + for (const auto e : c3t3_item->c3t3().triangulation().finite_edges()) + { + if (c3t3_item->c3t3().is_in_complex(e) + || CGAL::Tetrahedral_remeshing::protecting_balls_intersect(e, c3t3)) + { + Vertex_pair evv = CGAL::Tetrahedral_remeshing::make_vertex_pair(e); + constraints.insert(evv); + } + } + CGAL::tetrahedral_isotropic_remeshing( - c3t3_item->c3t3(), - target_length, - CGAL::parameters::remesh_boundaries(!protect) - .number_of_iterations(nb_iter) - .smooth_constrained_edges(smooth_edges)); + c3t3_item->c3t3(), + target_length, + CGAL::parameters::remesh_boundaries(!protect) + .number_of_iterations(nb_iter) + .smooth_constrained_edges(smooth_edges) + .edge_is_constrained_map(Constraints_pmap(constraints)) + ); std::cout << "Remeshing done (" << time.elapsed() << " ms)" << std::endl; diff --git a/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h b/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h index 8114a141aa7..a10c0e632bf 100644 --- a/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h +++ b/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h @@ -75,7 +75,7 @@ This function overloads the generic function \link PkgBGLIoFuncsOFF `write_OFF(s \sa \link PkgPolyhedronIOFunc `operator>>(std::istream& in, Polyhedron_3& P)` \endlink */ template -bool write_OFF( std::ostream& out, Polyhedron_3& P); +bool write_OFF( std::ostream& out, const Polyhedron_3& P); /*! \relates Polyhedron_3 @@ -83,7 +83,7 @@ bool write_OFF( std::ostream& out, Polyhedron_3& P); \link PkgPolyhedronIOFunc `CGAL::IO::write_OFF(std::ostream&, Polyhedron_3&)` \endlink should be used instead. */ template -bool write_off( std::ostream& out, Polyhedron_3& P); +bool write_off( std::ostream& out, const Polyhedron_3& P); /*! \relates Polyhedron_3 @@ -91,7 +91,6 @@ bool write_off( std::ostream& out, Polyhedron_3& P); calls \link write_OFF() `write_OFF(out, P)` \endlink. */ template -std::ostream& operator<<( std::ostream& out, Polyhedron_3& P); +std::ostream& operator<<( std::ostream& out, const Polyhedron_3& P); } /* namespace CGAL */ - diff --git a/Polynomial/include/CGAL/Polynomial.h b/Polynomial/include/CGAL/Polynomial.h index b3681eb43b5..ad61432cd40 100644 --- a/Polynomial/include/CGAL/Polynomial.h +++ b/Polynomial/include/CGAL/Polynomial.h @@ -34,7 +34,6 @@ #include #include #include -#include #include #include diff --git a/Polynomial/include/CGAL/Polynomial/Polynomial_type.h b/Polynomial/include/CGAL/Polynomial/Polynomial_type.h index e2529d2e349..de6bcdc447b 100644 --- a/Polynomial/include/CGAL/Polynomial/Polynomial_type.h +++ b/Polynomial/include/CGAL/Polynomial/Polynomial_type.h @@ -486,9 +486,9 @@ public: // and NT would be changed by NTX typedef typename Fraction_traits::Is_fraction Is_fraction; typedef typename Coercion_traits::Type Type; - typedef typename ::boost::mpl::if_c< - ::std::is_same::value, Is_fraction, CGAL::Tag_false - >::type If_decomposable_AND_Type_equals_NT; + typedef std::conditional_t< + std::is_same_v, Is_fraction, CGAL::Tag_false + > If_decomposable_AND_Type_equals_NT; return sign_at_(x,If_decomposable_AND_Type_equals_NT()); } diff --git a/Polynomial/include/CGAL/Polynomial_traits_d.h b/Polynomial/include/CGAL/Polynomial_traits_d.h index 6eb4f0d6e3f..dfbf7cf3135 100644 --- a/Polynomial/include/CGAL/Polynomial_traits_d.h +++ b/Polynomial/include/CGAL/Polynomial_traits_d.h @@ -999,7 +999,7 @@ public: // Sign_at, Sign_at_homogeneous, Compare // define XXX_ even though ICoeff may not be Real_embeddable - // select propoer XXX among XXX_ or Null_functor using ::boost::mpl::if_ + // select propoer XXX among XXX_ or Null_functor using ::std::conditional_t private: struct Sign_at_ { private: @@ -1036,8 +1036,8 @@ private: typedef Real_embeddable_traits RET_IC; typedef typename RET_IC::Is_real_embeddable IC_is_real_embeddable; public: - typedef typename ::boost::mpl::if_::type Sign_at; - typedef typename ::boost::mpl::if_::type Sign_at_homogeneous; + typedef std::conditional_t Sign_at; + typedef std::conditional_t Sign_at_homogeneous; typedef typename Real_embeddable_traits::Compare Compare; diff --git a/Property_map/include/CGAL/Dynamic_property_map.h b/Property_map/include/CGAL/Dynamic_property_map.h index a7dc48b5354..bca414e19b0 100644 --- a/Property_map/include/CGAL/Dynamic_property_map.h +++ b/Property_map/include/CGAL/Dynamic_property_map.h @@ -19,7 +19,6 @@ #include #include -#include #include @@ -127,9 +126,9 @@ struct Dynamic_with_index { typedef Key key_type; typedef Value value_type; - typedef typename boost::mpl::if_< std::is_same, - value_type, - value_type&>::type reference; + typedef std::conditional_t< std::is_same_v, + value_type, + value_type&> reference; typedef boost::read_write_property_map_tag category; Dynamic_with_index() diff --git a/Property_map/include/CGAL/property_map.h b/Property_map/include/CGAL/property_map.h index 735c1f5da49..1154ab87b42 100644 --- a/Property_map/include/CGAL/property_map.h +++ b/Property_map/include/CGAL/property_map.h @@ -661,7 +661,7 @@ struct Boolean_property_map return pm.set_ptr->count(k) != 0; } - friend void put(Boolean_property_map& pm, const key_type& k, bool v) + friend void put(Boolean_property_map pm, const key_type& k, bool v) { CGAL_assertion(pm.set_ptr!=nullptr); if (v) diff --git a/QP_solver/test/QP_solver/test_solver.cpp b/QP_solver/test/QP_solver/test_solver.cpp index ad298449b55..4fc641cc286 100644 --- a/QP_solver/test/QP_solver/test_solver.cpp +++ b/QP_solver/test/QP_solver/test_solver.cpp @@ -282,6 +282,7 @@ bool process(const std::string& filename, { using std::cout; using std::endl; + using CGAL::check_tag; // extract verbosity: const int verbosity = options.find("Verbosity")->second; diff --git a/Ridges_3/examples/Ridges_3/Ridges_Umbilics_LCC.cpp b/Ridges_3/examples/Ridges_3/Ridges_Umbilics_LCC.cpp index 5373ac5e376..611be7e6c0b 100644 --- a/Ridges_3/examples/Ridges_3/Ridges_Umbilics_LCC.cpp +++ b/Ridges_3/examples/Ridges_3/Ridges_Umbilics_LCC.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include namespace po = boost::program_options; diff --git a/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h index f77f1d9c07f..ef7c6164f2d 100644 --- a/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h +++ b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/STL_Extension/include/CGAL/Compact_container.h b/STL_Extension/include/CGAL/Compact_container.h index 24f7ef91c72..81ff5cf1bce 100644 --- a/STL_Extension/include/CGAL/Compact_container.h +++ b/STL_Extension/include/CGAL/Compact_container.h @@ -35,8 +35,6 @@ #include #include -#include - // An STL like container with the following properties : // - to achieve compactness, it requires access to a pointer stored in T, // specified by a traits. This pointer is supposed to be 4 bytes aligned @@ -866,10 +864,10 @@ namespace internal { typedef typename DSC::value_type value_type; typedef typename DSC::size_type size_type; typedef typename DSC::difference_type difference_type; - typedef typename boost::mpl::if_c< Const, const value_type*, - value_type*>::type pointer; - typedef typename boost::mpl::if_c< Const, const value_type&, - value_type&>::type reference; + typedef std::conditional_t< Const, const value_type*, + value_type*> pointer; + typedef std::conditional_t< Const, const value_type&, + value_type&> reference; typedef std::bidirectional_iterator_tag iterator_category; // the initialization with nullptr is required by our Handle concept. diff --git a/STL_Extension/include/CGAL/Concurrent_compact_container.h b/STL_Extension/include/CGAL/Concurrent_compact_container.h index 7f18ab80f57..7f5533f92b7 100644 --- a/STL_Extension/include/CGAL/Concurrent_compact_container.h +++ b/STL_Extension/include/CGAL/Concurrent_compact_container.h @@ -36,8 +36,6 @@ #include #include -#include - namespace CGAL { #define CGAL_GENERATE_MEMBER_DETECTOR(X) \ diff --git a/STL_Extension/include/CGAL/Container_helper.h b/STL_Extension/include/CGAL/Container_helper.h index aeb66ea052b..18a98dfa456 100644 --- a/STL_Extension/include/CGAL/Container_helper.h +++ b/STL_Extension/include/CGAL/Container_helper.h @@ -38,10 +38,8 @@ void resize(Container& c, std::size_t size, // Container without a resize() function, but with a size() function (e.g. an array) template void resize(Container& CGAL_assertion_code(array), std::size_t CGAL_assertion_code(size), - std::enable_if_t< - boost::mpl::and_< - boost::mpl::not_ >, - has_size >::value >* = nullptr) + std::enable_if_t::value && + has_size::value >* = nullptr) { CGAL_assertion(array.size() == size); } @@ -50,8 +48,8 @@ void resize(Container& CGAL_assertion_code(array), std::size_t CGAL_assertion_co template void resize(Container&, std::size_t, std::enable_if_t< - !boost::mpl::or_, - has_size >::value >* = nullptr) + !(has_resize::value || + has_size::value)>* = nullptr) { } diff --git a/STL_Extension/include/CGAL/Handle_with_policy.h b/STL_Extension/include/CGAL/Handle_with_policy.h index 5f952a66e15..528bf8061d1 100644 --- a/STL_Extension/include/CGAL/Handle_with_policy.h +++ b/STL_Extension/include/CGAL/Handle_with_policy.h @@ -21,8 +21,6 @@ #include #include -#include - #include #ifdef CGAL_USE_LEDA @@ -728,10 +726,10 @@ public: static Bind bind; // Define type that is used for function matching - typedef typename ::boost::mpl::if_c< + typedef std::conditional_t< is_class_hierarchy, ::CGAL::Tag_true, - ::CGAL::Tag_false >::type + ::CGAL::Tag_false > Class_hierarchy; //! the internal representation, i.e., \c T plus a reference count diff --git a/STL_Extension/include/CGAL/Named_function_parameters.h b/STL_Extension/include/CGAL/Named_function_parameters.h index d0f1648f816..7558aae88f2 100644 --- a/STL_Extension/include/CGAL/Named_function_parameters.h +++ b/STL_Extension/include/CGAL/Named_function_parameters.h @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -143,14 +142,14 @@ struct Lookup_named_param_def typedef typename internal_np::Get_param::type NP_type; typedef typename internal_np::Get_param::reference NP_reference; - typedef typename boost::mpl::if_< - std::is_same, - D, NP_type>::type + typedef std::conditional_t< + std::is_same_v, + D, NP_type> type; - typedef typename boost::mpl::if_< - std::is_same, - D&, NP_reference>::type + typedef std::conditional_t< + std::is_same_v, + D&, NP_reference> reference; }; diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h index ece342c321b..8fc2baca0c3 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h @@ -55,7 +55,7 @@ perturb(const CGAL_NP_CLASS& np = parameters::default_values()) } template -Named_function_parameters<::CGAL::parameters::internal::Exude_options, ::CGAL::internal_np::exude_options_param_t, CGAL_NP_BASE> +Named_function_parameters<::CGAL::parameters::internal::Perturb_options, ::CGAL::internal_np::perturb_options_param_t, CGAL_NP_BASE> perturb(const CGAL_NP_CLASS_1& np1, const CGAL_NP_CLASS_2& np2, const NP& ... nps) { return perturb(::CGAL::internal_np::combine_named_parameters(np1, np2, nps...)); @@ -91,7 +91,7 @@ exude(const CGAL_NP_CLASS& np = parameters::default_values()) using ::CGAL::parameters::choose_parameter; using ::CGAL::parameters::get_parameter; double time_limit = choose_parameter(get_parameter(np,::CGAL::internal_np::maximum_running_time),::CGAL::parameters::internal::undef_parameter); - double sliver_bound = choose_parameter(get_parameter(np,::CGAL::internal_np::lower_sliver_bound),::CGAL::parameters::default_values_for_mesh_3::perturb_sliver_bound); + double sliver_bound = choose_parameter(get_parameter(np,::CGAL::internal_np::lower_sliver_bound),::CGAL::parameters::default_values_for_mesh_3::exude_sliver_bound); ::CGAL::parameters::internal::Exude_options options(true); @@ -304,7 +304,7 @@ mesh_3_options(const CGAL_NP_CLASS& np = parameters::default_values()) options.dump_after_refine_prefix=choose_parameter(get_parameter(np, ::CGAL::internal_np::dump_after_refine_prefix_param), ""); options.dump_after_glob_opt_prefix=choose_parameter(get_parameter(np, ::CGAL::internal_np::dump_after_glob_opt_prefix_param), ""); options.dump_after_perturb_prefix=choose_parameter(get_parameter(np, ::CGAL::internal_np::dump_after_perturb_prefix_param), ""); - options.dump_after_exude_prefix=choose_parameter(get_parameter(np, ::CGAL::internal_np::dump_after_refine_surface_prefix_param), ""); + options.dump_after_exude_prefix=choose_parameter(get_parameter(np, ::CGAL::internal_np::dump_after_exude_prefix_param), ""); options.number_of_initial_points=choose_parameter(get_parameter(np, ::CGAL::internal_np::number_of_initial_points_param), -1); options.nonlinear_growth_of_balls = choose_parameter(get_parameter(np, ::CGAL::internal_np::nonlinear_growth_of_balls_param), false); options.maximal_number_of_vertices=choose_parameter(get_parameter(np, ::CGAL::internal_np::maximal_number_of_vertices_param), 0); diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h index e22b053fe64..9b172f5b4c1 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -47,6 +47,7 @@ CGAL_add_named_parameter(implementation_tag_t, implementation_tag, implementatio CGAL_add_named_parameter(prevent_unselection_t, prevent_unselection, prevent_unselection) CGAL_add_named_parameter(verbose_t, verbose, verbose) +CGAL_add_named_parameter(concurrency_tag_t, concurrency_tag, concurrency_tag) // List of named parameters used for IO CGAL_add_named_parameter(vertex_normal_output_iterator_t, vertex_normal_output_iterator, vertex_normal_output_iterator) @@ -247,6 +248,8 @@ CGAL_add_named_parameter(smooth_constrained_edges_t, smooth_constrained_edges, s // List of named parameters used in Alpha_wrap_3 CGAL_add_named_parameter(do_enforce_manifoldness_t, do_enforce_manifoldness, do_enforce_manifoldness) CGAL_add_named_parameter(seed_points_t, seed_points, seed_points) +CGAL_add_named_parameter(refine_triangulation_t, refine_triangulation, refine_triangulation) +CGAL_add_named_parameter(keep_inner_connected_components_t, keep_inner_connected_components, keep_inner_connected_components) // SMDS_3 parameters CGAL_add_named_parameter(surface_facets_t, surface_facets, surface_facets) @@ -347,19 +350,14 @@ CGAL_add_named_parameter_with_compatibility(features_detector_param_t, features_ CGAL_add_named_parameter_with_compatibility(input_features_param_t, input_features_param, input_features) CGAL_add_named_parameter_with_compatibility(edge_size_param_t, edge_size_param, edge_size) -CGAL_add_named_parameter_with_compatibility_cref_only(edge_sizing_field_param_t, edge_sizing_field_param, edge_sizing_field) CGAL_add_named_parameter_with_compatibility(edge_min_size_param_t, edge_min_size_param, edge_min_size) CGAL_add_named_parameter_with_compatibility(facet_angle_param_t, facet_angle_param, facet_angle) CGAL_add_named_parameter_with_compatibility(facet_size_param_t, facet_size_param, facet_size) -CGAL_add_named_parameter_with_compatibility_cref_only(facet_sizing_field_param_t, facet_sizing_field_param, facet_sizing_field) CGAL_add_named_parameter_with_compatibility_cref_only(facet_distance_param_t, facet_distance_param, facet_distance) CGAL_add_named_parameter_with_compatibility(facet_min_size_param_t, facet_min_size_param, facet_min_size) CGAL_add_named_parameter_with_compatibility(facet_topology_param_t, facet_topology_param, facet_topology) -CGAL_add_named_parameter_with_compatibility(cell_radius_edge_param_t, cell_radius_edge_param, cell_radius_edge) CGAL_add_named_parameter_with_compatibility(cell_radius_edge_ratio_param_t, cell_radius_edge_ratio_param, cell_radius_edge_ratio) CGAL_add_named_parameter_with_compatibility(cell_size_param_t, cell_size_param, cell_size) -CGAL_add_named_parameter_with_compatibility_cref_only(cell_sizing_field_param_t, cell_sizing_field_param, cell_sizing_field) -CGAL_add_named_parameter_with_compatibility_cref_only(sizing_field_param_t, sizing_field_param, sizing_field) CGAL_add_named_parameter_with_compatibility(cell_min_size_param_t, cell_min_size_param, cell_min_size) CGAL_add_named_parameter_with_compatibility(function_param_t, function_param, function) diff --git a/STL_Extension/include/CGAL/tags.h b/STL_Extension/include/CGAL/tags.h index 6aa1988e1cc..eba9ffdc721 100644 --- a/STL_Extension/include/CGAL/tags.h +++ b/STL_Extension/include/CGAL/tags.h @@ -19,26 +19,13 @@ #define CGAL_TAGS_H #include -#include namespace CGAL { struct Void {}; -// Boolean_tag is a model of the Boost Integral Constant concept. -// https://www.boost.org/libs/mpl/doc/refmanual/integral-constant.html template -struct Boolean_tag { - typedef boost::mpl::integral_c_tag tag; - typedef bool value_type; - static const bool value = b; - typedef Boolean_tag type; - operator bool() const { return this->value; } -}; -/* In C++11, try: -template -using Boolean_tag = std::integral_constant; -*/ +using Boolean_tag = std::bool_constant; typedef Boolean_tag Tag_true; typedef Boolean_tag Tag_false; diff --git a/STL_Extension/include/CGAL/transforming_iterator.h b/STL_Extension/include/CGAL/transforming_iterator.h index bd94ad33c4f..21d88e8f69c 100644 --- a/STL_Extension/include/CGAL/transforming_iterator.h +++ b/STL_Extension/include/CGAL/transforming_iterator.h @@ -12,7 +12,6 @@ #ifndef CGAL_TRANSFORMING_ITERATOR_H #define CGAL_TRANSFORMING_ITERATOR_H #include -#include #include #include #include @@ -55,10 +54,8 @@ class transforming_iterator_helper typedef typename Default::Get>>::type value_type; // Crappy heuristic. If we have *it that returns a Weighted_point and F that returns a reference to the Point contained in the Weighted_point it takes as argument, we do NOT want the transformed iterator to return a reference to the temporary *it. On the other hand, if *it returns an int n, and F returns a reference to array[n] it is not so good to lose the reference. This probably should be done elsewhere and should at least be made optional... - typedef typename boost::mpl::if_< - boost::mpl::or_, - std::is_integral >, - reference_, value_type>::type reference; + typedef std::conditional_t || std::is_integral_v, + reference_, value_type> reference; public: typedef boost::iterator_adaptor< diff --git a/STL_Extension/include/CGAL/type_traits.h b/STL_Extension/include/CGAL/type_traits.h index 59aae8a0307..c68386c7f76 100644 --- a/STL_Extension/include/CGAL/type_traits.h +++ b/STL_Extension/include/CGAL/type_traits.h @@ -21,10 +21,10 @@ namespace CGAL { template< class Base, class Derived > struct is_same_or_derived : - public ::boost::mpl::or_< - ::std::is_same< Base, Derived >, - ::boost::is_base_and_derived< Base, Derived > - >::type + public std::bool_constant< + ::std::is_same_v< Base, Derived > || + ::boost::is_base_and_derived< Base, Derived >::value + > {}; namespace cpp20 { diff --git a/STL_Extension/include/CGAL/type_traits/is_iterator.h b/STL_Extension/include/CGAL/type_traits/is_iterator.h index 6630dd8ceb1..8d476da2036 100644 --- a/STL_Extension/include/CGAL/type_traits/is_iterator.h +++ b/STL_Extension/include/CGAL/type_traits/is_iterator.h @@ -35,14 +35,13 @@ BOOST_MPL_HAS_XXX_TRAIT_DEF(reference) //provide all 5 nested types provided by iterator_traits template struct is_iterator_ - : public boost::mpl::or_< - boost::mpl::and_< - has_iterator_category, - has_value_type, - has_difference_type, - has_pointer, - has_reference >, - std::is_pointer > + : public std::bool_constant< + ( has_iterator_category::value && + has_value_type::value && + has_difference_type::value && + has_pointer::value && + has_reference::value) || + std::is_pointer_v > { }; template ::value> diff --git a/Scripts/developer_scripts/add_toc_to_github_wiki_page.py b/Scripts/developer_scripts/add_toc_to_github_wiki_page.py index ce61f49db7e..f9f58e4f5b5 100644 --- a/Scripts/developer_scripts/add_toc_to_github_wiki_page.py +++ b/Scripts/developer_scripts/add_toc_to_github_wiki_page.py @@ -1,125 +1,138 @@ -from sys import argv -from sys import exit import codecs import re import argparse +import sys +from urllib.parse import quote parser = argparse.ArgumentParser() -parser.add_argument("filename", - help="the Mardown file to process") -parser.add_argument("--codebase", - help="for a Markdown file of Codebase instead of Github", - action="store_true") -parser.add_argument("--h1", - help="support level one sections (h1)", - action="store_true") +parser.add_argument("filename", help="the Markdown file to process") +parser.add_argument( + "--codebase", + help="for a Markdown file of Codebase instead of Github", + action="store_true", +) +parser.add_argument("--h1", help="support level one sections (h1)", action="store_true") +parser.add_argument("--max-level", help="maximum level of sections", type=int, default = 5) args = parser.parse_args() + # a probably incomplete version to generate an anchor from a section name def get_anchor(s): - s = s.replace("`","") - s = s.replace("(","") - s = s.replace(")","") - s = s.replace(".","") - s = s.replace("#","") - s = s.replace(":","") - s = s.replace(",","") - s = s.replace(";","") - if args.codebase: - s = s.replace("/","-") - else: - s = s.replace("/","") - s = s.replace("<","") - s = s.replace(">","") - s = s.replace("+","") - s = s.replace("=","") - s = s.replace("?","") - s = s.replace("@","") - s = s.lstrip(" ") - s = s.rstrip("\n") - s = s.rstrip(" ") - s = re.sub(r'\s+','-',s) - if not args.codebase: - s = s.lower() - if args.codebase: - s = s.replace("'","-and-39-") - return "#"+s + s = s.replace("`", "") + s = s.replace("(", "") + s = s.replace(")", "") + if not args.codebase: + s = s.replace(".", "") + s = s.replace("#", "") + s = s.replace(":", "") + s = s.replace(",", "") + s = s.replace(";", "") + if args.codebase: + s = s.replace("/", "-") + else: + s = s.replace("/", "") + s = s.replace("<", "") + s = s.replace(">", "") + s = s.replace("+", "") + s = s.replace("=", "") + s = s.replace("?", "") + s = s.replace("@", "") + s = s.lstrip(" ") + s = s.rstrip("\n") + s = s.rstrip(" ") + if not args.codebase: + s = s.lower() + if args.codebase: + s = s.replace("' ", "-and-39-") + s = s.replace("'", "-and-39-") + s = re.sub(r"\s+", "-", s) + return "#" + quote(s) + # indices the nesting level (first level allowed is ##) def get_level(s): - m = re.search('^(#+)\s', s) - if m: - return len(m.group(1)) - else: - return 0 + m = re.search(r"^(#+)\s", s) + if m: + return len(m.group(1)) + else: + return 0 + def get_name(s): - m = re.search('^#+\s+(.*)\s*$', s) - if m: - return m.group(1) - else: - return "ERROR: Section name extraction" - -#generate the entry for one section -def get_toc_entry(s): - name = get_name(s) - if args.h1: - level = get_level(s)-1 - else: - level = get_level(s)-2 - anchor = get_anchor(s) - - if level<0: - return "ERROR: h1 sections are not allowed" - - res="* ["+name+"]("+anchor+")" - for i in range(0,level): - res=" "+res - return res - -#now the main -input = args.filename - -f = codecs.open(input, 'r', encoding='utf-8') - -if not f: - print("Cannot open "+input+"\n") - exit() - -#look for the begin of the file -line=f.readline() -if line.find("")==-1: - exit() - -#skip current TOC -line=f.readline() -while line and line.find("")==-1: - line=f.readline() - -if not line: - exit() - -buffer="" -TOC="\n\n# Table of Contents\n" - -verbatim_mode=False # to ignore verbatim mode while looking for sections -TOC_empty=True -for line in f.readlines(): - buffer+=line - if verbatim_mode: - if line[:3]=="```": - verbatim_mode=False - else: - if line[:3]=="```": - verbatim_mode=True + m = re.search(r"^#+\s+(.*)\s*$", s) + if m: + return m.group(1) else: - if line[0]=="#": - TOC+=(get_toc_entry(line)+"\n") - TOC_empty=False -TOC+="\n\n" + return "ERROR: Section name extraction" -if not TOC_empty: - f.close() - f = codecs.open(input, 'w', encoding='utf-8') - f.write(TOC) - f.write(buffer) + +# generate the entry for one section +def get_toc_entry(s): + name = get_name(s) + if args.h1: + level = get_level(s) - 1 + else: + level = get_level(s) - 2 + anchor = get_anchor(s) + + if level < 0: + return "ERROR: h1 sections are not allowed" + + res = "* [" + name + "](" + anchor + ")" + for _ in range(0, level): + res = " " + res + return res + + +# now the main +def main(): + filename = args.filename + + f = codecs.open(filename, "r", encoding="utf-8") + + if not f: + print("Cannot open " + input + "\n") + sys.exit() + + # look for the begin of the file + line = f.readline() + if line.find("") == -1: + sys.exit() + + # skip current TOC + line = f.readline() + while line and line.find("") == -1: + line = f.readline() + + if not line: + sys.exit() + + buffer = "" + toc = "\n" + toc += "\n\n" + toc += "\n# Table of Contents\n" + + verbatim_mode = False # to ignore verbatim mode while looking for sections + toc_empty = True + for line in f.readlines(): + buffer += line + if verbatim_mode: + if line[:3] == "```": + verbatim_mode = False + else: + if line[:3] == "```": + verbatim_mode = True + else: + if line[0] == "#" and get_level(line) <= args.max_level: + toc += get_toc_entry(line) + "\n" + toc_empty = False + toc += "\n\n" + + if not toc_empty: + f.close() + f = codecs.open(filename, "w", encoding="utf-8") + f.write(toc) + f.write(buffer) + +if __name__ == "__main__": + main() diff --git a/Scripts/developer_scripts/cgal_demo_copy_all_dlls_cygwin.sh b/Scripts/developer_scripts/cgal_demo_copy_all_dlls_cygwin.sh index 2af501d48c0..6699629f7c2 100644 --- a/Scripts/developer_scripts/cgal_demo_copy_all_dlls_cygwin.sh +++ b/Scripts/developer_scripts/cgal_demo_copy_all_dlls_cygwin.sh @@ -1,7 +1,7 @@ #!/bin/bash #use this script from inside the build directory of the Polyhedron demo -#Needs the Qt5_DIR env variable set to /lib/cmake/Qt5 +#Needs the Qt6_DIR env variable set to /lib/cmake/Qt6 #No config : in autotest_cgal we use NMake as generator #If using MSVC Generator, declare config="Release" @@ -43,4 +43,4 @@ for file in "${files[@]}"; do done; #check dependencies done #loop over directories mkdir -p "$target_directory/platforms" -cp "$Qt5_INSTALLATION_DIR/plugins/platforms/qwindows.dll" "$target_directory/platforms" +cp "$Qt6_INSTALLATION_DIR/plugins/platforms/qwindows.dll" "$target_directory/platforms" diff --git a/Shape_detection/examples/Shape_detection/region_growing_lines_on_segment_set.cpp b/Shape_detection/examples/Shape_detection/region_growing_lines_on_segment_set.cpp index c283a4652fe..270f53d3bda 100644 --- a/Shape_detection/examples/Shape_detection/region_growing_lines_on_segment_set.cpp +++ b/Shape_detection/examples/Shape_detection/region_growing_lines_on_segment_set.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include "include/utils.h" // Typedefs. diff --git a/Shape_detection/examples/Shape_detection/region_growing_planes_on_polygon_mesh.cpp b/Shape_detection/examples/Shape_detection/region_growing_planes_on_polygon_mesh.cpp index 37245edcd9d..43d7b5b291a 100644 --- a/Shape_detection/examples/Shape_detection/region_growing_planes_on_polygon_mesh.cpp +++ b/Shape_detection/examples/Shape_detection/region_growing_planes_on_polygon_mesh.cpp @@ -6,7 +6,7 @@ #endif #include #include -#include +#include #include "include/utils.h" // Typedefs. diff --git a/Shape_regularization/include/CGAL/Shape_regularization/regularize_segments.h b/Shape_regularization/include/CGAL/Shape_regularization/regularize_segments.h index 2042cff97b5..ad290801019 100644 --- a/Shape_regularization/include/CGAL/Shape_regularization/regularize_segments.h +++ b/Shape_regularization/include/CGAL/Shape_regularization/regularize_segments.h @@ -70,6 +70,9 @@ namespace Segments { that should be addressed. The function is based on the class `QP_regularization`. Please refer to that class and these concepts for more information. + This class requires a `QPSolver` model which defaults to the \ref thirdpartyOSQP "OSQP" + library, which must be available on the system. + \tparam InputRange a model of `ConstRange` whose iterator type is `RandomAccessIterator` diff --git a/Skin_surface_3/include/CGAL/Skin_surface_base_3.h b/Skin_surface_3/include/CGAL/Skin_surface_base_3.h index 6962b1ec8f2..528ea1e0e83 100644 --- a/Skin_surface_3/include/CGAL/Skin_surface_base_3.h +++ b/Skin_surface_3/include/CGAL/Skin_surface_base_3.h @@ -42,7 +42,6 @@ #include -#include #include namespace CGAL { diff --git a/Spatial_searching/doc/Spatial_searching/examples.txt b/Spatial_searching/doc/Spatial_searching/examples.txt index defc30a2079..8c3c7920ff7 100644 --- a/Spatial_searching/doc/Spatial_searching/examples.txt +++ b/Spatial_searching/doc/Spatial_searching/examples.txt @@ -11,6 +11,7 @@ \example Spatial_searching/searching_with_circular_query.cpp \example Spatial_searching/searching_surface_mesh_vertices.cpp \example Spatial_searching/searching_polyhedron_vertices.cpp +\example Spatial_searching/searching_triangulation_vertices.cpp \example Spatial_searching/searching_with_point_with_info.cpp \example Spatial_searching/searching_with_point_with_info_inplace.cpp \example Spatial_searching/searching_with_point_with_info_pmap.cpp diff --git a/Spatial_searching/examples/Spatial_searching/CMakeLists.txt b/Spatial_searching/examples/Spatial_searching/CMakeLists.txt index f9546507bd4..b273ac3477b 100644 --- a/Spatial_searching/examples/Spatial_searching/CMakeLists.txt +++ b/Spatial_searching/examples/Spatial_searching/CMakeLists.txt @@ -23,6 +23,7 @@ create_single_source_cgal_program("searching_with_point_with_info_inplace.cpp") create_single_source_cgal_program("searching_with_point_with_info_pmap.cpp") create_single_source_cgal_program("searching_surface_mesh_vertices.cpp") create_single_source_cgal_program("searching_polyhedron_vertices.cpp") +create_single_source_cgal_program("searching_triangulation_vertices.cpp") create_single_source_cgal_program("searching_polyhedron_vertices_with_fuzzy_sphere.cpp") create_single_source_cgal_program("user_defined_point_and_distance.cpp") create_single_source_cgal_program("using_fair_splitting_rule.cpp") diff --git a/Spatial_searching/examples/Spatial_searching/searching_triangulation_vertices.cpp b/Spatial_searching/examples/Spatial_searching/searching_triangulation_vertices.cpp new file mode 100644 index 00000000000..0dfd38e71e1 --- /dev/null +++ b/Spatial_searching/examples/Spatial_searching/searching_triangulation_vertices.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point_3; +typedef CGAL::Delaunay_triangulation_3 Delaunay; +typedef Delaunay::Vertex_handle Vertex_handle; + + +struct Project { + typedef Vertex_handle argument_type; + typedef const Point_3& Point; + typedef Point result_type; + Point operator()( Vertex_handle v) const { return v->point(); } +}; + + +typedef boost::function_property_map Vertex_point_pmap; +typedef CGAL::Search_traits_3 Traits_base; +typedef CGAL::Search_traits_adapter Traits; +typedef CGAL::Orthogonal_k_neighbor_search K_neighbor_search; +typedef K_neighbor_search::Tree Tree; +typedef Tree::Splitter Splitter; +typedef K_neighbor_search::Distance Distance; + +int main(int argc, char* argv[]) +{ + std::ifstream in((argc>1)?argv[1]:CGAL::data_file_path("points_3/kitten.xyz")); + std::vector points; + Point_3 p; + while(in >> p){ + points.push_back(p); + } + + Delaunay dt(points.begin(), points.end()); + + const unsigned int K = 5; + + Project project; + Vertex_point_pmap vppmap(project); + + // Insert number_of_data_points in the tree + Tree tree(dt.finite_vertex_handles().begin(), dt.finite_vertex_handles().end(), Splitter(), Traits(vppmap)); + + // search K nearest neighbors + Point_3 query(0.0, 0.0, 0.0); + Distance tr_dist(vppmap); + + K_neighbor_search search(tree, query, K,0,true,tr_dist); + std::cout <<"The "<< K << " nearest vertices to the query point at (0,0,0) are:" << std::endl; + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); it++){ + std::cout << "vertex " << &*(it->first) << " : " << vppmap[it->first] << " at distance " + << tr_dist.inverse_of_transformed_distance(it->second) << std::endl; + } + + return 0; +} diff --git a/Spatial_searching/include/CGAL/Fuzzy_iso_box.h b/Spatial_searching/include/CGAL/Fuzzy_iso_box.h index 0b34898eff9..08cc1da0063 100644 --- a/Spatial_searching/include/CGAL/Fuzzy_iso_box.h +++ b/Spatial_searching/include/CGAL/Fuzzy_iso_box.h @@ -22,8 +22,6 @@ #include #include -#include - #include diff --git a/Spatial_searching/include/CGAL/Search_traits_adapter.h b/Spatial_searching/include/CGAL/Search_traits_adapter.h index ff640dc639a..7a518cf68ee 100644 --- a/Spatial_searching/include/CGAL/Search_traits_adapter.h +++ b/Spatial_searching/include/CGAL/Search_traits_adapter.h @@ -224,16 +224,16 @@ public: // Select type of iterator + construct class depending on whether // point map is lvalue or not - typedef typename boost::mpl::if_< - std::is_reference::reference>, + typedef std::conditional_t< + std::is_reference_v::reference>, typename Base::Cartesian_const_iterator_d, - No_lvalue_iterator>::type + No_lvalue_iterator> Cartesian_const_iterator_d; - typedef typename boost::mpl::if_< - std::is_reference::reference>, + typedef std::conditional_t< + std::is_reference_v::reference>, Construct_cartesian_const_iterator_d_lvalue, - Construct_cartesian_const_iterator_d_no_lvalue>::type + Construct_cartesian_const_iterator_d_no_lvalue> Construct_cartesian_const_iterator_d; struct Construct_iso_box_d: public Base::Construct_iso_box_d{ diff --git a/Straight_skeleton_2/examples/Straight_skeleton_2/extrude_skeleton.cpp b/Straight_skeleton_2/examples/Straight_skeleton_2/extrude_skeleton.cpp index a50f2efc4da..cc73aa7493b 100644 --- a/Straight_skeleton_2/examples/Straight_skeleton_2/extrude_skeleton.cpp +++ b/Straight_skeleton_2/examples/Straight_skeleton_2/extrude_skeleton.cpp @@ -9,7 +9,7 @@ #include "CGAL/input_helpers.h" // polygon reading, random polygon with weights generation #include -#include +#include #include #include #include diff --git a/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_aux.h b/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_aux.h index a799eccda60..30b1e25de59 100644 --- a/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_aux.h +++ b/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_aux.h @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -36,12 +35,10 @@ struct Has_inexact_constructions { typedef typename K::FT FT ; - typedef typename boost::mpl::if_< boost::mpl::or_< std::is_same - , std::is_same - > - , Tag_true - , Tag_false - >::type type ; + typedef std::conditional_t< std::is_same_v || std::is_same_v + , Tag_true + , Tag_false + > type ; } ; template diff --git a/Straight_skeleton_extrusion_2/test/Straight_skeleton_extrusion_2/test_sls_extrude.cpp b/Straight_skeleton_extrusion_2/test/Straight_skeleton_extrusion_2/test_sls_extrude.cpp index eaa971ce880..d6f68604517 100644 --- a/Straight_skeleton_extrusion_2/test/Straight_skeleton_extrusion_2/test_sls_extrude.cpp +++ b/Straight_skeleton_extrusion_2/test/Straight_skeleton_extrusion_2/test_sls_extrude.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include namespace PMP = ::CGAL::Polygon_mesh_processing; diff --git a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt index c37ee06bf59..5badcf76a9c 100644 --- a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt +++ b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt @@ -43,57 +43,57 @@ The following table lists some \cgal data structures that have I/O functions com Input Polygon Mesh `CGAL::Surface_mesh` - \link PkgSurfaceMeshIOFuncOFF CGAL::IO::read_OFF(const char*, CGAL::Surface_mesh&)\endlink + \link PkgSurfaceMeshIOFuncOFF CGAL::IO::read_OFF(const std::string&, CGAL::Surface_mesh&)\endlink `CGAL::Polyhedron_3` - \link PkgPolyhedronIOFunc CGAL::IO::read_OFF(const char*, CGAL::Polyhedron_3&)\endlink + \link PkgPolyhedronIOFunc CGAL::IO::read_OFF(const std::string&, CGAL::Polyhedron_3&)\endlink Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsOFF CGAL::IO::read_OFF(const char*, Graph&)\endlink + \link PkgBGLIoFuncsOFF CGAL::IO::read_OFF(const std::string&, Graph&)\endlink Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOOFF CGAL::IO::read_OFF(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOOFF CGAL::IO::read_OFF(const std::string&, CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOOff CGAL::IO::read_OFF(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOOff CGAL::IO::read_OFF(const std::string&, PointOutputIterator)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsOFF CGAL::IO::read_OFF(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsOFF CGAL::IO::read_OFF(const std::string&, PointRange&, PolygonRange&)\endlink Output Polygon Mesh `CGAL::Surface_mesh` - \link PkgSurfaceMeshIOFuncOFF CGAL::IO::write_OFF(const char*, CGAL::Surface_mesh&)\endlink + \link PkgSurfaceMeshIOFuncOFF CGAL::IO::write_OFF(const std::string, CGAL::Surface_mesh&)\endlink `CGAL::Polyhedron_3` - \link PkgPolyhedronIOFunc CGAL::IO::write_OFF(const char*, CGAL::Polyhedron_3&)\endlink + \link PkgPolyhedronIOFunc CGAL::IO::write_OFF(const std::string&, const CGAL::Polyhedron_3&)\endlink Any model of `FaceGraph` - \link PkgBGLIoFuncsOFF CGAL::IO::write_OFF(const char*, Graph&)\endlink + \link PkgBGLIoFuncsOFF CGAL::IO::write_OFF(const std::string&, const Graph&)\endlink Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOOFF CGAL::IO::write_OFF(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOOFF CGAL::IO::write_OFF(const std::string&, const CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOOff CGAL::IO::write_OFF(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOOff CGAL::IO::write_OFF(const std::string&, const PointRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsOFF CGAL::IO::write_OFF(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsOFF CGAL::IO::write_OFF(const std::string&, const PointRange&, const PolygonRange&)\endlink @@ -117,23 +117,23 @@ A precise specification of the format is available Input Polygon Mesh Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsOBJ CGAL::IO::read_OBJ(const char*, Graph&)\endlink + \link PkgBGLIoFuncsOBJ CGAL::IO::read_OBJ(const std::string&, Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsOBJ CGAL::IO::read_OBJ(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsOBJ CGAL::IO::read_OBJ(const std::string&, PointRange&, PolygonRange&)\endlink Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsOBJ CGAL::IO::write_OBJ(const char*, Graph&)\endlink + \link PkgBGLIoFuncsOBJ CGAL::IO::write_OBJ(const std::string&, const Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsOBJ CGAL::IO::write_OBJ(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsOBJ CGAL::IO::write_OBJ(const std::string&, const PointRange&, const PolygonRange&)\endlink @@ -158,23 +158,23 @@ A precise specification of those formats is available Input Polygon Mesh Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsSTL CGAL::IO::read_STL(const char*, Graph&)\endlink + \link PkgBGLIoFuncsSTL CGAL::IO::read_STL(const std::string&, Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsSTL CGAL::IO::read_STL(const char*, PointRange&, TriangleRange&)\endlink + \link PkgStreamSupportIoFuncsSTL CGAL::IO::read_STL(const std::string&, PointRange&, TriangleRange&)\endlink Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsSTL CGAL::IO::write_STL(const char*, Graph&)\endlink + \link PkgBGLIoFuncsSTL CGAL::IO::write_STL(const std::string&, const Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsSTL CGAL::IO::write_STL(const char*, PointRange&, TriangleRange&)\endlink + \link PkgStreamSupportIoFuncsSTL CGAL::IO::write_STL(const std::string&, const PointRange&, const TriangleRange&)\endlink @@ -202,49 +202,49 @@ A precise specification of those formats is available Input Polygon Mesh `CGAL::Surface_mesh` - \link PkgSurfaceMeshIOFuncPLY CGAL::IO::read_PLY(const char*, CGAL::Surface_mesh&)\endlink + \link PkgSurfaceMeshIOFuncPLY CGAL::IO::read_PLY(const std::string&, CGAL::Surface_mesh&)\endlink Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsPLY CGAL::IO::read_PLY(const char*, Graph&)\endlink + \link PkgBGLIoFuncsPLY CGAL::IO::read_PLY(const std::string&, Graph&)\endlink Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOPLY CGAL::IO::read_PLY(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOPLY CGAL::IO::read_PLY(const std::string&, CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOPly CGAL::IO::read_PLY(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOPly CGAL::IO::read_PLY(const std::string&, PointRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsPLY CGAL::IO::read_PLY(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsPLY CGAL::IO::read_PLY(const std::string&, PointRange&, PolygonRange&)\endlink Output Polygon Mesh `CGAL::Surface_mesh` - \link PkgSurfaceMeshIOFuncPLY CGAL::IO::write_PLY(const char*, CGAL::Surface_mesh&)\endlink + \link PkgSurfaceMeshIOFuncPLY CGAL::IO::write_PLY(const std::string&, const CGAL::Surface_mesh&)\endlink Any model of `FaceGraph` - \link PkgBGLIoFuncsPLY CGAL::IO::write_PLY(const char*, Graph&)\endlink + \link PkgBGLIoFuncsPLY CGAL::IO::write_PLY(const std::string&, const Graph&)\endlink Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOPLY CGAL::IO::write_PLY(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOPLY CGAL::IO::write_PLY(const std::string&, const CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOPly CGAL::IO::write_PLY(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOPly CGAL::IO::write_PLY(const std::string&, const PointRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsPLY CGAL::IO::write_PLY(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsPLY CGAL::IO::write_PLY(const std::string&, const PointRange&, PolygonRange&)\endlink @@ -270,21 +270,21 @@ A precise specification of those formats is available Input Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOLAS CGAL::IO::read_LAS(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOLAS CGAL::IO::read_LAS(const std::string&, CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOLas CGAL::IO::read_LAS(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOLas CGAL::IO::read_LAS(const std::string&, PointRange&)\endlink Output Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOLAS CGAL::IO::write_LAS(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOLAS CGAL::IO::write_LAS(const std::string&, const CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOLas CGAL::IO::write_LAS(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOLas CGAL::IO::write_LAS(const std::string&, const PointRange&)\endlink @@ -303,21 +303,21 @@ of its coordinates and other properties. Only coordinates and normals are curren Input Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOXYZ CGAL::IO::read_XYZ(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOXYZ CGAL::IO::read_XYZ(const std::string&, CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOXyz CGAL::IO::read_XYZ(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOXyz CGAL::IO::read_XYZ(const std::string&, PointRange&)\endlink Output Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOXYZ CGAL::IO::write_XYZ(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOXYZ CGAL::IO::write_XYZ(const std::string&, const CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOXyz CGAL::IO::write_XYZ(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOXyz CGAL::IO::write_XYZ(const std::string&, const PointRange&)\endlink @@ -337,23 +337,23 @@ A precise specification of the format is available Input Polygon Mesh Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsGOCAD CGAL::IO::read_GOCAD(const char*, Graph&)\endlink + \link PkgBGLIoFuncsGOCAD CGAL::IO::read_GOCAD(const std::string&, Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsGOCAD CGAL::IO::read_GOCAD(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsGOCAD CGAL::IO::read_GOCAD(const std::string&, PointRange&, PolygonRange&)\endlink Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsGOCAD CGAL::IO::write_GOCAD(const char*, Graph&)\endlink + \link PkgBGLIoFuncsGOCAD CGAL::IO::write_GOCAD(const std::string&, const Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsGOCAD CGAL::IO::write_GOCAD(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsGOCAD CGAL::IO::write_GOCAD(const std::string&, const PointRange&, const PolygonRange&)\endlink @@ -381,23 +381,23 @@ note that only versions `1.x` are currently supported in \cgal. Input Polygon Mesh `CGAL::Surface_mesh` - \link PkgSurfaceMeshIOFunc3MF CGAL::IO::read_3MF(const char*, Surface_meshRange&)\endlink + \link PkgSurfaceMeshIOFunc3MF CGAL::IO::read_3MF(const std::string&, Surface_meshRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncs3MF CGAL::IO::read_3MF(const char*, PointRanges&, PolygonRanges&)\endlink + \link PkgStreamSupportIoFuncs3MF CGAL::IO::read_3MF(const std::string&, PointRanges&, PolygonRanges&)\endlink Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncs3MF CGAL::IO::write_3MF(const char*, GraphRange&)\endlink + \link PkgBGLIoFuncs3MF CGAL::IO::write_3MF(const std::string&, const GraphRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncs3MF CGAL::IO::write_3MF(const char*, PointRanges&, PolygonRanges&)\endlink + \link PkgStreamSupportIoFuncs3MF CGAL::IO::write_3MF(const std::string&, const PointRanges&, const PolygonRanges&)\endlink @@ -416,17 +416,17 @@ A precise specification of the format is available - 3D Manufacturing Format (3MF) + 3D VRML Format (WRL) Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsWRL CGAL::IO::write_WRL(const char*, Graph&)\endlink + \link PkgBGLIoFuncsWRL CGAL::IO::write_WRL(const std::string&, const Graph&)\endlink -\section IOStreamVTK VTK (VTU / VTP) File Formats +\section IOStreamVTK VTK (VTU / VTP / legacy) File Formats \attention \cgal needs to be configured with the VTK Libraries for this function to be available. @@ -440,36 +440,38 @@ The VTK libraries use different file formats to handle data structures, but we o - The `VTP` format can be used to store collections of points, lines, and triangles. In the VTK Libraries, it is the format - reserved to store `PolyData`, and in \cgal, we use it to store Polygon Meshes. + reserved to store `PolyData`, and in \cgal, we use it to store polygon meshes. + +We additionally provide a read function for the legacy non-XML `VTK` file format for polygon meshes. A precise specification of those formats is available at vtk.org. - + - + - + - + - +
VTK (VTU / VTP) File FormatsVTK (VTU / VTP / legacy) File Formats
Input Polygon Mesh Any model of `MutableFaceGraph`\link PkgBGLIoFuncsVTP CGAL::IO::read_VTP(const char*, Graph&)\endlink\link PkgBGLIoFuncsVTP CGAL::IO::read_VTP(const std::string&, Graph&)\endlink
Polygon Soup Any point + polygon range\link PkgStreamSupportIoFuncsVTP CGAL::IO::read_VTP(const char*, PointRange&, PolygonRange&)\endlink\link PkgStreamSupportIoFuncsVTK CGAL::IO::read_VTP(const std::string&, PointRange&, PolygonRange&)\endlink,
\link PkgStreamSupportIoFuncsVTK CGAL::IO::read_VTK(const std::string&, PointRange&, PolygonRange&)\endlink
Output Polygon Mesh Any model of `FaceGraph`\link PkgBGLIoFuncsVTP CGAL::IO::write_VTP(const char*, Graph&)\endlink\link PkgBGLIoFuncsVTP CGAL::IO::write_VTP(const std::string&, const Graph&)\endlink
Polygon Soup Any point + polygon range\link PkgStreamSupportIoFuncsVTP CGAL::IO::write_VTP(const char*, PointRange&, PolygonRange&)\endlink\link PkgStreamSupportIoFuncsVTK CGAL::IO::write_VTP(const std::string&, const PointRange&, const PolygonRange&)\endlink
diff --git a/Stream_support/doc/Stream_support/IOstream.txt b/Stream_support/doc/Stream_support/IOstream.txt index be0f7ee02a9..fb4d9fe8afa 100644 --- a/Stream_support/doc/Stream_support/IOstream.txt +++ b/Stream_support/doc/Stream_support/IOstream.txt @@ -305,18 +305,18 @@ The following table shows which file formats can be read from and written for po Input `read_points()` - \link PkgPointSetProcessing3IOOff `read_OFF()` \endlink - \link PkgPointSetProcessing3IOXyz `read_XYZ()` \endlink - \link PkgPointSetProcessing3IOPly `read_PLY()` \endlink - \link PkgPointSetProcessing3IOLas `read_LAS()` \endlink + \link PkgPointSetProcessing3IOOff `CGAL::IO::read_OFF()` \endlink + \link PkgPointSetProcessing3IOXyz `GAL::IO::read_XYZ()` \endlink + \link PkgPointSetProcessing3IOPly `GAL::IO::read_PLY()` \endlink + \link PkgPointSetProcessing3IOLas `GAL::IO::read_LAS()` \endlink Output `write_points()` - \link PkgPointSetProcessing3IOOff `write_OFF()` \endlink - \link PkgPointSetProcessing3IOXyz `write_XYZ()` \endlink - \link PkgPointSetProcessing3IOPly `write_PLY()` \endlink - \link PkgPointSetProcessing3IOLas `write_LAS()` \endlink + \link PkgPointSetProcessing3IOOff `GAL::IO::write_OFF()` \endlink + \link PkgPointSetProcessing3IOXyz `GAL::IO::write_XYZ()` \endlink + \link PkgPointSetProcessing3IOPly `GAL::IO::write_PLY()` \endlink + \link PkgPointSetProcessing3IOLas `GAL::IO::write_LAS()` \endlink @@ -345,19 +345,19 @@ The file formats supported for `CGAL::Point_set_3` are detailed in the table bel Input - `read_point_set()` - \link PkgPointSet3IOOFF `read_OFF()` \endlink - \link PkgPointSet3IOXYZ `read_XYZ()` \endlink - \link PkgPointSet3IOPLY `read_PLY()` \endlink - \link PkgPointSet3IOLAS `read_LAS()` \endlink + `CGAL::IO::read_point_set()` + \link PkgPointSet3IOOFF `GAL::IO::read_OFF()` \endlink + \link PkgPointSet3IOXYZ `GAL::IO::read_XYZ()` \endlink + \link PkgPointSet3IOPLY `GAL::IO::read_PLY()` \endlink + \link PkgPointSet3IOLAS `GAL::IO::read_LAS()` \endlink Output - `write_point_set()` - \link PkgPointSet3IOOFF `write_OFF()` \endlink - \link PkgPointSet3IOXYZ `write_XYZ()` \endlink - \link PkgPointSet3IOPLY `write_PLY()` \endlink - \link PkgPointSet3IOLAS `write_LAS()` \endlink + `CGAL::IO::write_point_set()` + \link PkgPointSet3IOOFF `GAL::IO::write_OFF()` \endlink + \link PkgPointSet3IOXYZ `GAL::IO::write_XYZ()` \endlink + \link PkgPointSet3IOPLY `GAL::IO::write_PLY()` \endlink + \link PkgPointSet3IOLAS `GAL::IO::write_LAS()` \endlink @@ -381,27 +381,27 @@ their indices per face (i.e a vector of 3 integers represent a triangle face). Input - `read_polygon_soup()` - \link PkgStreamSupportIoFuncsOFF `read_OFF()` \endlink - \link PkgStreamSupportIoFuncsOBJ `read_OBJ()` \endlink - \link PkgStreamSupportIoFuncsSTL `read_STL()` \endlink - \link PkgStreamSupportIoFuncsPLY `read_PLY()` \endlink - \link PkgStreamSupportIoFuncsVTP `read_VTP()` \endlink - \link PkgStreamSupportIoFuncsGOCAD `read_GOCAD()` \endlink - \link PkgStreamSupportIoFuncsWKT `read_WKT()` \endlink - \link PkgStreamSupportIoFuncs3MF `read_3MF()` \endlink + `CGAL::IO::read_polygon_soup()` + \link PkgStreamSupportIoFuncsOFF `GAL::IO::read_OFF()` \endlink + \link PkgStreamSupportIoFuncsOBJ `GAL::IO::read_OBJ()` \endlink + \link PkgStreamSupportIoFuncsSTL `GAL::IO::read_STL()` \endlink + \link PkgStreamSupportIoFuncsPLY `GAL::IO::read_PLY()` \endlink + \link PkgStreamSupportIoFuncsVTK `GAL::IO::read_VTP()` \endlink + \link PkgStreamSupportIoFuncsGOCAD `GAL::IO::read_GOCAD()` \endlink + \link PkgStreamSupportIoFuncsWKT `GAL::IO::read_WKT()` \endlink + \link PkgStreamSupportIoFuncs3MF `GAL::IO::read_3MF()` \endlink Output - `write_polygon_soup()` - \link PkgStreamSupportIoFuncsOFF `write_OFF()` \endlink - \link PkgStreamSupportIoFuncsOBJ `write_OBJ()` \endlink - \link PkgStreamSupportIoFuncsSTL `write_STL()` \endlink - \link PkgStreamSupportIoFuncsPLY `write_PLY()` \endlink - \link PkgStreamSupportIoFuncsVTP `write_VTP()` \endlink - \link PkgStreamSupportIoFuncsGOCAD `write_GOCAD()` \endlink - \link PkgStreamSupportIoFuncsWKT `write_WKT()` \endlink - \link PkgStreamSupportIoFuncs3MF `write_3MF()` \endlink + `CGAL::IO::write_polygon_soup()` + \link PkgStreamSupportIoFuncsOFF `GAL::IO::write_OFF()` \endlink + \link PkgStreamSupportIoFuncsOBJ `GAL::IO::write_OBJ()` \endlink + \link PkgStreamSupportIoFuncsSTL `GAL::IO::write_STL()` \endlink + \link PkgStreamSupportIoFuncsPLY `GAL::IO::write_PLY()` \endlink + \link PkgStreamSupportIoFuncsVTK `GAL::IO::write_VTP()` \endlink + \link PkgStreamSupportIoFuncsGOCAD `GAL::IO::write_GOCAD()` \endlink + \link PkgStreamSupportIoFuncsWKT `GAL::IO::write_WKT()` \endlink + \link PkgStreamSupportIoFuncs3MF `GAL::IO::write_3MF()` \endlink @@ -424,23 +424,23 @@ The table above only lists the functions that work with any polygon mesh. Input - `read_polygon_mesh()` - `read_OFF()` - `read_STL()` - `read_VTP()` - `read_OBJ()` - `read_GOCAD()` + `CGAL::IO::read_polygon_mesh()` + `CGAL::IO::read_OFF()` + `CGAL::IO::read_STL()` + `CGAL::IO::read_VTP()` + `CGAL::IO::read_OBJ()` + `CGAL::IO::read_GOCAD()`
-
Output - `write_polygon_mesh()` - `write_OFF()` - `write_STL()` - `write_VTP()` - `write_OBJ()` - `write_GOCAD()` - `write_WRL()` + ``CGAL::IO::write_polygon_mesh()` + `CGAL::IO::write_OFF()` + `CGAL::IO::write_STL()` + `CGAL::IO::write_VTP()` + `CGAL::IO::write_OBJ()` + `CGAL::IO::write_GOCAD()` + `CGAL::IO::write_WRL()` @@ -478,17 +478,17 @@ from the standard \cgal I/O functions. Input -read_WKT() -read_multi_point_WKT() -read_multi_linestring_WKT() -read_multi_polygon_WKT() +`CGAL::IO::read_WKT()` +`CGAL::IO::read_multi_point_WKT()` +`CGAL::IO::read_multi_linestring_WKT()` +`CGAL::IO::read_multi_polygon_WKT()` Output
-
-write_multi_point_WKT() -write_multi_linestring_WKT() -write_multi_polygon_WKT() +`CGAL::IO::write_multi_point_WKT()` +`CGAL::IO::write_multi_linestring_WKT()` +`CGAL::IO::write_multi_polygon_WKT()` diff --git a/Stream_support/doc/Stream_support/PackageDescription.txt b/Stream_support/doc/Stream_support/PackageDescription.txt index 9d993ee4779..0cacc80c631 100644 --- a/Stream_support/doc/Stream_support/PackageDescription.txt +++ b/Stream_support/doc/Stream_support/PackageDescription.txt @@ -20,7 +20,7 @@ /// I/O Functions for the \ref IOStreamOFF /// \ingroup IOstreamFunctions -/// \defgroup PkgStreamSupportIoFuncsVTP VTP I/O Functions +/// \defgroup PkgStreamSupportIoFuncsVTK VTK I/O Functions /// I/O Functions for the \ref IOStreamVTK /// \ingroup IOstreamFunctions @@ -96,9 +96,8 @@ the printing mode. - \link PkgStreamSupportIoFuncsOBJ I/O for OBJ files \endlink - \link PkgStreamSupportIoFuncsOFF I/O for OFF files \endlink - \link PkgStreamSupportIoFuncsGOCAD I/O for GOCAD files \endlink -- \link PkgStreamSupportIoFuncsVTP I/O for VTP files \endlink +- \link PkgStreamSupportIoFuncsVTK I/O for VTK files \endlink - \link PkgStreamSupportIoFuncs3MF I/O for 3MF files \endlink - \link PkgStreamSupportIoFuncsWKT I/O for WKT files \endlink */ - diff --git a/Stream_support/include/CGAL/IO/VTK.h b/Stream_support/include/CGAL/IO/VTK.h index 585cc9d9685..fd8f7accc45 100644 --- a/Stream_support/include/CGAL/IO/VTK.h +++ b/Stream_support/include/CGAL/IO/VTK.h @@ -26,8 +26,10 @@ #include #include #include +#include #include #include +#include #endif #if defined(CGAL_USE_VTK) || defined(DOXYGEN_RUNNING) @@ -114,14 +116,14 @@ bool read_VTP(const std::string& fname, } /*! - * \ingroup PkgStreamSupportIoFuncsVTP + * \ingroup PkgStreamSupportIoFuncsVTK * * \brief reads the content of the input file into `points` and `polygons`, using the \ref IOStreamVTK. * * \attention The polygon soup is not cleared, and the data from the file are appended. * * \tparam PointRange a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` - * whose value type is the point type + * whose `value_type` is the point type * \tparam PolygonRange a model of the concepts `SequenceContainer` and `BackInsertionSequence` * whose `value_type` is itself a model of the concept `SequenceContainer` * and `BackInsertionSequence` whose `value_type` is an unsigned integer type @@ -140,6 +142,62 @@ bool read_VTP(const std::string& fname, PointRange& points, PolygonRange& polygo return read_VTP(fname, points, polygons, parameters::default_values()); } + +template +bool read_VTK(const std::string& fname, + PointRange& points, + PolygonRange& polygons, + const NamedParameters& np) +{ + std::ifstream test(fname); + if(!test.good()) + { + std::cerr<<"File doesn't exist."< data; + vtkSmartPointer obs = + vtkSmartPointer::New(); + vtkSmartPointer reader = + CGAL::IO::internal::read_vtk_file(fname,obs); + data = vtkPolyData::SafeDownCast(reader->GetOutput()); + if (!data) + data = vtkUnstructuredGrid::SafeDownCast(reader->GetOutput()); + + if (obs->GetError()) + return false; + + return internal::vtkPointSet_to_polygon_soup(data, points, polygons, np); +} + +/*! + * \ingroup PkgStreamSupportIoFuncsVTK + * + * \brief reads the content of the input file into `points` and `polygons`, using the legacy file format of the \ref IOStreamVTK. + * + * \attention The polygon soup is not cleared, and the data from the file are appended. + * + * \tparam PointRange a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` + * whose `value_type` is the point type + * \tparam PolygonRange a model of the concepts `SequenceContainer` and `BackInsertionSequence` + * whose `value_type` is itself a model of the concept `SequenceContainer` + * and `BackInsertionSequence` whose `value_type` is an unsigned integer type + * convertible to `std::size_t` + * + * \param fname the path to the input file + * \param points points of the soup of polygons + * \param polygons a range of polygons. Each element in it describes a polygon + * using the indices of the points in `points`. + * + * \returns `true` if the reading was successful, `false` otherwise. + */ +template +bool read_VTK(const std::string& fname, PointRange& points, PolygonRange& polygons) +{ + return read_VTK(fname, points, polygons, parameters::default_values()); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // Write @@ -340,11 +398,11 @@ void write_soup_polys_points(std::ostream& os, } // namespace internal /*! - * \ingroup PkgStreamSupportIoFuncsVTP + * \ingroup PkgStreamSupportIoFuncsVTK * * \brief writes the content of `points` and `polygons` in `out`, using the \ref IOStreamVTK. * - * \tparam PointRange a model of the concept `RandomAccessContainer` whose value type is the point type + * \tparam PointRange a model of the concept `RandomAccessContainer` whose `value_type` is the point type * \tparam PolygonRange a model of the concept `SequenceContainer` * whose `value_type` is itself a model of the concept `SequenceContainer` * whose `value_type` is an unsigned integer type convertible to `std::size_t` @@ -428,11 +486,11 @@ bool write_VTP(std::ostream& os, } /*! - * \ingroup PkgStreamSupportIoFuncsVTP + * \ingroup PkgStreamSupportIoFuncsVTK * * \brief writes the content of `points` and `polygons` in a file named `fname`, using the \ref IOStreamVTK. * - * \tparam PointRange a model of the concept `RandomAccessContainer` whose value type is the point type + * \tparam PointRange a model of the concept `RandomAccessContainer` whose `valuetype` is the point type * \tparam PolygonRange a model of the concept `SequenceContainer` * whose `value_type` is itself a model of the concept `SequenceContainer` * whose `value_type` is an unsigned integer type convertible to `std::size_t` diff --git a/Stream_support/include/CGAL/IO/helpers.h b/Stream_support/include/CGAL/IO/helpers.h index bba12aa85a7..7382ebabd66 100644 --- a/Stream_support/include/CGAL/IO/helpers.h +++ b/Stream_support/include/CGAL/IO/helpers.h @@ -77,10 +77,10 @@ struct is_Point_set_3 : has_Point_set { }; // Point_set_3 and strings also functions as ranges, but we want to match polygon soups here template struct is_Range - : public boost::mpl::and_< - boost::has_range_const_iterator, // should be a range - boost::mpl::not_ >, // but not a Point_set_3 - boost::mpl::not_ > > // or a std::string / char [x] + : public std::bool_constant< + boost::has_range_const_iterator::value && // should be a range + !is_Point_set_3::value && // but not a Point_set_3 + !std::is_convertible_v > // or a std::string / char [x] { }; template @@ -89,7 +89,7 @@ inline constexpr bool is_Range_v = is_Range::value; // For polygon meshes template struct is_Point_set_or_Range_or_Iterator - : public boost::mpl::or_, is_Range, is_iterator > + : public std::bool_constant::value || is_Range::value || is_iterator::value > { }; template diff --git a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Surface_mesh_segmentation.h b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Surface_mesh_segmentation.h index d0a77fa1a78..a2a2228f6f5 100644 --- a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Surface_mesh_segmentation.h +++ b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Surface_mesh_segmentation.h @@ -324,8 +324,8 @@ private: CGAL_precondition( (! (face(edge,mesh)==boost::graph_traits::null_face())) && (! (face(opposite(edge,mesh),mesh)==boost::graph_traits::null_face())) ); - const Point a = get(vertex_point_pmap,target(edge,mesh)); - const Point b = get(vertex_point_pmap,target(prev(edge,mesh),mesh)); + const Point a = get(vertex_point_pmap,source(edge,mesh)); + const Point b = get(vertex_point_pmap,target(edge,mesh)); const Point c = get(vertex_point_pmap,target(next(edge,mesh),mesh)); const Point d = get(vertex_point_pmap,target(next(opposite(edge,mesh),mesh),mesh)); // As far as I check: if, say, dihedral angle is 5, this returns 175, diff --git a/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_garland_heckbert.cpp b/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_garland_heckbert.cpp index 365fc39d267..7d2f9500b5d 100644 --- a/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_garland_heckbert.cpp +++ b/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_garland_heckbert.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include diff --git a/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_linear_cell_complex.cpp b/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_linear_cell_complex.cpp index 4bedf34619a..19105b1833b 100644 --- a/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_linear_cell_complex.cpp +++ b/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_linear_cell_complex.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_stability.cpp b/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_stability.cpp index 1a6a2786c6d..6566b233e61 100644 --- a/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_stability.cpp +++ b/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_stability.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include //bbox #include diff --git a/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_deprecated_stop_predicates.cpp b/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_deprecated_stop_predicates.cpp index 238a796eb03..5a898efb4df 100644 --- a/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_deprecated_stop_predicates.cpp +++ b/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_deprecated_stop_predicates.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/MCF_Skeleton_LCC_example.cpp b/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/MCF_Skeleton_LCC_example.cpp index bc2455499ad..dd62887970c 100644 --- a/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/MCF_Skeleton_LCC_example.cpp +++ b/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/MCF_Skeleton_LCC_example.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/simple_mcfskel_LCC_example.cpp b/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/simple_mcfskel_LCC_example.cpp index 522ce16fb44..83f07c3d25d 100644 --- a/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/simple_mcfskel_LCC_example.cpp +++ b/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/simple_mcfskel_LCC_example.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_subcurve.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_subcurve.h index 2e15d64e7b7..da52494018e 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_subcurve.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_subcurve.h @@ -104,6 +104,17 @@ protected: public: + + void reset_left_event() + { + this->set_left_event(static_cast(nullptr)); + if (m_orig_subcurve1) + { + m_orig_subcurve1->reset_left_event(); + m_orig_subcurve2->reset_left_event(); + } + } + /*! Get the subcurves that originate an overlap. */ Subcurve* originating_subcurve1() { return m_orig_subcurve1; } diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h index acc94c13abc..eafd4d73b89 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h @@ -298,6 +298,14 @@ void Surface_sweep_2::_handle_overlaps_in_right_curves() template void Surface_sweep_2::_handle_right_curves() { + + for(Event_subcurve_iterator sc_it = this->m_currentEvent->right_curves_begin(), + sc_it_end = this->m_currentEvent->right_curves_end(); + sc_it!=sc_it_end; ++sc_it) + { + (*sc_it)->reset_left_event(); + } + CGAL_SS_PRINT_START("handling right curves at ("); CGAL_SS_DEBUG(this->PrintEvent(this->m_currentEvent)); CGAL_SS_PRINT_TEXT(")"); @@ -565,10 +573,12 @@ void Surface_sweep_2::_intersect(Subcurve* c1, Subcurve* c2, Event* left_event = first_parent->left_event(); Event* right_event = first_parent->right_event(); - if (! second_parent->is_start_point(left_event)) - left_event->add_curve_to_left(second_parent); - else - left_event->remove_curve_from_right(second_parent); + if (left_event != nullptr) { + if (! second_parent->is_start_point(left_event)) + left_event->add_curve_to_left(second_parent); + else + left_event->remove_curve_from_right(second_parent); + } CGAL_SS_PRINT_CURVE(c1); CGAL_SS_PRINT_TEXT(" + "); @@ -588,7 +598,8 @@ void Surface_sweep_2::_intersect(Subcurve* c1, Subcurve* c2, // add the overlapping curve kept of the right of the left end right_event->add_curve_to_left(first_parent); - _add_curve_to_right(left_event, first_parent); + if (left_event != nullptr) + _add_curve_to_right(left_event, first_parent); this->m_visitor->found_overlap(c1, c2, first_parent); diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2_algorithms.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2_algorithms.h index 62d6d31aaec..c684948f8e3 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2_algorithms.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2_algorithms.h @@ -33,6 +33,7 @@ #include #include #include +#include namespace CGAL { @@ -54,11 +55,13 @@ struct Default_arr_traits > typedef CGAL::Arr_segment_traits_2 Traits; }; -template -struct Default_arr_traits > +template +struct Default_arr_traits, + typename Kernel::Point_2>> { - typedef CGAL::Arr_polyline_traits_2 Traits; + using Subtraits = CGAL::Arr_segment_traits_2; + typedef CGAL::Arr_polyline_traits_2 Traits; }; template diff --git a/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt b/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt index 2c9363b2d68..a6de52b8c0d 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt @@ -7,9 +7,9 @@ project(Surface_sweep_2_Tests) find_package(CGAL REQUIRED COMPONENTS Core) set(CGAL_SEGMENT_TRAITS 1) -set(CGAL_SEGMENT_LEDA_TRAITS 2) set(CGAL_POLYLINE_TRAITS 11) set(CGAL_CONIC_TRAITS 21) +set(CGAL_POLYCONIC_TRAITS 22) set(TRAP 1) # Trapezoidal decomposition set(NAIVE 2) @@ -38,16 +38,18 @@ function(compile_and_run_sweep name source_file point_location traits data_set) file( GLOB files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - "${CMAKE_CURRENT_SOURCE_DIR}/${data_set}/*") + "${CMAKE_CURRENT_SOURCE_DIR}/${data_set}/*.txt") foreach(file ${files}) - # message("test ${source_file} ${file}") + # message("test ${source_file} ${file}") string(MAKE_C_IDENTIFIER "${name} ${file}" test_name) - # message(" --> ${test_name}") + # message(" --> ${test_name}") cgal_add_test(${name} TEST_NAME ${test_name} ARGUMENTS ${file}) endforeach() endfunction() -compile_and_run_sweep(test_sweep test_sweep.cpp ${NAIVE} ${CGAL_SEGMENT_TRAITS} - "DATA/segments_tight") -compile_and_run_sweep(test_sweep_conic test_sweep_conic.cpp ${NAIVE} - ${CGAL_CONIC_TRAITS} "DATA/conics") +compile_and_run_sweep(test_sweep test_sweep.cpp ${NAIVE} + ${CGAL_SEGMENT_TRAITS} "data/segments_tight") +compile_and_run_sweep(test_sweep_conic test_sweep.cpp ${NAIVE} + ${CGAL_CONIC_TRAITS} "data/conics") +compile_and_run_sweep(test_sweep_polyline test_sweep.cpp ${NAIVE} + ${CGAL_POLYLINE_TRAITS} "data/polylines") diff --git a/Surface_sweep_2/test/Surface_sweep_2/CompareCurveList.h b/Surface_sweep_2/test/Surface_sweep_2/CompareCurveList.h deleted file mode 100644 index ff43d9b73a4..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/CompareCurveList.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _COMPARE_CURVE_LIST_H -#define _COMPARE_CURVE_LIST_H - -#include -#include - - -template -class Equal_pred -{ -public: - typedef typename Traits::Point_2 Point_2; - typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; - - bool operator()(const Point_2& p1, const Point_2& p2) - { - return(Traits().equal_2_object()(p1, p2)); - } - - bool operator()(const X_monotone_curve_2& c1, const X_monotone_curve_2& c2) - { - return(Traits().equal_2_object()(c1, c2)); - } -}; - - -template - bool compare_lists(const List& list1, const List& list2, Traits& /*tr*/) -{ - typedef typename List::const_iterator Iter; - Iter begin1 = list1.begin(); - Iter end1 = list1.end(); - - Iter begin2 = list2.begin(); - - if(! (list1.size() == list2.size())) - { - std::cout << "The lists are not of the same lengths (" - << list1.size() << "," << list2.size() << ")\n"; - return false; - } - - Equal_pred eq; - return std::equal(begin1, end1, begin2, eq); -} - - -#endif diff --git a/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h b/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h new file mode 100644 index 00000000000..2727e737570 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h @@ -0,0 +1,45 @@ +#ifndef _COMPARE_CURVES_H +#define _COMPARE_CURVES_H + +#include +#include + +template +class Equal_pred { +public: + using Point_2 = typename Traits::Point_2; + using X_monotone_curve_2 = typename Traits::X_monotone_curve_2; + + Equal_pred(const Traits& traits) : m_traits(traits) {} + + bool operator()(const Point_2& p1, const Point_2& p2) + { return(m_traits.equal_2_object()(p1, p2)); } + + bool operator()(const X_monotone_curve_2& c1, const X_monotone_curve_2& c2) + { return(m_traits.equal_2_object()(c1, c2)); } + +private: + const Traits& m_traits; +}; + + +template +bool compare_lists(const List& list1, const List& list2, Traits& traits) { + if(! (list1.size() == list2.size())) { + std::cerr << "Error: The lists are not of the same lengths (" + << list1.size() << "," << list2.size() << ")\n"; + return false; + } + + Equal_pred eq(traits); + auto rc = std::equal(list1.begin(), list1.end(), list2.begin(), eq); + if (! rc) { + std::cerr << "Error: The lists do not match\n"; + return false; + } + + return true; +} + + +#endif diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test00.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test00.txt deleted file mode 100644 index 420b718d1e7..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test00.txt +++ /dev/null @@ -1,23 +0,0 @@ -2 --1 1 1 -1 -1 1 -1 -1 -4 -0/8 0/8 -1/1 -1/1 --1/1 1/1 0/8 0/8 -0/8 0/8 1/1 -1/1 -1/1 1/1 0/8 0/8 -5 --1/1 -1/1 --1/1 1/1 -0/8 0/8 -1/1 -1/1 -1/1 1/1 -1 -0/8 0/8 -1 -4 -0/8 0/8 -1/1 -1/1 --1/1 1/1 0/8 0/8 -0/8 0/8 1/1 -1/1 -1/1 1/1 0/8 0/8 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test01.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test01.txt deleted file mode 100644 index b8f61bf90c6..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test01.txt +++ /dev/null @@ -1,50 +0,0 @@ -4 -4 6 3 0 -1 3 5 1 -5 0 1 2 -1 0 3 4 -12 -1/1 0/1 36/20 32/20 -36/20 32/20 1/1 2/1 -36/20 32/20 44/20 48/20 -1/1 3/1 44/20 48/20 -44/20 48/20 3/1 4/1 -82/26 24/26 3/1 0/1 -82/26 24/26 36/20 32/20 -86/26 48/26 82/26 24/26 -44/20 48/20 86/26 48/26 -4/1 6/1 86/26 48/26 -5/1 0/1 82/26 24/26 -86/26 48/26 5/1 1/1 -12 -1/1 0/1 -1/1 2/1 -1/1 3/1 -36/20 32/20 -44/20 48/20 -3/1 0/1 -3/1 4/1 -82/26 24/26 -86/26 48/26 -4/1 6/1 -5/1 0/1 -5/1 1/1 -4 -36/20 32/20 -44/20 48/20 -82/26 24/26 -86/26 48/26 -2 -12 -1/1 0/1 36/20 32/20 -36/20 32/20 1/1 2/1 -36/20 32/20 44/20 48/20 -1/1 3/1 44/20 48/20 -44/20 48/20 3/1 4/1 -82/26 24/26 3/1 0/1 -82/26 24/26 36/20 32/20 -86/26 48/26 82/26 24/26 -44/20 48/20 86/26 48/26 -4/1 6/1 86/26 48/26 -5/1 0/1 82/26 24/26 -86/26 48/26 5/1 1/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test02.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test02.txt deleted file mode 100644 index 9f96ea0d395..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test02.txt +++ /dev/null @@ -1,34 +0,0 @@ -3 -0 6 9 5 -7 4 1 3 -5 2 3 7 -7 -0/1 6/1 153/43 241/43 -153/43 241/43 3/1 7/1 -140/32 114/32 1/1 3/1 -140/32 114/32 153/43 241/43 -5/1 2/1 140/32 114/32 -7/1 4/1 140/32 114/32 -153/43 241/43 9/1 5/1 -8 -0/1 6/1 -1/1 3/1 -3/1 7/1 -153/43 241/43 -140/32 114/32 -5/1 2/1 -7/1 4/1 -9/1 5/1 -2 -153/43 241/43 -140/32 114/32 -1 -7 -0/1 6/1 153/43 241/43 -153/43 241/43 3/1 7/1 -140/32 114/32 1/1 3/1 -140/32 114/32 153/43 241/43 -5/1 2/1 140/32 114/32 -7/1 4/1 140/32 114/32 -153/43 241/43 9/1 5/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test03.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test03.txt deleted file mode 100644 index 9fc24d51667..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test03.txt +++ /dev/null @@ -1,22 +0,0 @@ -3 -1 1 5 1 -1 2 5 2 -1 3 5 3 -3 -1/1 1/1 5/1 1/1 -1/1 2/1 5/1 2/1 -1/1 3/1 5/1 3/1 -6 -1/1 1/1 -1/1 2/1 -1/1 3/1 -5/1 1/1 -5/1 2/1 -5/1 3/1 -0 -1 -3 -1/1 1/1 5/1 1/1 -1/1 2/1 5/1 2/1 -1/1 3/1 5/1 3/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test04.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test04.txt deleted file mode 100644 index 953c0bdeaaf..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test04.txt +++ /dev/null @@ -1,34 +0,0 @@ -3 -1 4 4 1 -2 2 9 2 -3 7 8 1 -7 -2/1 2/1 63/21 42/21 -1/1 4/1 63/21 42/21 -63/21 42/21 4/1 1/1 -63/21 42/21 301/42 84/42 -3/1 7/1 301/42 84/42 -301/42 84/42 8/1 1/1 -301/42 84/42 9/1 2/1 -8 -1/1 4/1 -2/1 2/1 -63/21 42/21 -3/1 7/1 -4/1 1/1 -301/42 84/42 -8/1 1/1 -9/1 2/1 -2 -63/21 42/21 -301/42 84/42 -1 -7 -2/1 2/1 63/21 42/21 -1/1 4/1 63/21 42/21 -63/21 42/21 4/1 1/1 -63/21 42/21 301/42 84/42 -3/1 7/1 301/42 84/42 -301/42 84/42 8/1 1/1 -301/42 84/42 9/1 2/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test05.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test05.txt deleted file mode 100644 index 46d7e73e4d6..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test05.txt +++ /dev/null @@ -1,40 +0,0 @@ -3 -2 7 15 2 -3 2 10 6 -1 3 14 3 -9 -3/1 2/1 247/52 156/52 -1/1 3/1 247/52 156/52 -247/52 156/52 681/87 414/87 -2/1 7/1 681/87 414/87 -681/87 414/87 10/1 6/1 -247/52 156/52 806/65 195/65 -681/87 414/87 806/65 195/65 -806/65 195/65 14/1 3/1 -806/65 195/65 15/1 2/1 -9 -1/1 3/1 -2/1 7/1 -3/1 2/1 -247/52 156/52 -681/87 414/87 -10/1 6/1 -806/65 195/65 -14/1 3/1 -15/1 2/1 -3 -247/52 156/52 -681/87 414/87 -806/65 195/65 -2 -9 -3/1 2/1 247/52 156/52 -1/1 3/1 247/52 156/52 -247/52 156/52 681/87 414/87 -2/1 7/1 681/87 414/87 -681/87 414/87 10/1 6/1 -247/52 156/52 806/65 195/65 -681/87 414/87 806/65 195/65 -806/65 195/65 14/1 3/1 -806/65 195/65 15/1 2/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test06.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test06.txt deleted file mode 100644 index cd0e00f2585..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test06.txt +++ /dev/null @@ -1,61 +0,0 @@ -6 -12 4 9 4 -12 3 11 3 -14 1 8 6 -7 6 1 1 -6 2 3 7 -5 7 3 5 -14 -60/16 92/16 3/1 5/1 -60/16 92/16 3/1 7/1 -213/45 185/45 1/1 1/1 -213/45 185/45 60/16 92/16 -5/1 7/1 60/16 92/16 -6/1 2/1 213/45 185/45 -7/1 6/1 213/45 185/45 -156/15 60/15 9/1 4/1 -156/15 60/15 8/1 6/1 -58/5 15/5 11/1 3/1 -58/5 15/5 156/15 60/15 -12/1 3/1 58/5 15/5 -12/1 4/1 156/15 60/15 -14/1 1/1 58/5 15/5 -16 -1/1 1/1 -3/1 5/1 -3/1 7/1 -60/16 92/16 -213/45 185/45 -5/1 7/1 -6/1 2/1 -7/1 6/1 -8/1 6/1 -9/1 4/1 -156/15 60/15 -11/1 3/1 -58/5 15/5 -12/1 3/1 -12/1 4/1 -14/1 1/1 -4 -60/16 92/16 -213/45 185/45 -156/15 60/15 -58/5 15/5 -1 -14 -60/16 92/16 3/1 5/1 -60/16 92/16 3/1 7/1 -213/45 185/45 1/1 1/1 -213/45 185/45 60/16 92/16 -5/1 7/1 60/16 92/16 -6/1 2/1 213/45 185/45 -7/1 6/1 213/45 185/45 -156/15 60/15 9/1 4/1 -156/15 60/15 8/1 6/1 -58/5 15/5 11/1 3/1 -58/5 15/5 156/15 60/15 -12/1 3/1 58/5 15/5 -12/1 4/1 156/15 60/15 -14/1 1/1 58/5 15/5 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test07.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test07.txt deleted file mode 100644 index c94c53eece6..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test07.txt +++ /dev/null @@ -1,22 +0,0 @@ -4 -5 5 2 3 -7 1 2 3 -7 1 9 4 -5 5 9 4 -4 -5/1 5/1 2/1 3/1 -7/1 1/1 2/1 3/1 -7/1 1/1 9/1 4/1 -5/1 5/1 9/1 4/1 -4 -2/1 3/1 -5/1 5/1 -7/1 1/1 -9/1 4/1 -0 -2 -4 -5/1 5/1 2/1 3/1 -7/1 1/1 2/1 3/1 -7/1 1/1 9/1 4/1 -5/1 5/1 9/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test08.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test08.txt deleted file mode 100644 index 2aa0735bf04..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test08.txt +++ /dev/null @@ -1,19 +0,0 @@ -2 -1 2 4 2 -3 0 5 4 -3 -3/1 0/1 4/1 2/1 -1/1 2/1 4/1 2/1 -4/1 2/1 5/1 4/1 -4 -1/1 2/1 -3/1 0/1 -4/1 2/1 -5/1 4/1 -1 -4/1 2/1 -1 -3 -3/1 0/1 4/1 2/1 -1/1 2/1 4/1 2/1 -4/1 2/1 5/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test09.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test09.txt deleted file mode 100644 index e9f6371753e..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test09.txt +++ /dev/null @@ -1,20 +0,0 @@ -2 -1 1 7 1 -3 1 5 4 -3 -1/1 1/1 3/1 1/1 -3/1 1/1 5/1 4/1 -3/1 1/1 7/1 1/1 -4 -1/1 1/1 -3/1 1/1 -5/1 4/1 -7/1 1/1 -1 -3/1 1/1 -1 -3 -1/1 1/1 3/1 1/1 -3/1 1/1 5/1 4/1 -3/1 1/1 7/1 1/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test10.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test10.txt deleted file mode 100644 index f0113460554..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test10.txt +++ /dev/null @@ -1,21 +0,0 @@ -2 -6 1 1 1 -4 -2 3 1 -3 -3/1 1/1 1/1 1/1 -4/1 -2/1 3/1 1/1 -6/1 1/1 3/1 1/1 -4 -1/1 1/1 -3/1 1/1 -4/1 -2/1 -6/1 1/1 -1 -3/1 1/1 -1 -3 -3/1 1/1 1/1 1/1 -4/1 -2/1 3/1 1/1 -6/1 1/1 3/1 1/1 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test11.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test11.txt deleted file mode 100644 index 78140996955..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test11.txt +++ /dev/null @@ -1,21 +0,0 @@ -2 -1 1 3 5 -5 3 2 3 -3 -1/1 1/1 2/1 3/1 -2/1 3/1 3/1 5/1 -5/1 3/1 2/1 3/1 -4 -1/1 1/1 -2/1 3/1 -3/1 5/1 -5/1 3/1 -1 -2/1 3/1 -1 -3 -1/1 1/1 2/1 3/1 -2/1 3/1 3/1 5/1 -5/1 3/1 2/1 3/1 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test12.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test12.txt deleted file mode 100644 index 39d22990f45..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test12.txt +++ /dev/null @@ -1,29 +0,0 @@ -3 -2 4 4 1 -7 1 1 1 -1 4 5 4 -5 -1/1 4/1 2/1 4/1 -4/1 1/1 1/1 1/1 -2/1 4/1 4/1 1/1 -2/1 4/1 5/1 4/1 -7/1 1/1 4/1 1/1 -6 -1/1 1/1 -1/1 4/1 -2/1 4/1 -4/1 1/1 -5/1 4/1 -7/1 1/1 -2 -2/1 4/1 -4/1 1/1 -1 -5 -1/1 4/1 2/1 4/1 -4/1 1/1 1/1 1/1 -2/1 4/1 4/1 1/1 -2/1 4/1 5/1 4/1 -7/1 1/1 4/1 1/1 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test13.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test13.txt deleted file mode 100644 index 69f7c821d95..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test13.txt +++ /dev/null @@ -1,28 +0,0 @@ -3 -0 2 4 2 -1 5 9 -1 -7 4 3 0 -5 -0/1 2/1 4/1 2/1 -280/56 112/56 3/1 0/1 -1/1 5/1 280/56 112/56 -7/1 4/1 280/56 112/56 -280/56 112/56 9/1 -1/1 -7 -0/1 2/1 -1/1 5/1 -3/1 0/1 -4/1 2/1 -280/56 112/56 -7/1 4/1 -9/1 -1/1 -1 -280/56 112/56 -1 -5 -0/1 2/1 4/1 2/1 -280/56 112/56 3/1 0/1 -1/1 5/1 280/56 112/56 -7/1 4/1 280/56 112/56 -280/56 112/56 9/1 -1/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test14.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test14.txt deleted file mode 100644 index 6252c3b96dc..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test14.txt +++ /dev/null @@ -1,47 +0,0 @@ -7 -0 2 4 2 -1 5 9 -1 -7 4 3 0 -3 5 5 5 -3 4 5 4 -3 -1 5 -1 -3 -2 5 -2 -9 -0/1 2/1 4/1 2/1 -3/1 -2/1 5/1 -2/1 -3/1 -1/1 5/1 -1/1 -280/56 112/56 3/1 0/1 -1/1 5/1 280/56 112/56 -3/1 4/1 5/1 4/1 -3/1 5/1 5/1 5/1 -7/1 4/1 280/56 112/56 -280/56 112/56 9/1 -1/1 -15 -0/1 2/1 -1/1 5/1 -3/1 -2/1 -3/1 -1/1 -3/1 0/1 -3/1 4/1 -3/1 5/1 -4/1 2/1 -5/1 -2/1 -5/1 -1/1 -280/56 112/56 -5/1 4/1 -5/1 5/1 -7/1 4/1 -9/1 -1/1 -1 -280/56 112/56 -1 -9 -0/1 2/1 4/1 2/1 -3/1 -2/1 5/1 -2/1 -3/1 -1/1 5/1 -1/1 -280/56 112/56 3/1 0/1 -1/1 5/1 280/56 112/56 -3/1 4/1 5/1 4/1 -3/1 5/1 5/1 5/1 -7/1 4/1 280/56 112/56 -280/56 112/56 9/1 -1/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test15.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test15.txt deleted file mode 100644 index bc9ee161137..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test15.txt +++ /dev/null @@ -1,41 +0,0 @@ -9 -0 0 4 3 -3 -3 5 -1 -3 -3 0 0 -4 -4 5 -1 -4 -4 3 -3 -5 -1 9 -1 -8 2 9 -1 -8 2 5 -1 -4 3 5 -1 -9 -3/1 -3/1 0/1 0/1 -4/1 -4/1 3/1 -3/1 -0/1 0/1 4/1 3/1 -4/1 -4/1 5/1 -1/1 -3/1 -3/1 5/1 -1/1 -4/1 3/1 5/1 -1/1 -8/1 2/1 5/1 -1/1 -5/1 -1/1 9/1 -1/1 -8/1 2/1 9/1 -1/1 -7 -0/1 0/1 -3/1 -3/1 -4/1 -4/1 -4/1 3/1 -5/1 -1/1 -8/1 2/1 -9/1 -1/1 -0 -4 -9 -3/1 -3/1 0/1 0/1 -4/1 -4/1 3/1 -3/1 -0/1 0/1 4/1 3/1 -4/1 -4/1 5/1 -1/1 -3/1 -3/1 5/1 -1/1 -4/1 3/1 5/1 -1/1 -8/1 2/1 5/1 -1/1 -5/1 -1/1 9/1 -1/1 -8/1 2/1 9/1 -1/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test16.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test16.txt deleted file mode 100644 index d174c920fc2..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test16.txt +++ /dev/null @@ -1,57 +0,0 @@ -7 -6 3 0 3 -2 0 4 6 -4 0 2 6 -5 1 1 5 -5 5 1 1 -0 2 6 4 -1 4 5 2 -14 -2/1 0/1 36/12 36/12 -36/12 36/12 1/1 1/1 -0/1 2/1 36/12 36/12 -36/12 36/12 0/1 3/1 -1/1 4/1 36/12 36/12 -36/12 36/12 1/1 5/1 -36/12 36/12 2/1 6/1 -4/1 0/1 36/12 36/12 -36/12 36/12 4/1 6/1 -5/1 1/1 36/12 36/12 -36/12 36/12 5/1 2/1 -5/1 5/1 36/12 36/12 -6/1 3/1 36/12 36/12 -36/12 36/12 6/1 4/1 -15 -0/1 2/1 -0/1 3/1 -1/1 1/1 -1/1 4/1 -1/1 5/1 -2/1 0/1 -2/1 6/1 -36/12 36/12 -4/1 0/1 -4/1 6/1 -5/1 1/1 -5/1 2/1 -5/1 5/1 -6/1 3/1 -6/1 4/1 -1 -36/12 36/12 -1 -14 -2/1 0/1 36/12 36/12 -36/12 36/12 1/1 1/1 -0/1 2/1 36/12 36/12 -36/12 36/12 0/1 3/1 -1/1 4/1 36/12 36/12 -36/12 36/12 1/1 5/1 -36/12 36/12 2/1 6/1 -4/1 0/1 36/12 36/12 -36/12 36/12 4/1 6/1 -5/1 1/1 36/12 36/12 -36/12 36/12 5/1 2/1 -5/1 5/1 36/12 36/12 -6/1 3/1 36/12 36/12 -36/12 36/12 6/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test17.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test17.txt deleted file mode 100644 index 32cf9a98c6c..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test17.txt +++ /dev/null @@ -1,23 +0,0 @@ -4 -1 5 0 4 -1 5 2 4 -1 3 0 4 -1 3 2 4 -4 -1/1 3/1 0/1 4/1 -1/1 5/1 0/1 4/1 -1/1 3/1 2/1 4/1 -1/1 5/1 2/1 4/1 -4 -0/1 4/1 -1/1 3/1 -1/1 5/1 -2/1 4/1 -0 -2 -4 -1/1 3/1 0/1 4/1 -1/1 5/1 0/1 4/1 -1/1 3/1 2/1 4/1 -1/1 5/1 2/1 4/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test18.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test18.txt deleted file mode 100644 index 049c8e10a28..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test18.txt +++ /dev/null @@ -1,27 +0,0 @@ -3 -0 0 6 0 -0 2 3 2 -2 -1 4 1 -5 -2/1 -1/1 36/12 0/12 -0/1 0/1 36/12 0/12 -0/1 2/1 3/1 2/1 -36/12 0/12 4/1 1/1 -36/12 0/12 6/1 0/1 -7 -0/1 0/1 -0/1 2/1 -2/1 -1/1 -36/12 0/12 -3/1 2/1 -4/1 1/1 -6/1 0/1 -1 -36/12 0/12 -1 -5 -2/1 -1/1 36/12 0/12 -0/1 0/1 36/12 0/12 -0/1 2/1 3/1 2/1 -36/12 0/12 4/1 1/1 -36/12 0/12 6/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test19.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test19.txt deleted file mode 100644 index b21e9b2a107..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test19.txt +++ /dev/null @@ -1,21 +0,0 @@ -3 -0 0 3 0 -3 0 5 0 -5 0 8 0 -3 -0/1 0/1 3/1 0/1 -3/1 0/1 5/1 0/1 -5/1 0/1 8/1 0/1 -4 -0/1 0/1 -3/1 0/1 -5/1 0/1 -8/1 0/1 -0 -1 -3 -0/1 0/1 3/1 0/1 -3/1 0/1 5/1 0/1 -5/1 0/1 8/1 0/1 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test20.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test20.txt deleted file mode 100644 index 9075a5d1fb5..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test20.txt +++ /dev/null @@ -1,30 +0,0 @@ -3 -1 2 4 2 -3 0 5 4 -3 4 5 0 -5 -3/1 0/1 4/1 2/1 -1/1 2/1 4/1 2/1 -3/1 4/1 4/1 2/1 -4/1 2/1 5/1 0/1 -4/1 2/1 5/1 4/1 -6 -1/1 2/1 -3/1 0/1 -3/1 4/1 -4/1 2/1 -5/1 0/1 -5/1 4/1 -1 -4/1 2/1 -1 -5 -3/1 0/1 4/1 2/1 -1/1 2/1 4/1 2/1 -3/1 4/1 4/1 2/1 -4/1 2/1 5/1 0/1 -4/1 2/1 5/1 4/1 - - - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test21.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test21.txt deleted file mode 100644 index 445b25d3b6e..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test21.txt +++ /dev/null @@ -1,29 +0,0 @@ -3 -6 1 1 6 -9 3 0 3 -2 1 6 5 -6 -2/1 1/1 180/45 135/45 -180/45 135/45 0/1 3/1 -180/45 135/45 1/1 6/1 -6/1 1/1 180/45 135/45 -180/45 135/45 6/1 5/1 -9/1 3/1 180/45 135/45 -7 -0/1 3/1 -1/1 6/1 -2/1 1/1 -180/45 135/45 -6/1 1/1 -6/1 5/1 -9/1 3/1 -1 -180/45 135/45 -1 -6 -2/1 1/1 180/45 135/45 -180/45 135/45 0/1 3/1 -180/45 135/45 1/1 6/1 -6/1 1/1 180/45 135/45 -180/45 135/45 6/1 5/1 -9/1 3/1 180/45 135/45 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test22.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test22.txt deleted file mode 100644 index 738953c643b..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test22.txt +++ /dev/null @@ -1,29 +0,0 @@ -5 -0 0 1 1 -0 0 2 3 -0 0 9 8 -0 0 -1 -3 -0 0 -3 4 -5 -0/1 0/1 -1/1 -3/1 -0/1 0/1 -3/1 4/1 -0/1 0/1 1/1 1/1 -0/1 0/1 2/1 3/1 -0/1 0/1 9/1 8/1 -6 --3/1 4/1 --1/1 -3/1 -0/1 0/1 -1/1 1/1 -2/1 3/1 -9/1 8/1 -0 -1 -5 -0/1 0/1 -1/1 -3/1 -0/1 0/1 -3/1 4/1 -0/1 0/1 1/1 1/1 -0/1 0/1 2/1 3/1 -0/1 0/1 9/1 8/1 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test23.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test23.txt deleted file mode 100644 index 8c692cc93a4..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test23.txt +++ /dev/null @@ -1,24 +0,0 @@ -4 -1 2 0 0 -3 2 0 0 -0 0 4 0 -0 0 2 -2 -4 -1/1 2/1 0/1 0/1 -0/1 0/1 2/1 -2/1 -3/1 2/1 0/1 0/1 -0/1 0/1 4/1 0/1 -5 -0/1 0/1 -1/1 2/1 -2/1 -2/1 -3/1 2/1 -4/1 0/1 -0 -1 -4 -1/1 2/1 0/1 0/1 -0/1 0/1 2/1 -2/1 -3/1 2/1 0/1 0/1 -0/1 0/1 4/1 0/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test24.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test24.txt deleted file mode 100644 index 601e8cfbf8a..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test24.txt +++ /dev/null @@ -1,23 +0,0 @@ -4 --3 2 0 0 --3 0 0 0 --2 -2 0 0 -0 0 -2 -4 -4 -0/1 0/1 -2/1 -4/1 --2/1 -2/1 0/1 0/1 --3/1 0/1 0/1 0/1 --3/1 2/1 0/1 0/1 -5 --3/1 0/1 --3/1 2/1 --2/1 -4/1 --2/1 -2/1 -0/1 0/1 -0 -1 -4 -0/1 0/1 -2/1 -4/1 --2/1 -2/1 0/1 0/1 --3/1 0/1 0/1 0/1 --3/1 2/1 0/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test25.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test25.txt deleted file mode 100644 index 3b52e2164d7..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test25.txt +++ /dev/null @@ -1,24 +0,0 @@ -4 -0 0 3 3 -3 3 6 6 -6 0 3 3 -0 6 3 3 -4 -0/1 0/1 3/1 3/1 -0/1 6/1 3/1 3/1 -6/1 0/1 3/1 3/1 -3/1 3/1 6/1 6/1 -5 -0/1 0/1 -0/1 6/1 -3/1 3/1 -6/1 0/1 -6/1 6/1 -0 -1 -4 -0/1 0/1 3/1 3/1 -0/1 6/1 3/1 3/1 -6/1 0/1 3/1 3/1 -3/1 3/1 6/1 6/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test26.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test26.txt deleted file mode 100644 index fc3cfb4fc30..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test26.txt +++ /dev/null @@ -1,42 +0,0 @@ -7 -0 7 2 5 -0 5 2 5 -2 4 4 4 -2 4 4 2 -2 7 4 9 -0 1 4 1 -1 4 3 6 -8 -1/1 4/1 2/1 5/1 -0/1 5/1 2/1 5/1 -0/1 7/1 2/1 5/1 -2/1 5/1 3/1 6/1 -0/1 1/1 4/1 1/1 -2/1 4/1 4/1 2/1 -2/1 4/1 4/1 4/1 -2/1 7/1 4/1 9/1 -12 -0/1 1/1 -0/1 5/1 -0/1 7/1 -1/1 4/1 -2/1 4/1 -2/1 5/1 -2/1 7/1 -3/1 6/1 -4/1 1/1 -4/1 2/1 -4/1 4/1 -4/1 9/1 -1 -2/1 5/1 -1 -8 -1/1 4/1 2/1 5/1 -0/1 5/1 2/1 5/1 -0/1 7/1 2/1 5/1 -2/1 5/1 3/1 6/1 -0/1 1/1 4/1 1/1 -2/1 4/1 4/1 2/1 -2/1 4/1 4/1 4/1 -2/1 7/1 4/1 9/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test27.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test27.txt deleted file mode 100644 index 1d25c06c8c4..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test27.txt +++ /dev/null @@ -1,37 +0,0 @@ -8 -1 5 0 4 -1 5 2 4 -1 3 0 4 -1 3 2 4 -0 2 1 3 -0 2 1 1 -1 3 2 2 -1 1 2 2 -8 -0/1 2/1 1/1 1/1 -0/1 2/1 1/1 3/1 -1/1 3/1 0/1 4/1 -1/1 5/1 0/1 4/1 -1/1 1/1 2/1 2/1 -1/1 3/1 2/1 2/1 -1/1 3/1 2/1 4/1 -1/1 5/1 2/1 4/1 -7 -0/1 2/1 -0/1 4/1 -1/1 1/1 -1/1 3/1 -1/1 5/1 -2/1 2/1 -2/1 4/1 -0 -3 -8 -0/1 2/1 1/1 1/1 -0/1 2/1 1/1 3/1 -1/1 3/1 0/1 4/1 -1/1 5/1 0/1 4/1 -1/1 1/1 2/1 2/1 -1/1 3/1 2/1 2/1 -1/1 3/1 2/1 4/1 -1/1 5/1 2/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test28.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test28.txt deleted file mode 100644 index ed905e724c2..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test28.txt +++ /dev/null @@ -1,44 +0,0 @@ -10 --1 0 0 1 -0 1 1 2 -0 -1 -1 0 -1 0 0 1 -2 1 1 2 -0 -1 1 0 -1 0 2 1 -1 0 2 -1 -2 1 3 0 -2 -1 3 0 -10 -0/1 -1/1 -1/1 0/1 --1/1 0/1 0/1 1/1 -0/1 -1/1 1/1 0/1 -1/1 0/1 0/1 1/1 -0/1 1/1 1/1 2/1 -1/1 0/1 2/1 -1/1 -1/1 0/1 2/1 1/1 -2/1 1/1 1/1 2/1 -2/1 -1/1 3/1 0/1 -2/1 1/1 3/1 0/1 -8 --1/1 0/1 -0/1 -1/1 -0/1 1/1 -1/1 0/1 -1/1 2/1 -2/1 -1/1 -2/1 1/1 -3/1 0/1 -0 -4 -10 -0/1 -1/1 -1/1 0/1 --1/1 0/1 0/1 1/1 -0/1 -1/1 1/1 0/1 -1/1 0/1 0/1 1/1 -0/1 1/1 1/1 2/1 -1/1 0/1 2/1 -1/1 -1/1 0/1 2/1 1/1 -2/1 1/1 1/1 2/1 -2/1 -1/1 3/1 0/1 -2/1 1/1 3/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test29.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test29.txt deleted file mode 100644 index 37aca71a59c..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test29.txt +++ /dev/null @@ -1,26 +0,0 @@ -3 -0 4 4 0 -0 0 4 4 -2 2 5 2 -5 -0/1 0/1 2/1 2/1 -0/1 4/1 2/1 2/1 -2/1 2/1 4/1 0/1 -2/1 2/1 4/1 4/1 -2/1 2/1 5/1 2/1 -6 -0/1 0/1 -0/1 4/1 -2/1 2/1 -4/1 0/1 -4/1 4/1 -5/1 2/1 -1 -2/1 2/1 -1 -5 -0/1 0/1 2/1 2/1 -0/1 4/1 2/1 2/1 -2/1 2/1 4/1 0/1 -2/1 2/1 4/1 4/1 -2/1 2/1 5/1 2/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test30.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test30.txt deleted file mode 100644 index e6a784c9d3d..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test30.txt +++ /dev/null @@ -1,22 +0,0 @@ -2 -0 0 5 0 -2 -2 2 3 -4 -2/1 -2/1 50/25 0/25 -0/1 0/1 50/25 0/25 -50/25 0/25 2/1 3/1 -50/25 0/25 5/1 0/1 -5 -0/1 0/1 -2/1 -2/1 -50/25 0/25 -2/1 3/1 -5/1 0/1 -1 -50/25 0/25 -1 -4 -2/1 -2/1 50/25 0/25 -0/1 0/1 50/25 0/25 -50/25 0/25 2/1 3/1 -50/25 0/25 5/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test31.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test31.txt deleted file mode 100644 index 3185f80ec7b..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test31.txt +++ /dev/null @@ -1,33 +0,0 @@ -3 -1 2 3 2 -0 0 5 0 -2 4 2 -2 -7 -60/30 0/30 2/1 -2/1 -0/1 0/1 60/30 0/30 -24/12 24/12 60/30 0/30 -1/1 2/1 24/12 24/12 -2/1 4/1 24/12 24/12 -24/12 24/12 3/1 2/1 -60/30 0/30 5/1 0/1 -8 -0/1 0/1 -1/1 2/1 -2/1 -2/1 -60/30 0/30 -24/12 24/12 -2/1 4/1 -3/1 2/1 -5/1 0/1 -2 -60/30 0/30 -24/12 24/12 -1 -7 -60/30 0/30 2/1 -2/1 -0/1 0/1 60/30 0/30 -24/12 24/12 60/30 0/30 -1/1 2/1 24/12 24/12 -2/1 4/1 24/12 24/12 -24/12 24/12 3/1 2/1 -60/30 0/30 5/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test32.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test32.txt deleted file mode 100644 index 830d83f2e59..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test32.txt +++ /dev/null @@ -1,33 +0,0 @@ -3 -1 2 3 2 -0 0 5 0 -2 -2 2 4 -7 -2/1 -2/1 2/1 0/1 -0/1 0/1 2/1 0/1 -2/1 0/1 2/1 2/1 -1/1 2/1 2/1 2/1 -2/1 2/1 2/1 4/1 -2/1 2/1 3/1 2/1 -2/1 0/1 5/1 0/1 -8 -0/1 0/1 -1/1 2/1 -2/1 -2/1 -60/30 0/30 -24/12 24/12 -2/1 4/1 -3/1 2/1 -5/1 0/1 -2 -60/30 0/30 -24/12 24/12 -1 -7 -2/1 -2/1 2/1 0/1 -0/1 0/1 2/1 0/1 -2/1 0/1 2/1 2/1 -1/1 2/1 2/1 2/1 -2/1 2/1 2/1 4/1 -2/1 2/1 3/1 2/1 -2/1 0/1 5/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test33.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test33.txt deleted file mode 100644 index 52b22ae49a6..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test33.txt +++ /dev/null @@ -1,16 +0,0 @@ -2 -1 5 1 2 -0 0 3 2 -2 -1/1 5/1 1/1 2/1 -0/1 0/1 3/1 2/1 -4 -0/1 0/1 -1/1 2/1 -1/1 5/1 -3/1 2/1 -0 -1 -2 -1/1 5/1 1/1 2/1 -0/1 0/1 3/1 2/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test34.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test34.txt deleted file mode 100644 index 9587d1b15dc..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test34.txt +++ /dev/null @@ -1,16 +0,0 @@ -2 --1 2 1 4 -0 0 0 2 -2 -0/1 0/1 0/1 2/1 --1/1 2/1 1/1 4/1 -4 --1/1 2/1 -0/1 0/1 -0/1 2/1 -1/1 4/1 -0 -1 -2 -0/1 0/1 0/1 2/1 --1/1 2/1 1/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test35.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test35.txt deleted file mode 100644 index 58b53d15991..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test35.txt +++ /dev/null @@ -1,43 +0,0 @@ -5 -1 7 3 7 -2 6 2 2 -0 4 4 4 -1 3 3 3 -1 0 3 0 -9 -2/1 3/1 2/1 2/1 -1/1 3/1 2/1 3/1 -2/1 4/1 2/1 3/1 -0/1 4/1 2/1 4/1 -2/1 6/1 2/1 4/1 -1/1 0/1 3/1 0/1 -2/1 3/1 3/1 3/1 -1/1 7/1 3/1 7/1 -2/1 4/1 4/1 4/1 -12 -0/1 4/1 -1/1 0/1 -1/1 3/1 -1/1 7/1 -2/1 2/1 -16/8 24/8 -32/16 64/16 -2/1 6/1 -3/1 0/1 -3/1 3/1 -3/1 7/1 -4/1 4/1 -2 -16/8 24/8 -32/16 64/16 -1 -9 -2/1 3/1 2/1 2/1 -1/1 3/1 2/1 3/1 -2/1 4/1 2/1 3/1 -0/1 4/1 2/1 4/1 -2/1 6/1 2/1 4/1 -1/1 0/1 3/1 0/1 -2/1 3/1 3/1 3/1 -1/1 7/1 3/1 7/1 -2/1 4/1 4/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test36.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test36.txt deleted file mode 100644 index 2c4c5a96f29..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test36.txt +++ /dev/null @@ -1,46 +0,0 @@ -4 -2 0 2 9 -1 7 5 3 -0 4 4 2 -1 2 4 5 -11 -2/1 0/1 2/1 3/1 -1/1 2/1 2/1 3/1 -0/1 4/1 2/1 3/1 -2/1 3/1 2/1 6/1 -1/1 7/1 2/1 6/1 -2/1 6/1 2/1 9/1 -2/1 3/1 7/2 9/2 -2/1 6/1 7/2 9/2 -2/1 3/1 4/1 2/1 -7/2 9/2 4/1 5/1 -7/2 9/2 5/1 3/1 -11 -0/1 4/1 -1/1 2/1 -1/1 7/1 -2/1 0/1 -36/18 54/18 -72/36 216/36 -2/1 9/1 -84/24 108/24 -4/1 2/1 -4/1 5/1 -5/1 3/1 -3 -36/18 54/18 -72/36 216/36 -84/24 108/24 -2 -11 -2/1 0/1 2/1 3/1 -1/1 2/1 2/1 3/1 -0/1 4/1 2/1 3/1 -2/1 3/1 2/1 6/1 -1/1 7/1 2/1 6/1 -2/1 6/1 2/1 9/1 -2/1 3/1 7/2 9/2 -2/1 6/1 7/2 9/2 -2/1 3/1 4/1 2/1 -7/2 9/2 4/1 5/1 -7/2 9/2 5/1 3/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test37.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test37.txt deleted file mode 100644 index bf946526e36..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test37.txt +++ /dev/null @@ -1,55 +0,0 @@ -5 -0 0 0 3 -0 4 0 6 --3 2 2 0 --2 4 1 6 --1 6 -1 1 -13 --1/1 6/5 -1/1 1/1 --3/1 2/1 -1/1 6/5 --1/1 14/3 -1/1 6/5 --2/1 4/1 -1/1 14/3 --1/1 6/1 -1/1 14/3 -0/1 0/1 0/1 4/5 --1/1 6/5 0/1 4/5 -0/1 4/5 0/1 3/1 -0/1 4/1 0/1 16/3 --1/1 14/3 0/1 16/3 -0/1 16/3 0/1 6/1 -0/1 16/3 1/1 6/1 -0/1 4/5 2/1 0/1 -14 --3/1 2/1 --2/1 4/1 --1/1 1/1 --25/25 30/25 --15/15 70/15 --1/1 6/1 -0/1 0/1 -0/15 12/15 -0/1 3/1 -0/1 4/1 -0/6 32/6 -0/1 6/1 -1/1 6/1 -2/1 0/1 -4 --25/25 30/25 --15/15 70/15 -0/15 12/15 -0/6 32/6 -1 -13 --1/1 6/5 -1/1 1/1 --3/1 2/1 -1/1 6/5 --1/1 14/3 -1/1 6/5 --2/1 4/1 -1/1 14/3 --1/1 6/1 -1/1 14/3 -0/1 0/1 0/1 4/5 --1/1 6/5 0/1 4/5 -0/1 4/5 0/1 3/1 -0/1 4/1 0/1 16/3 --1/1 14/3 0/1 16/3 -0/1 16/3 0/1 6/1 -0/1 16/3 1/1 6/1 -0/1 4/5 2/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test40.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test40.txt deleted file mode 100644 index beea62f7afb..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test40.txt +++ /dev/null @@ -1,19 +0,0 @@ -2 -0 0 0 6 -0 3 3 3 -3 -0/1 0/1 0/1 3/1 -0/1 3/1 0/1 6/1 -0/1 3/1 3/1 3/1 -4 -0/1 0/1 -0/1 3/1 -0/1 6/1 -3/1 3/1 -1 -0/1 3/1 -1 -3 -0/1 0/1 0/1 3/1 -0/1 3/1 0/1 6/1 -0/1 3/1 3/1 3/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test41.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test41.txt deleted file mode 100644 index 3651988bd29..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test41.txt +++ /dev/null @@ -1,19 +0,0 @@ -2 --3 3 0 3 -0 0 0 6 -3 -0/1 0/1 0/1 3/1 --3/1 3/1 0/1 3/1 -0/1 3/1 0/1 6/1 -4 --3/1 3/1 -0/1 0/1 -0/1 3/1 -0/1 6/1 -1 -0/1 3/1 -1 -3 -0/1 0/1 0/1 3/1 --3/1 3/1 0/1 3/1 -0/1 3/1 0/1 6/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test42.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test42.txt deleted file mode 100644 index b83c0b96d1c..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test42.txt +++ /dev/null @@ -1,23 +0,0 @@ -3 -0 0 0 4 --2 2 0 2 -0 2 2 2 -4 -0/1 0/1 0/1 2/1 --2/1 2/1 0/1 2/1 -0/1 2/1 0/1 4/1 -0/1 2/1 2/1 2/1 -5 --2/1 2/1 -0/1 0/1 -0/1 2/1 -0/1 4/1 -2/1 2/1 -1 -0/1 2/1 -1 -4 -0/1 0/1 0/1 2/1 --2/1 2/1 0/1 2/1 -0/1 2/1 0/1 4/1 -0/1 2/1 2/1 2/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test43.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test43.txt deleted file mode 100644 index a78d9c4bdea..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test43.txt +++ /dev/null @@ -1,15 +0,0 @@ -2 -0 5 4 5 -4 5 4 1 -2 -4/1 5/1 4/1 1/1 -0/1 5/1 4/1 5/1 -3 -0/1 5/1 -4/1 1/1 -4/1 5/1 -0 -1 -2 -4/1 5/1 4/1 1/1 -0/1 5/1 4/1 5/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test44.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test44.txt deleted file mode 100644 index 0aff3e7b181..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test44.txt +++ /dev/null @@ -1,23 +0,0 @@ -4 -0 4 4 4 -4 4 4 0 -0 0 4 0 -0 4 0 0 -4 -0/1 4/1 0/1 0/1 -0/1 0/1 4/1 0/1 -4/1 4/1 4/1 0/1 -0/1 4/1 4/1 4/1 -4 -0/1 0/1 -0/1 4/1 -4/1 0/1 -4/1 4/1 -0 -2 -4 -0/1 4/1 0/1 0/1 -0/1 0/1 4/1 0/1 -4/1 4/1 4/1 0/1 -0/1 4/1 4/1 4/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test45.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test45.txt deleted file mode 100644 index 431f41756eb..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test45.txt +++ /dev/null @@ -1,15 +0,0 @@ -2 -0 0 4 0 -0 4 0 0 -2 -0/1 4/1 0/1 0/1 -0/1 0/1 4/1 0/1 -3 -0/1 0/1 -0/1 4/1 -4/1 0/1 -0 -1 -2 -0/1 4/1 0/1 0/1 -0/1 0/1 4/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test46.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test46.txt deleted file mode 100644 index ed0e785f55b..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test46.txt +++ /dev/null @@ -1,21 +0,0 @@ -3 -0 6 2 6 -2 5 2 2 -2 1 4 1 -3 -2/1 5/1 2/1 2/1 -0/1 6/1 2/1 6/1 -2/1 1/1 4/1 1/1 -6 -0/1 6/1 -2/1 1/1 -2/1 2/1 -2/1 5/1 -2/1 6/1 -4/1 1/1 -0 -1 -3 -2/1 5/1 2/1 2/1 -0/1 6/1 2/1 6/1 -2/1 1/1 4/1 1/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test47.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test47.txt deleted file mode 100644 index 5861e7d3583..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test47.txt +++ /dev/null @@ -1,19 +0,0 @@ -2 -2 0 2 3 -4 0 0 0 -3 -2/1 0/1 0/1 0/1 -2/1 0/1 2/1 3/1 -4/1 0/1 2/1 0/1 -4 -0/1 0/1 -2/1 0/1 -2/1 3/1 -4/1 0/1 -1 -2/1 0/1 -1 -3 -2/1 0/1 0/1 0/1 -2/1 0/1 2/1 3/1 -4/1 0/1 2/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test48.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test48.txt deleted file mode 100644 index 8546ccf6f28..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test48.txt +++ /dev/null @@ -1,32 +0,0 @@ -4 -0 0 5 0 -2 3 2 0 -7 3 12 3 -9 3 9 0 -6 -0/1 0/1 2/1 0/1 -2/1 3/1 2/1 0/1 -2/1 0/1 5/1 0/1 -9/1 3/1 9/1 0/1 -7/1 3/1 9/1 3/1 -9/1 3/1 12/1 3/1 -8 -0/1 0/1 -2/1 0/1 -2/1 3/1 -5/1 0/1 -7/1 3/1 -9/1 0/1 -9/1 3/1 -12/1 3/1 -2 -2/1 0/1 -9/1 3/1 -1 -6 -0/1 0/1 2/1 0/1 -2/1 3/1 2/1 0/1 -2/1 0/1 5/1 0/1 -9/1 3/1 9/1 0/1 -7/1 3/1 9/1 3/1 -9/1 3/1 12/1 3/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test49.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test49.txt deleted file mode 100644 index 38fdef6d37b..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test49.txt +++ /dev/null @@ -1,15 +0,0 @@ -2 -0 0 4 0 -4 0 4 4 -2 -0/1 0/1 4/1 0/1 -4/1 0/1 4/1 4/1 -3 -0/1 0/1 -4/1 0/1 -4/1 4/1 -0 -1 -2 -0/1 0/1 4/1 0/1 -4/1 0/1 4/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test50.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test50.txt deleted file mode 100644 index 47db121f373..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test50.txt +++ /dev/null @@ -1,31 +0,0 @@ -5 -4 7 8 7 -8 7 8 5 -5 5 8 5 -8 6 9 7 -8 6 9 5 -6 -5/1 5/1 8/1 5/1 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -4/1 7/1 8/1 7/1 -8/1 6/1 9/1 5/1 -8/1 6/1 9/1 7/1 -7 -4/1 7/1 -5/1 5/1 -8/1 5/1 -8/1 6/1 -8/1 7/1 -9/1 5/1 -9/1 7/1 -1 -8/1 6/1 -1 -6 -5/1 5/1 8/1 5/1 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -4/1 7/1 8/1 7/1 -8/1 6/1 9/1 5/1 -8/1 6/1 9/1 7/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test51.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test51.txt deleted file mode 100644 index cf9cd7243ce..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test51.txt +++ /dev/null @@ -1,118 +0,0 @@ -16 -2 4 2 0 -2 6 2 10 -6 8 6 4 -8 7 8 5 -0 8 2 8 -4 7 8 7 -0 6 6 6 -8 5 5 5 -2 3 4 3 -1 7 4 10 -6 6 0 3 -0 1 3 4 -9 7 8 6 -9 5 8 6 -2 0 6 4 -2 10 6 8 -30 -2/1 3/1 2/1 0/1 -0/1 1/1 2/1 3/1 -2/1 4/1 2/1 3/1 -2/1 4/1 0/1 3/1 -0/1 6/1 2/1 6/1 -2/1 6/1 2/1 8/1 -1/1 7/1 2/1 8/1 -0/1 8/1 2/1 8/1 -2/1 8/1 2/1 10/1 -2/1 3/1 3/1 4/1 -2/1 8/1 10/3 28/3 -2/1 10/1 10/3 28/3 -2/1 3/1 4/1 3/1 -10/3 28/3 4/1 10/1 -2/1 0/1 6/1 4/1 -6/1 5/1 6/1 4/1 -6/1 5/1 5/1 5/1 -6/1 6/1 6/1 5/1 -6/1 6/1 2/1 4/1 -2/1 6/1 6/1 6/1 -6/1 7/1 6/1 6/1 -4/1 7/1 6/1 7/1 -6/1 8/1 6/1 7/1 -10/3 28/3 6/1 8/1 -8/1 5/1 6/1 5/1 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -6/1 7/1 8/1 7/1 -9/1 5/1 8/1 6/1 -9/1 7/1 8/1 6/1 -27 -0/1 1/1 -0/1 3/1 -0/1 6/1 -0/1 8/1 -1/1 7/1 -2/1 0/1 -2/1 3/1 -2/1 4/1 -2/1 6/1 -2/1 8/1 -2/1 10/1 -3/1 4/1 -60/18 168/18 -4/1 3/1 -4/1 7/1 -4/1 10/1 -5/1 5/1 -6/1 4/1 -72/12 60/12 -6/1 6/1 -96/16 112/16 -6/1 8/1 -8/1 5/1 -8/1 6/1 -8/1 7/1 -9/1 5/1 -9/1 7/1 -9 -2/1 3/1 -2/1 4/1 -2/1 6/1 -2/1 8/1 -60/18 168/18 -72/12 60/12 -6/1 6/1 -96/16 112/16 -8/1 6/1 -5 -30 -2/1 3/1 2/1 0/1 -0/1 1/1 2/1 3/1 -2/1 4/1 2/1 3/1 -2/1 4/1 0/1 3/1 -0/1 6/1 2/1 6/1 -2/1 6/1 2/1 8/1 -1/1 7/1 2/1 8/1 -0/1 8/1 2/1 8/1 -2/1 8/1 2/1 10/1 -2/1 3/1 3/1 4/1 -2/1 8/1 10/3 28/3 -2/1 10/1 10/3 28/3 -2/1 3/1 4/1 3/1 -10/3 28/3 4/1 10/1 -2/1 0/1 6/1 4/1 -6/1 5/1 6/1 4/1 -6/1 5/1 5/1 5/1 -6/1 6/1 6/1 5/1 -6/1 6/1 2/1 4/1 -2/1 6/1 6/1 6/1 -6/1 7/1 6/1 6/1 -4/1 7/1 6/1 7/1 -6/1 8/1 6/1 7/1 -10/3 28/3 6/1 8/1 -8/1 5/1 6/1 5/1 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -6/1 7/1 8/1 7/1 -9/1 5/1 8/1 6/1 -9/1 7/1 8/1 6/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test52.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test52.txt deleted file mode 100644 index 519eff3c8c9..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test52.txt +++ /dev/null @@ -1,29 +0,0 @@ -3 -0 4 4 0 -0 0 4 4 -2 5 2 -1 -6 -2/1 2/1 2/1 -1/1 -0/1 0/1 2/1 2/1 -0/1 4/1 2/1 2/1 -2/1 5/1 2/1 2/1 -2/1 2/1 4/1 0/1 -2/1 2/1 4/1 4/1 -7 -0/1 0/1 -0/1 4/1 -2/1 -1/1 -64/32 64/32 -2/1 5/1 -4/1 0/1 -4/1 4/1 -1 -64/32 64/32 -1 -6 -2/1 2/1 2/1 -1/1 -0/1 0/1 2/1 2/1 -0/1 4/1 2/1 2/1 -2/1 5/1 2/1 2/1 -2/1 2/1 4/1 0/1 -2/1 2/1 4/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test53.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test53.txt deleted file mode 100644 index 79d17493558..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test53.txt +++ /dev/null @@ -1,20 +0,0 @@ -3 -0 5 0 3 -0 3 0 2 -0 2 0 0 -3 -0/1 2/1 0/1 0/1 -0/1 3/1 0/1 2/1 -0/1 5/1 0/1 3/1 -4 -0/1 0/1 -0/1 2/1 -0/1 3/1 -0/1 5/1 -0 -1 -3 -0/1 2/1 0/1 0/1 -0/1 3/1 0/1 2/1 -0/1 5/1 0/1 3/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test54.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test54.txt deleted file mode 100644 index ce10a30cb75..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test54.txt +++ /dev/null @@ -1,23 +0,0 @@ -3 -8 7 8 5 -8 6 9 7 -8 6 9 5 -4 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -8/1 6/1 9/1 5/1 -8/1 6/1 9/1 7/1 -5 -8/1 5/1 -8/1 6/1 -8/1 7/1 -9/1 5/1 -9/1 7/1 -1 -8/1 6/1 -1 -4 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -8/1 6/1 9/1 5/1 -8/1 6/1 9/1 7/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test55.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test55.txt deleted file mode 100644 index 1065362fc19..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test55.txt +++ /dev/null @@ -1,28 +0,0 @@ -3 -0 0 0 2 -0 1 2 1 -2 0 2 2 -5 -0/1 0/1 0/1 1/1 -0/1 1/1 0/1 2/1 -2/1 0/1 2/1 1/1 -0/1 1/1 2/1 1/1 -2/1 1/1 2/1 2/1 -6 -0/1 0/1 -0/1 1/1 -0/1 2/1 -2/1 0/1 -2/1 1/1 -2/1 2/1 -2 -0/1 1/1 -2/1 1/1 -1 -5 -0/1 0/1 0/1 1/1 -0/1 1/1 0/1 2/1 -2/1 0/1 2/1 1/1 -0/1 1/1 2/1 1/1 -2/1 1/1 2/1 2/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test56.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test56.txt deleted file mode 100644 index adc296648a4..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test56.txt +++ /dev/null @@ -1,27 +0,0 @@ -3 -3 0 3 6 -0 1 6 5 -3 3 7 3 -5 -3/1 0/1 3/1 3/1 -0/1 1/1 3/1 3/1 -3/1 3/1 3/1 6/1 -3/1 3/1 6/1 5/1 -3/1 3/1 7/1 3/1 -6 -0/1 1/1 -3/1 0/1 -3/1 3/1 -3/1 6/1 -6/1 5/1 -7/1 3/1 -1 -3/1 3/1 -1 -5 -3/1 0/1 3/1 3/1 -0/1 1/1 3/1 3/1 -3/1 3/1 3/1 6/1 -3/1 3/1 6/1 5/1 -3/1 3/1 7/1 3/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test60.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test60.txt deleted file mode 100644 index 92beb4090a2..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test60.txt +++ /dev/null @@ -1,22 +0,0 @@ -2 -0 0 4 0 -3 0 7 0 -3 -0/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 7/1 0/1 -4 -0/1 0/1 -3/1 0/1 -4/1 0/1 -7/1 0/1 -2 -3/1 0/1 -4/1 0/1 -1 -4 -0/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 7/1 0/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test61.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test61.txt deleted file mode 100644 index 6db6035cbc7..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test61.txt +++ /dev/null @@ -1,33 +0,0 @@ -3 -3 0 6 0 -0 0 4 0 -2 0 8 0 -5 -0/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 6/1 0/1 -6/1 0/1 8/1 0/1 -6 -0/1 0/1 -2/1 0/1 -3/1 0/1 -4/1 0/1 -6/1 0/1 -8/1 0/1 -4 -2/1 0/1 -3/1 0/1 -4/1 0/1 -6/1 0/1 -1 -9 -0/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -3/1 0/1 4/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 6/1 0/1 -4/1 0/1 6/1 0/1 -6/1 0/1 8/1 0/1 \ No newline at end of file diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test62.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test62.txt deleted file mode 100644 index ee6c49c399e..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test62.txt +++ /dev/null @@ -1,15 +0,0 @@ -2 -0 0 3 0 -0 0 3 0 -1 -0/1 0/1 3/1 0/1 -2 -0/1 0/1 -3/1 0/1 -0 -1 -2 -0/1 0/1 3/1 0/1 -0/1 0/1 3/1 0/1 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test63.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test63.txt deleted file mode 100644 index 8923f049d15..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test63.txt +++ /dev/null @@ -1,25 +0,0 @@ -4 -0 0 2 0 -3 0 5 0 -0 0 5 0 -2 0 3 0 -3 -0/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 5/1 0/1 -4 -0/1 0/1 -2/1 0/1 -3/1 0/1 -5/1 0/1 -2 -2/1 0/1 -3/1 0/1 -1 -6 -0/1 0/1 2/1 0/1 -0/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 5/1 0/1 -3/1 0/1 5/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test64.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test64.txt deleted file mode 100644 index f2825be57f2..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test64.txt +++ /dev/null @@ -1,15 +0,0 @@ -3 -0 0 6 6 -0 0 6 6 -6 6 0 0 -1 -0/1 0/1 6/1 6/1 -2 -0/1 0/1 -6/1 6/1 -0 -1 -3 -0/1 0/1 6/1 6/1 -0/1 0/1 6/1 6/1 -6/1 6/1 0/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test65.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test65.txt deleted file mode 100644 index e83cce072ae..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test65.txt +++ /dev/null @@ -1,25 +0,0 @@ -3 -0 0 4 4 -0 0 4 4 -0 4 4 0 -4 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 -5 -0/1 0/1 -0/1 4/1 -64/32 64/32 -4/1 0/1 -4/1 4/1 -1 -64/32 64/32 -1 -6 -0/1 0/1 64/32 64/32 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 -64/32 64/32 4/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test66.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test66.txt deleted file mode 100644 index 7725cef46c2..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test66.txt +++ /dev/null @@ -1,28 +0,0 @@ -4 -0 0 4 4 -0 0 4 4 -0 4 4 0 -0 4 4 0 -4 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 -5 -0/1 0/1 -0/1 4/1 -64/32 64/32 -4/1 0/1 -4/1 4/1 -1 -64/32 64/32 -1 -8 -0/1 0/1 64/32 64/32 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 -64/32 64/32 4/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test67.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test67.txt deleted file mode 100644 index b380b5e7cbd..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test67.txt +++ /dev/null @@ -1,36 +0,0 @@ -5 -0 0 4 4 -0 0 4 4 -0 4 4 0 -0 4 4 0 --1 2 5 2 -6 -0/1 0/1 48/24 48/24 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 4/1 0/1 -48/24 48/24 4/1 4/1 -48/24 48/24 5/1 2/1 -7 --1/1 2/1 -0/1 0/1 -0/1 4/1 -48/24 48/24 -4/1 0/1 -4/1 4/1 -5/1 2/1 -1 -48/24 48/24 -1 -10 -0/1 0/1 48/24 48/24 -0/1 0/1 48/24 48/24 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 4/1 0/1 -48/24 48/24 4/1 0/1 -48/24 48/24 4/1 4/1 -48/24 48/24 4/1 4/1 -48/24 48/24 5/1 2/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test68.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test68.txt deleted file mode 100644 index 54feabc43ba..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test68.txt +++ /dev/null @@ -1,48 +0,0 @@ -6 -0 0 4 4 -0 0 4 4 -0 4 4 0 -0 4 4 0 --1 2 5 2 -1 1 3 3 -8 -0/1 0/1 1/1 1/1 -1/1 1/1 48/24 48/24 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 3/1 3/1 -48/24 48/24 4/1 0/1 -3/1 3/1 4/1 4/1 -48/24 48/24 5/1 2/1 -9 --1/1 2/1 -0/1 0/1 -0/1 4/1 -1/1 1/1 -48/24 48/24 -3/1 3/1 -4/1 0/1 -4/1 4/1 -5/1 2/1 -3 -1/1 1/1 -48/24 48/24 -3/1 3/1 -1 -16 -0/1 0/1 1/1 1/1 -0/1 0/1 1/1 1/1 -1/1 1/1 48/24 48/24 -1/1 1/1 48/24 48/24 -1/1 1/1 48/24 48/24 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 3/1 3/1 -48/24 48/24 3/1 3/1 -48/24 48/24 3/1 3/1 -48/24 48/24 4/1 0/1 -48/24 48/24 4/1 0/1 -3/1 3/1 4/1 4/1 -3/1 3/1 4/1 4/1 -48/24 48/24 5/1 2/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test69.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test69.txt deleted file mode 100644 index cc0683ad7ad..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test69.txt +++ /dev/null @@ -1,38 +0,0 @@ -8 -1 1 0 2 -1 1 0 1 -0 0 1 1 -3 2 2 1 -2 1 3 1 -3 0 2 1 -1 1 2 1 -2 1 1 1 -7 -0/1 0/1 1/1 1/1 -1/1 1/1 0/1 1/1 -1/1 1/1 0/1 2/1 -1/1 1/1 2/1 1/1 -3/1 0/1 2/1 1/1 -2/1 1/1 3/1 1/1 -3/1 2/1 2/1 1/1 -8 -0/1 0/1 -0/1 1/1 -0/1 2/1 -1/1 1/1 -2/1 1/1 -3/1 0/1 -3/1 1/1 -3/1 2/1 -0 -1 -8 -0/1 0/1 1/1 1/1 -1/1 1/1 0/1 1/1 -1/1 1/1 0/1 2/1 -1/1 1/1 2/1 1/1 -2/1 1/1 1/1 1/1 -3/1 0/1 2/1 1/1 -2/1 1/1 3/1 1/1 -3/1 2/1 2/1 1/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test70.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test70.txt deleted file mode 100644 index c6b68c4163b..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test70.txt +++ /dev/null @@ -1,41 +0,0 @@ -5 -3 0 4 0 -4 0 7 0 -2 0 5 0 -1 0 4 0 -0 0 3 0 -6 -0/1 0/1 1/1 0/1 -1/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 5/1 0/1 -5/1 0/1 7/1 0/1 -7 -0/1 0/1 -1/1 0/1 -2/1 0/1 -3/1 0/1 -4/1 0/1 -5/1 0/1 -7/1 0/1 -5 -1/1 0/1 -2/1 0/1 -3/1 0/1 -4/1 0/1 -5/1 0/1 -1 -12 -0/1 0/1 1/1 0/1 -1/1 0/1 2/1 0/1 -1/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -2/1 0/1 3/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -3/1 0/1 4/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 5/1 0/1 -4/1 0/1 5/1 0/1 -5/1 0/1 7/1 0/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test71.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test71.txt deleted file mode 100644 index 7ac58ab7917..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test71.txt +++ /dev/null @@ -1,29 +0,0 @@ -3 -2 4 2 0 -0 2 4 2 -0 2 4 2 -4 -2/1 2/1 2/1 0/1 -0/1 2/1 2/1 2/1 -2/1 4/1 2/1 2/1 -2/1 2/1 4/1 2/1 -5 -0/1 2/1 -2/1 0/1 -32/16 32/16 -2/1 4/1 -4/1 2/1 -1 -32/16 32/16 -1 -6 -2/1 2/1 2/1 0/1 -0/1 2/1 2/1 2/1 -0/1 2/1 2/1 2/1 -2/1 4/1 2/1 2/1 -2/1 2/1 4/1 2/1 -2/1 2/1 4/1 2/1 - - - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test72.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test72.txt deleted file mode 100644 index c231c7b4f77..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test72.txt +++ /dev/null @@ -1,81 +0,0 @@ -13 -0 0 4 4 -0 0 4 4 -0 4 4 0 -0 4 4 0 --1 2 1 2 -5 4 9 0 -5 4 9 0 -5 0 9 4 -4 2 6 2 -9 2 11 2 -10 4 14 0 -10 0 14 4 -10 0 14 4 -15 --1/1 2/1 1/1 2/1 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 -4/1 2/1 6/1 2/1 -5/1 0/1 224/32 64/32 -5/1 4/1 224/32 64/32 -224/32 64/32 9/1 0/1 -224/32 64/32 9/1 4/1 -9/1 2/1 11/1 2/1 -10/1 0/1 384/32 64/32 -10/1 4/1 384/32 64/32 -384/32 64/32 14/1 0/1 -384/32 64/32 14/1 4/1 -21 --1/1 2/1 -0/1 0/1 -0/1 4/1 -1/1 2/1 -64/32 64/32 -4/1 0/1 -4/1 2/1 -4/1 4/1 -5/1 0/1 -5/1 4/1 -6/1 2/1 -224/32 64/32 -9/1 0/1 -9/1 2/1 -9/1 4/1 -10/1 0/1 -10/1 4/1 -11/1 2/1 -384/32 64/32 -14/1 0/1 -14/1 4/1 -3 -64/32 64/32 -224/32 64/32 -384/32 64/32 -1 -23 --1/1 2/1 1/1 2/1 -0/1 0/1 64/32 64/32 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 -64/32 64/32 4/1 4/1 -4/1 2/1 6/1 2/1 -5/1 0/1 224/32 64/32 -5/1 4/1 224/32 64/32 -5/1 4/1 224/32 64/32 -224/32 64/32 9/1 0/1 -224/32 64/32 9/1 0/1 -224/32 64/32 9/1 4/1 -9/1 2/1 11/1 2/1 -10/1 0/1 384/32 64/32 -10/1 0/1 384/32 64/32 -10/1 4/1 384/32 64/32 -384/32 64/32 14/1 0/1 -384/32 64/32 14/1 4/1 -384/32 64/32 14/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test73.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test73.txt deleted file mode 100644 index 0a95db80fac..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test73.txt +++ /dev/null @@ -1,21 +0,0 @@ -2 -3 0 3 4 -3 2 3 7 -3 -3/1 0/1 3/1 2/1 -3/1 2/1 3/1 4/1 -3/1 4/1 3/1 7/1 -4 -3/1 0/1 -3/1 2/1 -3/1 4/1 -3/1 7/1 -2 -3/1 2/1 -3/1 4/1 -1 -4 -3/1 0/1 3/1 2/1 -3/1 2/1 3/1 4/1 -3/1 2/1 3/1 4/1 -3/1 4/1 3/1 7/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test74.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test74.txt deleted file mode 100644 index 4cc18dcb021..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test74.txt +++ /dev/null @@ -1,33 +0,0 @@ -3 -2 7 2 2 -2 4 2 0 -0 3 4 3 -6 -2/1 2/1 2/1 0/1 -2/1 2/1 2/1 3/1 -0/1 3/1 2/1 3/1 -2/1 3/1 2/1 4/1 -2/1 7/1 2/1 4/1 -2/1 3/1 4/1 3/1 -7 -0/1 3/1 -2/1 0/1 -2/1 2/1 -32/16 48/16 -2/1 4/1 -2/1 7/1 -4/1 3/1 -3 -2/1 2/1 -32/16 48/16 -2/1 4/1 -1 -8 -2/1 2/1 2/1 0/1 -2/1 2/1 2/1 3/1 -2/1 2/1 2/1 3/1 -0/1 3/1 2/1 3/1 -2/1 3/1 2/1 4/1 -2/1 3/1 2/1 4/1 -2/1 7/1 2/1 4/1 -2/1 3/1 4/1 3/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test75.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test75.txt deleted file mode 100644 index 50fe97fa383..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test75.txt +++ /dev/null @@ -1,25 +0,0 @@ -3 -2 4 2 0 -2 4 2 0 -0 2 4 2 -4 -2/1 0/1 2/1 2/1 -0/1 2/1 2/1 2/1 -2/1 2/1 2/1 4/1 -2/1 2/1 4/1 2/1 -5 -0/1 2/1 -2/1 0/1 -32/16 32/16 -2/1 4/1 -4/1 2/1 -1 -32/16 32/16 -1 -6 -2/1 0/1 2/1 2/1 -2/1 0/1 2/1 2/1 -0/1 2/1 2/1 2/1 -2/1 2/1 2/1 4/1 -2/1 2/1 2/1 4/1 -2/1 2/1 4/1 2/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test76.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test76.txt deleted file mode 100644 index e33576bb815..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test76.txt +++ /dev/null @@ -1,33 +0,0 @@ -3 -2 4 2 0 -4 4 4 0 -0 2 6 2 -7 -2/1 2/1 2/1 0/1 -0/1 2/1 2/1 2/1 -2/1 4/1 2/1 2/1 -4/1 2/1 4/1 0/1 -2/1 2/1 4/1 2/1 -4/1 4/1 4/1 2/1 -4/1 2/1 6/1 2/1 -8 -0/1 2/1 -2/1 0/1 -48/24 48/24 -2/1 4/1 -4/1 0/1 -96/24 48/24 -4/1 4/1 -6/1 2/1 -2 -48/24 48/24 -96/24 48/24 -1 -7 -2/1 2/1 2/1 0/1 -0/1 2/1 2/1 2/1 -2/1 4/1 2/1 2/1 -4/1 2/1 4/1 0/1 -2/1 2/1 4/1 2/1 -4/1 4/1 4/1 2/1 -4/1 2/1 6/1 2/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test77.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test77.txt deleted file mode 100644 index 52ed98b070e..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test77.txt +++ /dev/null @@ -1,18 +0,0 @@ -2 -0 3 0 0 -0 2 0 0 -2 -0/1 2/1 0/1 0/1 -0/1 3/1 0/1 2/1 -3 -0/1 0/1 -0/1 2/1 -0/1 3/1 -1 -0/1 2/1 -1 -3 -0/1 2/1 0/1 0/1 -0/1 2/1 0/1 0/1 -0/1 3/1 0/1 2/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test78.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test78.txt deleted file mode 100644 index 194577128a5..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test78.txt +++ /dev/null @@ -1,64 +0,0 @@ -6 -1 5 1 0 -1 5 1 2 -4 0 4 4 -4 2 4 4 -0 3 5 3 -0 1 5 1 -14 -1/1 1/1 1/1 0/1 -0/1 1/1 1/1 1/1 -1/1 2/1 1/1 1/1 -1/1 2/1 1/1 3/1 -0/1 3/1 1/1 3/1 -1/1 3/1 1/1 5/1 -4/1 0/1 4/1 1/1 -1/1 1/1 4/1 1/1 -4/1 1/1 4/1 2/1 -4/1 2/1 4/1 3/1 -1/1 3/1 4/1 3/1 -4/1 3/1 4/1 4/1 -4/1 1/1 5/1 1/1 -4/1 3/1 5/1 3/1 -14 -0/1 1/1 -0/1 3/1 -1/1 0/1 -25/25 25/25 -1/1 2/1 -25/25 75/25 -1/1 5/1 -4/1 0/1 -80/20 20/20 -4/1 2/1 -80/20 60/20 -4/1 4/1 -5/1 1/1 -5/1 3/1 -6 -25/25 25/25 -1/1 2/1 -25/25 75/25 -80/20 20/20 -4/1 2/1 -80/20 60/20 -2 -18 -1/1 1/1 1/1 0/1 -0/1 1/1 1/1 1/1 -1/1 2/1 1/1 1/1 -1/1 2/1 1/1 3/1 -1/1 2/1 1/1 3/1 -0/1 3/1 1/1 3/1 -1/1 3/1 1/1 5/1 -1/1 3/1 1/1 5/1 -4/1 0/1 4/1 1/1 -1/1 1/1 4/1 1/1 -4/1 1/1 4/1 2/1 -4/1 2/1 4/1 3/1 -4/1 2/1 4/1 3/1 -1/1 3/1 4/1 3/1 -4/1 3/1 4/1 4/1 -4/1 3/1 4/1 4/1 -4/1 1/1 5/1 1/1 -4/1 3/1 5/1 3/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test79.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test79.txt deleted file mode 100644 index dc9b76b1284..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test79.txt +++ /dev/null @@ -1,34 +0,0 @@ -4 -0 5 0 0 -0 5 0 2 -0 3 3 3 -0 1 3 1 -6 -0/1 1/1 0/1 0/1 -0/1 2/1 0/1 1/1 -0/1 2/1 0/1 3/1 -0/1 3/1 0/1 5/1 -0/1 1/1 3/1 1/1 -0/1 3/1 3/1 3/1 -7 -0/1 0/1 -0/1 1/1 -0/1 2/1 -0/1 3/1 -0/1 5/1 -3/1 1/1 -3/1 3/1 -3 -0/1 1/1 -0/1 2/1 -0/1 3/1 -1 -8 -0/1 1/1 0/1 0/1 -0/1 2/1 0/1 1/1 -0/1 2/1 0/1 3/1 -0/1 2/1 0/1 3/1 -0/1 3/1 0/1 5/1 -0/1 3/1 0/1 5/1 -0/1 1/1 3/1 1/1 -0/1 3/1 3/1 3/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test80.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test80.txt deleted file mode 100644 index 57300a903c3..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test80.txt +++ /dev/null @@ -1,32 +0,0 @@ -8 -0 4 4 4 -0 4 4 4 -4 4 4 0 -4 4 4 0 -0 0 4 0 -0 0 4 0 -0 4 0 0 -0 4 0 0 -4 -0/1 0/1 0/1 4/1 -0/1 0/1 4/1 0/1 -4/1 0/1 4/1 4/1 -0/1 4/1 4/1 4/1 -4 -0/1 0/1 -0/1 4/1 -4/1 0/1 -4/1 4/1 -0 -2 -8 -0/1 0/1 0/1 4/1 -0/1 0/1 0/1 4/1 -0/1 0/1 4/1 0/1 -0/1 0/1 4/1 0/1 -4/1 0/1 4/1 4/1 -4/1 0/1 4/1 4/1 -0/1 4/1 4/1 4/1 -0/1 4/1 4/1 4/1 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test81.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test81.txt deleted file mode 100644 index 4c27222b415..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test81.txt +++ /dev/null @@ -1,50 +0,0 @@ -6 -0 6 6 0 -0 2 6 8 -1 1 6 1 -1 1 6 1 -1 7 6 7 -1 7 6 7 -10 -0/1 2/1 144/72 288/72 -0/1 6/1 144/72 288/72 -1/1 1/1 150/30 30/30 -144/72 288/72 150/30 30/30 -144/72 288/72 150/30 210/30 -1/1 7/1 150/30 210/30 -150/30 30/30 6/1 0/1 -150/30 30/30 6/1 1/1 -150/30 210/30 6/1 7/1 -150/30 210/30 6/1 8/1 -11 -0/1 2/1 -0/1 6/1 -1/1 1/1 -1/1 7/1 -144/72 288/72 -150/30 30/30 -150/30 210/30 -6/1 0/1 -6/1 1/1 -6/1 7/1 -6/1 8/1 -3 -144/72 288/72 -150/30 30/30 -150/30 210/30 -1 -14 -0/1 2/1 144/72 288/72 -0/1 6/1 144/72 288/72 -1/1 1/1 150/30 30/30 -1/1 1/1 150/30 30/30 -144/72 288/72 150/30 30/30 -144/72 288/72 150/30 210/30 -1/1 7/1 150/30 210/30 -1/1 7/1 150/30 210/30 -150/30 30/30 6/1 0/1 -150/30 30/30 6/1 1/1 -150/30 30/30 6/1 1/1 -150/30 210/30 6/1 7/1 -150/30 210/30 6/1 7/1 -150/30 210/30 6/1 8/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test82.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test82.txt deleted file mode 100644 index e4dbeb073c2..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test82.txt +++ /dev/null @@ -1,25 +0,0 @@ -3 -0 4 4 0 -0 4 4 0 --1 2 5 2 -4 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 4/1 0/1 -48/24 48/24 5/1 2/1 -5 --1/1 2/1 -0/1 4/1 -48/24 48/24 -4/1 0/1 -5/1 2/1 -1 -48/24 48/24 -1 -6 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 4/1 0/1 -48/24 48/24 4/1 0/1 -48/24 48/24 5/1 2/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test83.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test83.txt deleted file mode 100644 index 67a74747e52..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test83.txt +++ /dev/null @@ -1,30 +0,0 @@ -5 -0 3 5 5 -0 1 7 0 -0 3 5 1 -0 2 5 1 -0 4 5 5 -5 -0/1 2/1 5/1 1/1 -0/1 3/1 5/1 1/1 -0/1 3/1 5/1 5/1 -0/1 4/1 5/1 5/1 -0/1 1/1 7/1 0/1 -7 -0/1 1/1 -0/1 2/1 -0/1 3/1 -0/1 4/1 -5/1 1/1 -5/1 5/1 -7/1 0/1 -0 -1 -5 -0/1 2/1 5/1 1/1 -0/1 3/1 5/1 1/1 -0/1 3/1 5/1 5/1 -0/1 4/1 5/1 5/1 -0/1 1/1 7/1 0/1 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test84.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test84.txt deleted file mode 100644 index 419bf09b9eb..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test84.txt +++ /dev/null @@ -1,30 +0,0 @@ -4 -0 4 6 0 -0 0 6 4 -3 2 5 4 -3 2 5 0 -6 -0/1 0/1 3/1 2/1 -0/1 4/1 3/1 2/1 -3/1 2/1 5/1 0/1 -3/1 2/1 5/1 4/1 -3/1 2/1 6/1 0/1 -3/1 2/1 6/1 4/1 -7 -0/1 0/1 -0/1 4/1 -3/1 2/1 -5/1 0/1 -5/1 4/1 -6/1 0/1 -6/1 4/1 -1 -3/1 2/1 -1 -6 -0/1 0/1 3/1 2/1 -0/1 4/1 3/1 2/1 -3/1 2/1 5/1 0/1 -3/1 2/1 5/1 4/1 -3/1 2/1 6/1 0/1 -3/1 2/1 6/1 4/1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test85.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test85.txt deleted file mode 100644 index 79d9d1bd8be..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test85.txt +++ /dev/null @@ -1,26 +0,0 @@ -3 -0 0 6 0 -2 0 4 3 -2 0 5 2 -4 -0/1 0/1 2/1 0/1 -2/1 0/1 4/1 3/1 -2/1 0/1 5/1 2/1 -2/1 0/1 6/1 0/1 -5 -0/1 0/1 -2/1 0/1 -4/1 3/1 -5/1 2/1 -6/1 0/1 -1 -2/1 0/1 -1 -4 -0/1 0/1 2/1 0/1 -2/1 0/1 4/1 3/1 -2/1 0/1 5/1 2/1 -2/1 0/1 6/1 0/1 - - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test86.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test86.txt deleted file mode 100644 index bb28d85698c..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test86.txt +++ /dev/null @@ -1,25 +0,0 @@ -3 -0 3 6 3 -3 3 6 1 -3 3 6 0 -4 -0/1 3/1 3/1 3/1 -3/1 3/1 6/1 0/1 -3/1 3/1 6/1 1/1 -3/1 3/1 6/1 3/1 -5 -0/1 3/1 -3/1 3/1 -6/1 0/1 -6/1 1/1 -6/1 3/1 -1 -3/1 3/1 -1 -4 -0/1 3/1 3/1 3/1 -3/1 3/1 6/1 0/1 -3/1 3/1 6/1 1/1 -3/1 3/1 6/1 3/1 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test87.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test87.txt deleted file mode 100644 index 2d84b028ae6..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test87.txt +++ /dev/null @@ -1,24 +0,0 @@ -3 -7 3 0 3 -3 3 5 0 -3 3 6 6 -4 -3/1 3/1 0/1 3/1 -3/1 3/1 5/1 0/1 -3/1 3/1 6/1 6/1 -7/1 3/1 3/1 3/1 -5 -0/1 3/1 -3/1 3/1 -5/1 0/1 -6/1 6/1 -7/1 3/1 -1 -3/1 3/1 -1 -4 -3/1 3/1 0/1 3/1 -3/1 3/1 5/1 0/1 -3/1 3/1 6/1 6/1 -7/1 3/1 3/1 3/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test88.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test88.txt deleted file mode 100644 index 911adaeaab2..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test88.txt +++ /dev/null @@ -1,27 +0,0 @@ -3 -0 4 7 4 -1 0 5 8 -3 4 6 6 -5 -1/1 0/1 3/1 4/1 -0/1 4/1 3/1 4/1 -3/1 4/1 5/1 8/1 -3/1 4/1 6/1 6/1 -3/1 4/1 7/1 4/1 -6 -0/1 4/1 -1/1 0/1 -3/1 4/1 -5/1 8/1 -6/1 6/1 -7/1 4/1 -1 -3/1 4/1 -1 -5 -1/1 0/1 3/1 4/1 -0/1 4/1 3/1 4/1 -3/1 4/1 5/1 8/1 -3/1 4/1 6/1 6/1 -3/1 4/1 7/1 4/1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base index c6c8af71e9a..2612c02c50f 100755 --- a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base +++ b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base @@ -78,12 +78,11 @@ compile() compile_and_run() { - echo "---$1---" # running general test if compile $1 $2 $3 ; then - echo " compilation of $1 succeeded" >> $ERRORFILE + echo " compilation of $1 succeeded" >> $ERRORFILE SUBCURVES="" run $1 $2 $3 $4 SUBCURVES="subcurves" @@ -93,14 +92,13 @@ compile_and_run() fi eval "2>&1 ${MAKE_CMD} CGAL_MAKEFILE=$CGAL_MAKEFILE clean > /dev/null " - } clean_tests() { if [ "${TEST_WITH_CMAKE}" != "FALSE" ]; then # - # The clean target generated by CMake under cygwin + # The clean target generated by CMake under cygwin # always fails for some reason # if ! ( uname | grep -q "CYGWIN" ) ; then @@ -117,7 +115,7 @@ compile_and_run_sweep() # running general test if compile $1 $2 $3 ; then - echo " compilation of $1 succeeded" >> $ERRORFILE + echo " compilation of $1 succeeded" >> $ERRORFILE run $1 $2 $3 $4 else echo " ERROR: compilation of $1 failed" >> $ERRORFILE @@ -134,7 +132,7 @@ run() for DATAFILE in ${datafiles} do if [ -d $DATAFILE ]; then - echo "$DATEFILE is a directory" + echo "$DATEFILE is a directory" continue fi @@ -158,7 +156,6 @@ run() echo " ERROR: could not execute $1 $DATAFILE $SUBCURVES" >> $ERRORFILE fi done - } run_io() @@ -178,20 +175,20 @@ run_io() for DATAFILE in ${datafiles} do - + if [ -d $DATAFILE ]; then - echo "$DATEFILE is a directory" + echo "$DATEFILE is a directory" continue fi - + IOFILE="${iofiles}`basename ${DATAFILE}`_${SUFFIO}" echo $IOFILE - + if [ -f $1 ] ; then rm -f arr.txt - + DATANAME=`basename $DATAFILE` - IONAME=`basename $IOFILE` + IONAME=`basename $IOFILE` OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$PLATFORM.$2 rm -f $OUTPUTFILE @@ -246,6 +243,7 @@ TRAP=1 # Trapezoidal decomposition NAIVE=2 WALK=3 - #run the test for new sweep +#run the test for new sweep (compile_and_run_sweep test_sweep $NAIVE $CGAL_SEGMENT_TRAITS "DATA/segments_tight") (compile_and_run_sweep test_sweep_conic $NAIVE $CGAL_CONIC_TRAITS "DATA/conics") +(compile_and_run_sweep test_sweep $NAIVE $CGAL_POLYLINE_TRAITS "DATA/polylines diff --git a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_with_cmake b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_with_cmake index 8c72a52e332..60483af61d6 100755 --- a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_with_cmake +++ b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_with_cmake @@ -1,4 +1,3 @@ #! /bin/bash ./cgal_test_base -cmake - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con01.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt similarity index 99% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con01.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt index a3464614b95..1ff457efdb1 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con01.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt @@ -8,4 +8,3 @@ e 3 3 7 5 4 5 10 5 {1*x^2 + 1*y^2 + 0*xy + -14*x + -10*y + 65} : (4.66667,6.88562) --cw--> (10,5) 5 1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con02.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt similarity index 99% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con02.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt index f3ca4fd2817..c404b51caa1 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con02.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt @@ -10,5 +10,3 @@ e 3 3 4 9 7 9 1 9 {1*x^2 + 1*y^2 + 0*xy + -8*x + -18*y + 88} : (7,9) --cw--> (5.45237,6.375) 6 2 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con03.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt similarity index 99% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con03.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt index 6ed5fcbab23..599a66f9b14 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con03.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt @@ -12,8 +12,3 @@ f 3 3 4 9 {1*x^2 + 1*y^2 + 0*xy + -8*x + -18*y + 88} : (1,9) --cw--> (7,9) 6 2 - - - - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con04.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt similarity index 99% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con04.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt index d9a9875cdeb..eb6a5c18711 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con04.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt @@ -12,6 +12,4 @@ f 1 1 3 2 {1*x^2 + 1*y^2 + 0*xy + -6*x + -4*y + 12} : (4,2) --cw--> (2,2) {1*x^2 + 1*y^2 + 0*xy + -6*x + -4*y + 12} : (2,2) --cw--> (4,2) 6 -0 - - +1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con05.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt similarity index 99% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con05.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt index 224bbc2397a..e68e06cb488 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con05.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt @@ -12,7 +12,3 @@ f 3 3 4 9 {1*x^2 + 1*y^2 + 0*xy + -8*x + -18*y + 88} : (1,9) --cw--> (7,9) 6 2 - - - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con06.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt similarity index 99% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con06.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt index 59ac8c5f663..f82851db1c1 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con06.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt @@ -14,4 +14,3 @@ f 1 1 1 1 {1*x^2 + 1*y^2 + 0*xy + -4*x + 0*y + 3} : (2,1) --cw--> (3,0) 5 3 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con07.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt similarity index 99% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con07.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt index 2b2253b5594..e884bd40154 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con07.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt @@ -10,4 +10,3 @@ f 2 2 2 2 {1*x^2 + 1*y^2 + 0*xy + -4*x + -4*y + 4} : (0,2) --cw--> (4,2) 5 1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con08.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt similarity index 99% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con08.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt index 54aae8118a0..63063346910 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con08.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt @@ -26,5 +26,3 @@ f 3 1 0 0 {4*x^2 + 25*y^2 + 0*xy + -16*x + 0*y + -84} : (2.75552,1.97704) --cw--> (7,0) 10 6 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con09.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt similarity index 99% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con09.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt index 543d1cff813..6afc8ee809c 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con09.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt @@ -121,5 +121,4 @@ f 1 1 -4 0 {1*x^2 + 1*y^2 + 0*xy + -8*x + 0*y + 0} : (8,0) --cw--> (4.5,-3.96863) {1*x^2 + 1*y^2 + 0*xy + -8*x + 0*y + 0} : (4.5,3.96863) --cw--> (8,0) 59 -34 - +41 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con10.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt similarity index 99% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con10.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt index 51c9e3ffb2a..d5f29cc3101 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con10.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt @@ -18,5 +18,4 @@ s 7 -2 3 2 {1*x^2 + 1*y^2 + 0*xy + -14*x + 2*y + 49} : (8,-1) --cw--> (7,-2) {1*x^2 + 1*y^2 + 0*xy + -14*x + 2*y + 49} : (7,0) --cw--> (8,-1) 8 -7 - +5 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap.txt b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap.txt new file mode 100644 index 00000000000..93d9d322792 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap.txt @@ -0,0 +1,30 @@ +# No. of input polylines followed by polylines +2 +5 0 0 20 0 30 20 40 0 60 0 +6 10 10 25 10 30 20 40 0 50 0 50 -10 +# No. of output polylines followed by polylines +5 +3 0 0 20 0 25 10 +2 10 10 25 10 +2 50 0 50 -10 +4 25 10 30 20 40 0 50 0 +2 50 0 60 0 +# No. of output points followed by points +6 +0 0 +10 10 +25 10 +50 -10 +50 0 +60 0 +# No. of intersection points followed by points +1 +50 0 +# No. of output polylines with overlaps followed by polylines +6 +3 0 0 20 0 25 10 +2 10 10 25 10 +2 50 0 50 -10 +4 25 10 30 20 40 0 50 0 +4 25 10 30 20 40 0 50 0 +2 50 0 60 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap2 b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap2 similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap2 rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/closed_polyline b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/closed_polyline similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/closed_polyline rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/closed_polyline diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/collinears b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/collinears similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/collinears rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/collinears diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/edge_vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/edge_vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/edge_vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/edge_vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/endpoint_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/endpoint_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/endpoint_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/endpoint_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/partial_overlap b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/partial_overlap similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/partial_overlap rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/partial_overlap diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/partial_overlap2 b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/partial_overlap2 similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/partial_overlap2 rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/partial_overlap2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/segment_overlap b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/segment_overlap similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/segment_overlap rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/segment_overlap diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/self_cut b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/self_cut similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/self_cut rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/self_cut diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/simple_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/simple_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/simple_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/simple_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test00.txt b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test00.txt new file mode 100644 index 00000000000..d2ae0552ae7 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test00.txt @@ -0,0 +1,55 @@ +# No. of input polylines followed by polylines +4 +3 0 1 1 0 4 0 +3 1 1 2 0 8 0 +3 1 2 3 0 6 0 +3 4 1 5 0 7 0 +# No. of output polylines followed by polylines +10 +3 0 1 1 0 2 0 +2 1 1 2 0 +2 2 0 3 0 +2 1 2 3 0 +2 3 0 4 0 +2 4 0 5 0 +2 4 1 5 0 +2 5 0 6 0 +2 6 0 7 0 +2 7 0 8 0 +# No. of output points followed by points +11 +0 1 +1 1 +1 2 +2 0 +3 0 +4 0 +4 1 +5 0 +6 0 +7 0 +8 0 +# No. of intersection points followed by points +3 +4 0 +6 0 +7 0 +# No. of output polylines with overlaps followed by polylines +17 +3 0 1 1 0 2 0 +2 1 1 2 0 +2 2 0 3 0 +2 2 0 3 0 +2 1 2 3 0 +2 3 0 4 0 +2 3 0 4 0 +2 3 0 4 0 +2 4 0 5 0 +2 4 0 5 0 +2 4 1 5 0 +2 5 0 6 0 +2 5 0 6 0 +2 5 0 6 0 +2 6 0 7 0 +2 6 0 7 0 +2 7 0 8 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/total_overlap b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/total_overlap similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/total_overlap rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/total_overlap diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/triangle b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/triangle similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/triangle rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/triangle diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/two_segments b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/two_segments similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/two_segments rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/two_segments diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/vertical_segment b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/vertical_segment similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/vertical_segment rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/vertical_segment diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/edge_vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/edge_vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/edge_vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/edge_vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/segs_and_circles b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/segs_and_circles similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/segs_and_circles rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/segs_and_circles diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/simple_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/simple_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/simple_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/simple_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/triangle b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/triangle similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/triangle rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/triangle diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/two_segments b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/two_segments similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/two_segments rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/two_segments diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/vertical_segment b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/vertical_segment similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/vertical_segment rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/vertical_segment diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/H_degeneracy b/Surface_sweep_2/test/Surface_sweep_2/data/segments/H_degeneracy similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/H_degeneracy rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/H_degeneracy diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/edge_vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segments/edge_vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/edge_vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/edge_vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/simple_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segments/simple_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/simple_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/simple_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/star_4 b/Surface_sweep_2/test/Surface_sweep_2/data/segments/star_4 similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/star_4 rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/star_4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/triangle b/Surface_sweep_2/test/Surface_sweep_2/data/segments/triangle similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/triangle rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/triangle diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/two_segments b/Surface_sweep_2/test/Surface_sweep_2/data/segments/two_segments similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/two_segments rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/two_segments diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segments/vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/vertical_segment b/Surface_sweep_2/test/Surface_sweep_2/data/segments/vertical_segment similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/vertical_segment rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/vertical_segment diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test00.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test00.txt new file mode 100644 index 00000000000..7d48df57242 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test00.txt @@ -0,0 +1,27 @@ +# No. of input segments followed by segments +2 +-1 1 1 -1 +1 1 -1 -1 +# No. of output segments followed by segments +4 +0 0 -1 -1 +-1 1 0 0 +0 0 1 -1 +1 1 0 0 +# No. of output points followed by points +5 +-1 -1 +-1 1 +0 0 +1 -1 +1 1 +# No. of intersection points followed by points +1 +0 0 +# No of faces: 1 +# No. of output segments with overlaps followed by segments +4 +0 0 -1 -1 +-1 1 0 0 +0 0 1 -1 +1 1 0 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test01.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test01.txt new file mode 100644 index 00000000000..b5e69de0242 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test01.txt @@ -0,0 +1,50 @@ +4 +4 6 3 0 +1 3 5 1 +5 0 1 2 +1 0 3 4 +12 +1 0 36/20 32/20 +36/20 32/20 1 2 +36/20 32/20 44/20 48/20 +1 3 44/20 48/20 +44/20 48/20 3 4 +82/26 24/26 3 0 +82/26 24/26 36/20 32/20 +86/26 48/26 82/26 24/26 +44/20 48/20 86/26 48/26 +4 6 86/26 48/26 +5 0 82/26 24/26 +86/26 48/26 5 1 +12 +1 0 +1 2 +1 3 +36/20 32/20 +44/20 48/20 +3 0 +3 4 +82/26 24/26 +86/26 48/26 +4 6 +5 0 +5 1 +4 +36/20 32/20 +44/20 48/20 +82/26 24/26 +86/26 48/26 +# No. of faces: 2 +12 +1 0 36/20 32/20 +36/20 32/20 1 2 +36/20 32/20 44/20 48/20 +1 3 44/20 48/20 +44/20 48/20 3 4 +82/26 24/26 3 0 +82/26 24/26 36/20 32/20 +86/26 48/26 82/26 24/26 +44/20 48/20 86/26 48/26 +4 6 86/26 48/26 +5 0 82/26 24/26 +86/26 48/26 5 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test02.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test02.txt new file mode 100644 index 00000000000..5c505dbd01f --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test02.txt @@ -0,0 +1,33 @@ +3 +0 6 9 5 +7 4 1 3 +5 2 3 7 +7 +0 6 153/43 241/43 +153/43 241/43 3 7 +140/32 114/32 1 3 +140/32 114/32 153/43 241/43 +5 2 140/32 114/32 +7 4 140/32 114/32 +153/43 241/43 9 5 +8 +0 6 +1 3 +3 7 +153/43 241/43 +140/32 114/32 +5 2 +7 4 +9 5 +2 +153/43 241/43 +140/32 114/32 +# No. of faces: 1 +7 +0 6 153/43 241/43 +153/43 241/43 3 7 +140/32 114/32 1 3 +140/32 114/32 153/43 241/43 +5 2 140/32 114/32 +7 4 140/32 114/32 +153/43 241/43 9 5 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test03.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test03.txt new file mode 100644 index 00000000000..15cc231bb28 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test03.txt @@ -0,0 +1,21 @@ +3 +1 1 5 1 +1 2 5 2 +1 3 5 3 +3 +1 1 5 1 +1 2 5 2 +1 3 5 3 +6 +1 1 +1 2 +1 3 +5 1 +5 2 +5 3 +0 +# No. of faces: 1 +3 +1 1 5 1 +1 2 5 2 +1 3 5 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test04.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test04.txt new file mode 100644 index 00000000000..8ea66e0df9f --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test04.txt @@ -0,0 +1,33 @@ +3 +1 4 4 1 +2 2 9 2 +3 7 8 1 +7 +2 2 63/21 42/21 +1 4 63/21 42/21 +63/21 42/21 4 1 +63/21 42/21 301/42 84/42 +3 7 301/42 84/42 +301/42 84/42 8 1 +301/42 84/42 9 2 +8 +1 4 +2 2 +63/21 42/21 +3 7 +4 1 +301/42 84/42 +8 1 +9 2 +2 +63/21 42/21 +301/42 84/42 +# No. of faces: 1 +7 +2 2 63/21 42/21 +1 4 63/21 42/21 +63/21 42/21 4 1 +63/21 42/21 301/42 84/42 +3 7 301/42 84/42 +301/42 84/42 8 1 +301/42 84/42 9 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test05.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test05.txt new file mode 100644 index 00000000000..187550ca704 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test05.txt @@ -0,0 +1,39 @@ +3 +2 7 15 2 +3 2 10 6 +1 3 14 3 +9 +3 2 247/52 156/52 +1 3 247/52 156/52 +247/52 156/52 681/87 414/87 +2 7 681/87 414/87 +681/87 414/87 10 6 +247/52 156/52 806/65 195/65 +681/87 414/87 806/65 195/65 +806/65 195/65 14 3 +806/65 195/65 15 2 +9 +1 3 +2 7 +3 2 +247/52 156/52 +681/87 414/87 +10 6 +806/65 195/65 +14 3 +15 2 +3 +247/52 156/52 +681/87 414/87 +806/65 195/65 +# No. of faces: 2 +9 +3 2 247/52 156/52 +1 3 247/52 156/52 +247/52 156/52 681/87 414/87 +2 7 681/87 414/87 +681/87 414/87 10 6 +247/52 156/52 806/65 195/65 +681/87 414/87 806/65 195/65 +806/65 195/65 14 3 +806/65 195/65 15 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test06.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test06.txt new file mode 100644 index 00000000000..2f9455a5a35 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test06.txt @@ -0,0 +1,60 @@ +6 +12 4 9 4 +12 3 11 3 +14 1 8 6 +7 6 1 1 +6 2 3 7 +5 7 3 5 +14 +60/16 92/16 3 5 +60/16 92/16 3 7 +213/45 185/45 1 1 +213/45 185/45 60/16 92/16 +5 7 60/16 92/16 +6 2 213/45 185/45 +7 6 213/45 185/45 +156/15 4 9 4 +156/15 4 8 6 +58/5 3 11 3 +58/5 3 156/15 4 +12 3 58/5 3 +12 4 156/15 4 +14 1 58/5 3 +16 +1 1 +3 5 +3 7 +60/16 92/16 +213/45 185/45 +5 7 +6 2 +7 6 +8 6 +9 4 +156/15 4 +11 3 +58/5 3 +12 3 +12 4 +14 1 +4 +60/16 92/16 +213/45 185/45 +156/15 4 +58/5 3 +# No. of faces: 1 +14 +60/16 92/16 3 5 +60/16 92/16 3 7 +213/45 185/45 1 1 +213/45 185/45 60/16 92/16 +5 7 60/16 92/16 +6 2 213/45 185/45 +7 6 213/45 185/45 +156/15 4 9 4 +156/15 4 8 6 +58/5 3 11 3 +58/5 3 156/15 4 +12 3 58/5 3 +12 4 156/15 4 +14 1 58/5 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test07.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test07.txt new file mode 100644 index 00000000000..b95f6e3998c --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test07.txt @@ -0,0 +1,22 @@ +4 +5 5 2 3 +7 1 2 3 +7 1 9 4 +5 5 9 4 +4 +5 5 2 3 +7 1 2 3 +7 1 9 4 +5 5 9 4 +4 +2 3 +5 5 +7 1 +9 4 +0 +# No. of faces: 2 +4 +5 5 2 3 +7 1 2 3 +7 1 9 4 +5 5 9 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test08.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test08.txt new file mode 100644 index 00000000000..10db8ae63ea --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test08.txt @@ -0,0 +1,19 @@ +2 +1 2 4 2 +3 0 5 4 +3 +3 0 4 2 +1 2 4 2 +4 2 5 4 +4 +1 2 +3 0 +4 2 +5 4 +1 +4 2 +# No. of faces: 1 +3 +3 0 4 2 +1 2 4 2 +4 2 5 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test09.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test09.txt new file mode 100644 index 00000000000..8e0635e3ca6 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test09.txt @@ -0,0 +1,19 @@ +2 +1 1 7 1 +3 1 5 4 +3 +1 1 3 1 +3 1 5 4 +3 1 7 1 +4 +1 1 +3 1 +5 4 +7 1 +1 +3 1 +# No. of faces: 1 +3 +1 1 3 1 +3 1 5 4 +3 1 7 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test10.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test10.txt new file mode 100644 index 00000000000..47e21732fd6 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test10.txt @@ -0,0 +1,19 @@ +2 +6 1 1 1 +4 -2 3 1 +3 +3 1 1 1 +4 -2 3 1 +6 1 3 1 +4 +1 1 +3 1 +4 -2 +6 1 +1 +3 1 +# No. of faces: 1 +3 +3 1 1 1 +4 -2 3 1 +6 1 3 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test11.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test11.txt new file mode 100644 index 00000000000..e389d4a7db7 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test11.txt @@ -0,0 +1,19 @@ +2 +1 1 3 5 +5 3 2 3 +3 +1 1 2 3 +2 3 3 5 +5 3 2 3 +4 +1 1 +2 3 +3 5 +5 3 +1 +2 3 +# No. of faces: 1 +3 +1 1 2 3 +2 3 3 5 +5 3 2 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test12.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test12.txt new file mode 100644 index 00000000000..4710b27995d --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test12.txt @@ -0,0 +1,27 @@ +3 +2 4 4 1 +7 1 1 1 +1 4 5 4 +5 +1 4 2 4 +4 1 1 1 +2 4 4 1 +2 4 5 4 +7 1 4 1 +6 +1 1 +1 4 +2 4 +4 1 +5 4 +7 1 +2 +2 4 +4 1 +# No. of faces: 1 +5 +1 4 2 4 +4 1 1 1 +2 4 4 1 +2 4 5 4 +7 1 4 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test13.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test13.txt new file mode 100644 index 00000000000..3fad0655447 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test13.txt @@ -0,0 +1,27 @@ +3 +0 2 4 2 +1 5 9 -1 +7 4 3 0 +5 +0 2 4 2 +5 2 3 0 +1 5 5 2 +7 4 5 2 +5 2 9 -1 +7 +0 2 +1 5 +3 0 +4 2 +5 2 +7 4 +9 -1 +1 +5 2 +# No. of faces: 1 +5 +0 2 4 2 +5 2 3 0 +1 5 5 2 +7 4 5 2 +5 2 9 -1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test14.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test14.txt new file mode 100644 index 00000000000..01535344d7c --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test14.txt @@ -0,0 +1,47 @@ +7 +0 2 4 2 +1 5 9 -1 +7 4 3 0 +3 5 5 5 +3 4 5 4 +3 -1 5 -1 +3 -2 5 -2 +9 +0 2 4 2 +3 -2 5 -2 +3 -1 5 -1 +5 2 3 0 +1 5 5 2 +3 4 5 4 +3 5 5 5 +7 4 5 2 +5 2 9 -1 +15 +0 2 +1 5 +3 -2 +3 -1 +3 0 +3 4 +3 5 +4 2 +5 -2 +5 -1 +5 2 +5 4 +5 5 +7 4 +9 -1 +1 +5 2 +# No. of faces: 1 +9 +0 2 4 2 +3 -2 5 -2 +3 -1 5 -1 +5 2 3 0 +1 5 5 2 +3 4 5 4 +3 5 5 5 +7 4 5 2 +5 2 9 -1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test15.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test15.txt new file mode 100644 index 00000000000..f7b36b05432 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test15.txt @@ -0,0 +1,40 @@ +9 +0 0 4 3 +3 -3 5 -1 +3 -3 0 0 +4 -4 5 -1 +4 -4 3 -3 +5 -1 9 -1 +8 2 9 -1 +8 2 5 -1 +4 3 5 -1 +9 +3 -3 0 0 +4 -4 3 -3 +0 0 4 3 +4 -4 5 -1 +3 -3 5 -1 +4 3 5 -1 +8 2 5 -1 +5 -1 9 -1 +8 2 9 -1 +7 +0 0 +3 -3 +4 -4 +4 3 +5 -1 +8 2 +9 -1 +0 +# No. of faces: 4 +9 +3 -3 0 0 +4 -4 3 -3 +0 0 4 3 +4 -4 5 -1 +3 -3 5 -1 +4 3 5 -1 +8 2 5 -1 +5 -1 9 -1 +8 2 9 -1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test16.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test16.txt new file mode 100644 index 00000000000..3bc6a8ce547 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test16.txt @@ -0,0 +1,57 @@ +7 +6 3 0 3 +2 0 4 6 +4 0 2 6 +5 1 1 5 +5 5 1 1 +0 2 6 4 +1 4 5 2 +14 +2 0 3 3 +3 3 1 1 +0 2 3 3 +3 3 0 3 +1 4 3 3 +3 3 1 5 +3 3 2 6 +4 0 3 3 +3 3 4 6 +5 1 3 3 +3 3 5 2 +5 5 3 3 +6 3 3 3 +3 3 6 4 +15 +0 2 +0 3 +1 1 +1 4 +1 5 +2 0 +2 6 +3 3 +4 0 +4 6 +5 1 +5 2 +5 5 +6 3 +6 4 +1 +3 3 +# No. of faces: 1 +14 +2 0 3 3 +3 3 1 1 +0 2 3 3 +3 3 0 3 +1 4 3 3 +3 3 1 5 +3 3 2 6 +4 0 3 3 +3 3 4 6 +5 1 3 3 +3 3 5 2 +5 5 3 3 +6 3 3 3 +3 3 6 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test17.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test17.txt new file mode 100644 index 00000000000..34351b917ac --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test17.txt @@ -0,0 +1,22 @@ +4 +1 5 0 4 +1 5 2 4 +1 3 0 4 +1 3 2 4 +4 +1 3 0 4 +1 5 0 4 +1 3 2 4 +1 5 2 4 +4 +0 4 +1 3 +1 5 +2 4 +0 +# No. of faces: 2 +4 +1 3 0 4 +1 5 0 4 +1 3 2 4 +1 5 2 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test18.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test18.txt new file mode 100644 index 00000000000..23c2db7d18f --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test18.txt @@ -0,0 +1,27 @@ +3 +0 0 6 0 +0 2 3 2 +2 -1 4 1 +5 +2 -1 3 0 +0 0 3 0 +0 2 3 2 +3 0 4 1 +3 0 6 0 +7 +0 0 +0 2 +2 -1 +3 0 +3 2 +4 1 +6 0 +1 +3 0 +# No. of faces: 1 +5 +2 -1 3 0 +0 0 3 0 +0 2 3 2 +3 0 4 1 +3 0 6 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test19.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test19.txt new file mode 100644 index 00000000000..a6cf55f8025 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test19.txt @@ -0,0 +1,19 @@ +3 +0 0 3 0 +3 0 5 0 +5 0 8 0 +3 +0 0 3 0 +3 0 5 0 +5 0 8 0 +4 +0 0 +3 0 +5 0 +8 0 +0 +# No. of faces: 1 +3 +0 0 3 0 +3 0 5 0 +5 0 8 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test20.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test20.txt new file mode 100644 index 00000000000..2c261cad7d1 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test20.txt @@ -0,0 +1,26 @@ +3 +1 2 4 2 +3 0 5 4 +3 4 5 0 +5 +3 0 4 2 +1 2 4 2 +3 4 4 2 +4 2 5 0 +4 2 5 4 +6 +1 2 +3 0 +3 4 +4 2 +5 0 +5 4 +1 +4 2 +# No. of faces: 1 +5 +3 0 4 2 +1 2 4 2 +3 4 4 2 +4 2 5 0 +4 2 5 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test21.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test21.txt new file mode 100644 index 00000000000..ad795ac780e --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test21.txt @@ -0,0 +1,29 @@ +3 +6 1 1 6 +9 3 0 3 +2 1 6 5 +6 +2 1 4 3 +4 3 0 3 +4 3 1 6 +6 1 4 3 +4 3 6 5 +9 3 4 3 +7 +0 3 +1 6 +2 1 +4 3 +6 1 +6 5 +9 3 +1 +4 3 +# No. of faces: 1 +6 +2 1 4 3 +4 3 0 3 +4 3 1 6 +6 1 4 3 +4 3 6 5 +9 3 4 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test22.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test22.txt new file mode 100644 index 00000000000..e6ac95bc017 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test22.txt @@ -0,0 +1,27 @@ +5 +0 0 1 1 +0 0 2 3 +0 0 9 8 +0 0 -1 -3 +0 0 -3 4 +5 +0 0 -1 -3 +0 0 -3 4 +0 0 1 1 +0 0 2 3 +0 0 9 8 +6 +-3 4 +-1 -3 +0 0 +1 1 +2 3 +9 8 +0 +# No. of faces: 1 +5 +0 0 -1 -3 +0 0 -3 4 +0 0 1 1 +0 0 2 3 +0 0 9 8 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test23.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test23.txt new file mode 100644 index 00000000000..633acf5e467 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test23.txt @@ -0,0 +1,23 @@ +4 +1 2 0 0 +3 2 0 0 +0 0 4 0 +0 0 2 -2 +4 +1 2 0 0 +0 0 2 -2 +3 2 0 0 +0 0 4 0 +5 +0 0 +1 2 +2 -2 +3 2 +4 0 +0 +# No. of faces: 1 +4 +1 2 0 0 +0 0 2 -2 +3 2 0 0 +0 0 4 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test24.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test24.txt new file mode 100644 index 00000000000..c1b674a8f00 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test24.txt @@ -0,0 +1,23 @@ +4 +-3 2 0 0 +-3 0 0 0 +-2 -2 0 0 +0 0 -2 -4 +4 +0 0 -2 -4 +-2 -2 0 0 +-3 0 0 0 +-3 2 0 0 +5 +-3 0 +-3 2 +-2 -4 +-2 -2 +0 0 +0 +# No. of faces: 1 +4 +0 0 -2 -4 +-2 -2 0 0 +-3 0 0 0 +-3 2 0 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test25.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test25.txt new file mode 100644 index 00000000000..c679dad3f34 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test25.txt @@ -0,0 +1,23 @@ +4 +0 0 3 3 +3 3 6 6 +6 0 3 3 +0 6 3 3 +4 +0 0 3 3 +0 6 3 3 +6 0 3 3 +3 3 6 6 +5 +0 0 +0 6 +3 3 +6 0 +6 6 +0 +# No. of faces: 1 +4 +0 0 3 3 +0 6 3 3 +6 0 3 3 +3 3 6 6 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test26.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test26.txt new file mode 100644 index 00000000000..2cfe803179b --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test26.txt @@ -0,0 +1,42 @@ +7 +0 7 2 5 +0 5 2 5 +2 4 4 4 +2 4 4 2 +2 7 4 9 +0 1 4 1 +1 4 3 6 +8 +1 4 2 5 +0 5 2 5 +0 7 2 5 +2 5 3 6 +0 1 4 1 +2 4 4 2 +2 4 4 4 +2 7 4 9 +12 +0 1 +0 5 +0 7 +1 4 +2 4 +2 5 +2 7 +3 6 +4 1 +4 2 +4 4 +4 9 +1 +2 5 +# No. of faces: 1 +8 +1 4 2 5 +0 5 2 5 +0 7 2 5 +2 5 3 6 +0 1 4 1 +2 4 4 2 +2 4 4 4 +2 7 4 9 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test27.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test27.txt new file mode 100644 index 00000000000..09d93ba7d9b --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test27.txt @@ -0,0 +1,37 @@ +8 +1 5 0 4 +1 5 2 4 +1 3 0 4 +1 3 2 4 +0 2 1 3 +0 2 1 1 +1 3 2 2 +1 1 2 2 +8 +0 2 1 1 +0 2 1 3 +1 3 0 4 +1 5 0 4 +1 1 2 2 +1 3 2 2 +1 3 2 4 +1 5 2 4 +7 +0 2 +0 4 +1 1 +1 3 +1 5 +2 2 +2 4 +0 +# No. of faces: 3 +8 +0 2 1 1 +0 2 1 3 +1 3 0 4 +1 5 0 4 +1 1 2 2 +1 3 2 2 +1 3 2 4 +1 5 2 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test28.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test28.txt new file mode 100644 index 00000000000..d945734fca4 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test28.txt @@ -0,0 +1,44 @@ +10 +-1 0 0 1 +0 1 1 2 +0 -1 -1 0 +1 0 0 1 +2 1 1 2 +0 -1 1 0 +1 0 2 1 +1 0 2 -1 +2 1 3 0 +2 -1 3 0 +10 +0 -1 -1 0 +-1 0 0 1 +0 -1 1 0 +1 0 0 1 +0 1 1 2 +1 0 2 -1 +1 0 2 1 +2 1 1 2 +2 -1 3 0 +2 1 3 0 +8 +-1 0 +0 -1 +0 1 +1 0 +1 2 +2 -1 +2 1 +3 0 +0 +# No. of faces: 4 +10 +0 -1 -1 0 +-1 0 0 1 +0 -1 1 0 +1 0 0 1 +0 1 1 2 +1 0 2 -1 +1 0 2 1 +2 1 1 2 +2 -1 3 0 +2 1 3 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test29.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test29.txt new file mode 100644 index 00000000000..44a64a0247f --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test29.txt @@ -0,0 +1,26 @@ +3 +0 4 4 0 +0 0 4 4 +2 2 5 2 +5 +0 0 2 2 +0 4 2 2 +2 2 4 0 +2 2 4 4 +2 2 5 2 +6 +0 0 +0 4 +2 2 +4 0 +4 4 +5 2 +1 +2 2 +# No. of faces: 1 +5 +0 0 2 2 +0 4 2 2 +2 2 4 0 +2 2 4 4 +2 2 5 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test30.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test30.txt new file mode 100644 index 00000000000..93f5204f262 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test30.txt @@ -0,0 +1,22 @@ +2 +0 0 5 0 +2 -2 2 3 +4 +2 -2 2 0 +0 0 2 0 +2 0 2 3 +2 0 5 0 +5 +0 0 +2 -2 +2 0 +2 3 +5 0 +1 +2 0 +# No. of faces: 1 +4 +2 -2 2 0 +0 0 2 0 +2 0 2 3 +2 0 5 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test31.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test31.txt new file mode 100644 index 00000000000..42f4208cf9a --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test31.txt @@ -0,0 +1,33 @@ +3 +1 2 3 2 +0 0 5 0 +2 4 2 -2 +7 +2 0 2 -2 +0 0 2 0 +2 2 2 0 +1 2 2 2 +2 4 2 2 +2 2 3 2 +2 0 5 0 +8 +0 0 +1 2 +2 -2 +2 0 +2 2 +2 4 +3 2 +5 0 +2 +2 0 +2 2 +# No. of faces: 1 +7 +2 0 2 -2 +0 0 2 0 +2 2 2 0 +1 2 2 2 +2 4 2 2 +2 2 3 2 +2 0 5 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test32.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test32.txt new file mode 100644 index 00000000000..822e3789c28 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test32.txt @@ -0,0 +1,33 @@ +3 +1 2 3 2 +0 0 5 0 +2 -2 2 4 +7 +2 -2 2 0 +0 0 2 0 +2 0 2 2 +1 2 2 2 +2 2 2 4 +2 2 3 2 +2 0 5 0 +8 +0 0 +1 2 +2 -2 +2 0 +2 2 +2 4 +3 2 +5 0 +2 +2 0 +2 2 +# No. of faces: 1 +7 +2 -2 2 0 +0 0 2 0 +2 0 2 2 +1 2 2 2 +2 2 2 4 +2 2 3 2 +2 0 5 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test33.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test33.txt new file mode 100644 index 00000000000..6db47eaf9ed --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test33.txt @@ -0,0 +1,16 @@ +2 +1 5 1 2 +0 0 3 2 +2 +1 5 1 2 +0 0 3 2 +4 +0 0 +1 2 +1 5 +3 2 +0 +# No. of faces: 1 +2 +1 5 1 2 +0 0 3 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test34.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test34.txt new file mode 100644 index 00000000000..47ced43d85b --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test34.txt @@ -0,0 +1,16 @@ +2 +-1 2 1 4 +0 0 0 2 +2 +0 0 0 2 +-1 2 1 4 +4 +-1 2 +0 0 +0 2 +1 4 +0 +# No. of faces: 1 +2 +0 0 0 2 +-1 2 1 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test35.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test35.txt new file mode 100644 index 00000000000..c8a3dd025bc --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test35.txt @@ -0,0 +1,43 @@ +5 +1 7 3 7 +2 6 2 2 +0 4 4 4 +1 3 3 3 +1 0 3 0 +9 +2 3 2 2 +1 3 2 3 +2 4 2 3 +0 4 2 4 +2 6 2 4 +1 0 3 0 +2 3 3 3 +1 7 3 7 +2 4 4 4 +12 +0 4 +1 0 +1 3 +1 7 +2 2 +2 3 +2 4 +2 6 +3 0 +3 3 +3 7 +4 4 +2 +2 3 +2 4 +# No. of faces: 1 +9 +2 3 2 2 +1 3 2 3 +2 4 2 3 +0 4 2 4 +2 6 2 4 +1 0 3 0 +2 3 3 3 +1 7 3 7 +2 4 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test36.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test36.txt new file mode 100644 index 00000000000..03fbb7e16ea --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test36.txt @@ -0,0 +1,46 @@ +4 +2 0 2 9 +1 7 5 3 +0 4 4 2 +1 2 4 5 +11 +2 0 2 3 +1 2 2 3 +0 4 2 3 +2 3 2 6 +1 7 2 6 +2 6 2 9 +2 3 7/2 9/2 +2 6 7/2 9/2 +2 3 4 2 +7/2 9/2 4 5 +7/2 9/2 5 3 +11 +0 4 +1 2 +1 7 +2 0 +2 3 +72/36 216/36 +2 9 +84/24 108/24 +4 2 +4 5 +5 3 +3 +2 3 +72/36 216/36 +84/24 108/24 +# No. of faces: 2 +11 +2 0 2 3 +1 2 2 3 +0 4 2 3 +2 3 2 6 +1 7 2 6 +2 6 2 9 +2 3 7/2 9/2 +2 6 7/2 9/2 +2 3 4 2 +7/2 9/2 4 5 +7/2 9/2 5 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test37.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test37.txt new file mode 100644 index 00000000000..2c10412d83b --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test37.txt @@ -0,0 +1,55 @@ +5 +0 0 0 3 +0 4 0 6 +-3 2 2 0 +-2 4 1 6 +-1 6 -1 1 +13 +-1 6/5 -1 1 +-3 2 -1 6/5 +-1 14/3 -1 6/5 +-2 4 -1 14/3 +-1 6 -1 14/3 +0 0 0 4/5 +-1 6/5 0 4/5 +0 4/5 0 3 +0 4 0 16/3 +-1 14/3 0 16/3 +0 16/3 0 6 +0 16/3 1 6 +0 4/5 2 0 +14 +-3 2 +-2 4 +-1 1 +-25/25 30/25 +-1 70/15 +-1 6 +0 0 +0 12/15 +0 3 +0 4 +0 32/6 +0 6 +1 6 +2 0 +4 +-25/25 30/25 +-1 70/15 +0 12/15 +0 32/6 +# No. of faces: 1 +13 +-1 6/5 -1 1 +-3 2 -1 6/5 +-1 14/3 -1 6/5 +-2 4 -1 14/3 +-1 6 -1 14/3 +0 0 0 4/5 +-1 6/5 0 4/5 +0 4/5 0 3 +0 4 0 16/3 +-1 14/3 0 16/3 +0 16/3 0 6 +0 16/3 1 6 +0 4/5 2 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test40.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test40.txt new file mode 100644 index 00000000000..2cb778d38b7 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test40.txt @@ -0,0 +1,19 @@ +2 +0 0 0 6 +0 3 3 3 +3 +0 0 0 3 +0 3 0 6 +0 3 3 3 +4 +0 0 +0 3 +0 6 +3 3 +1 +0 3 +# No. of faces: 1 +3 +0 0 0 3 +0 3 0 6 +0 3 3 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test41.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test41.txt new file mode 100644 index 00000000000..f9cefcc2116 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test41.txt @@ -0,0 +1,19 @@ +2 +-3 3 0 3 +0 0 0 6 +3 +0 0 0 3 +-3 3 0 3 +0 3 0 6 +4 +-3 3 +0 0 +0 3 +0 6 +1 +0 3 +# No. of faces: 1 +3 +0 0 0 3 +-3 3 0 3 +0 3 0 6 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test42.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test42.txt new file mode 100644 index 00000000000..4cfeb604b7f --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test42.txt @@ -0,0 +1,23 @@ +3 +0 0 0 4 +-2 2 0 2 +0 2 2 2 +4 +0 0 0 2 +-2 2 0 2 +0 2 0 4 +0 2 2 2 +5 +-2 2 +0 0 +0 2 +0 4 +2 2 +1 +0 2 +# No. of faces: 1 +4 +0 0 0 2 +-2 2 0 2 +0 2 0 4 +0 2 2 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test43.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test43.txt new file mode 100644 index 00000000000..90afe463752 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test43.txt @@ -0,0 +1,15 @@ +2 +0 5 4 5 +4 5 4 1 +2 +4 5 4 1 +0 5 4 5 +3 +0 5 +4 1 +4 5 +0 +# No. of faces: 1 +2 +4 5 4 1 +0 5 4 5 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test44.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test44.txt new file mode 100644 index 00000000000..19a28bae19d --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test44.txt @@ -0,0 +1,22 @@ +4 +0 4 4 4 +4 4 4 0 +0 0 4 0 +0 4 0 0 +4 +0 4 0 0 +0 0 4 0 +4 4 4 0 +0 4 4 4 +4 +0 0 +0 4 +4 0 +4 4 +0 +# No. of faces: 2 +4 +0 4 0 0 +0 0 4 0 +4 4 4 0 +0 4 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test45.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test45.txt new file mode 100644 index 00000000000..24188d25fa0 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test45.txt @@ -0,0 +1,15 @@ +2 +0 0 4 0 +0 4 0 0 +2 +0 4 0 0 +0 0 4 0 +3 +0 0 +0 4 +4 0 +0 +# No. of faces: 1 +2 +0 4 0 0 +0 0 4 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test46.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test46.txt new file mode 100644 index 00000000000..512151f3428 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test46.txt @@ -0,0 +1,21 @@ +3 +0 6 2 6 +2 5 2 2 +2 1 4 1 +3 +2 5 2 2 +0 6 2 6 +2 1 4 1 +6 +0 6 +2 1 +2 2 +2 5 +2 6 +4 1 +0 +# No. of faces: 1 +3 +2 5 2 2 +0 6 2 6 +2 1 4 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test47.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test47.txt new file mode 100644 index 00000000000..1624ab36537 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test47.txt @@ -0,0 +1,19 @@ +2 +2 0 2 3 +4 0 0 0 +3 +2 0 0 0 +2 0 2 3 +4 0 2 0 +4 +0 0 +2 0 +2 3 +4 0 +1 +2 0 +# No. of faces: 1 +3 +2 0 0 0 +2 0 2 3 +4 0 2 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test48.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test48.txt new file mode 100644 index 00000000000..9884d9b633f --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test48.txt @@ -0,0 +1,32 @@ +4 +0 0 5 0 +2 3 2 0 +7 3 12 3 +9 3 9 0 +6 +0 0 2 0 +2 3 2 0 +2 0 5 0 +9 3 9 0 +7 3 9 3 +9 3 12 3 +8 +0 0 +2 0 +2 3 +5 0 +7 3 +9 0 +9 3 +12 3 +2 +2 0 +9 3 +# No. of faces: 1 +6 +0 0 2 0 +2 3 2 0 +2 0 5 0 +9 3 9 0 +7 3 9 3 +9 3 12 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test49.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test49.txt new file mode 100644 index 00000000000..937d78e447e --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test49.txt @@ -0,0 +1,15 @@ +2 +0 0 4 0 +4 0 4 4 +2 +0 0 4 0 +4 0 4 4 +3 +0 0 +4 0 +4 4 +0 +# No. of faces: 1 +2 +0 0 4 0 +4 0 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test50.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test50.txt new file mode 100644 index 00000000000..11d3fd8a787 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test50.txt @@ -0,0 +1,31 @@ +5 +4 7 8 7 +8 7 8 5 +5 5 8 5 +8 6 9 7 +8 6 9 5 +6 +5 5 8 5 +8 6 8 5 +8 7 8 6 +4 7 8 7 +8 6 9 5 +8 6 9 7 +7 +4 7 +5 5 +8 5 +8 6 +8 7 +9 5 +9 7 +1 +8 6 +# No. of faces: 1 +6 +5 5 8 5 +8 6 8 5 +8 7 8 6 +4 7 8 7 +8 6 9 5 +8 6 9 7 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test51.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test51.txt new file mode 100644 index 00000000000..0acf5053818 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test51.txt @@ -0,0 +1,118 @@ +16 +2 4 2 0 +2 6 2 10 +6 8 6 4 +8 7 8 5 +0 8 2 8 +4 7 8 7 +0 6 6 6 +8 5 5 5 +2 3 4 3 +1 7 4 10 +6 6 0 3 +0 1 3 4 +9 7 8 6 +9 5 8 6 +2 0 6 4 +2 10 6 8 +30 +2 3 2 0 +0 1 2 3 +2 4 2 3 +2 4 0 3 +0 6 2 6 +2 6 2 8 +1 7 2 8 +0 8 2 8 +2 8 2 10 +2 3 3 4 +2 8 10/3 28/3 +2 10 10/3 28/3 +2 3 4 3 +10/3 28/3 4 10 +2 0 6 4 +6 5 6 4 +6 5 5 5 +6 6 6 5 +6 6 2 4 +2 6 6 6 +6 7 6 6 +4 7 6 7 +6 8 6 7 +10/3 28/3 6 8 +8 5 6 5 +8 6 8 5 +8 7 8 6 +6 7 8 7 +9 5 8 6 +9 7 8 6 +27 +0 1 +0 3 +0 6 +0 8 +1 7 +2 0 +2 3 +2 4 +2 6 +2 8 +2 10 +3 4 +60/18 168/18 +4 3 +4 7 +4 10 +5 5 +6 4 +6 5 +6 6 +6 7 +6 8 +8 5 +8 6 +8 7 +9 5 +9 7 +9 +2 3 +2 4 +2 6 +2 8 +60/18 168/18 +6 5 +6 6 +6 7 +8 6 +# No. of faces: 5 +30 +2 3 2 0 +0 1 2 3 +2 4 2 3 +2 4 0 3 +0 6 2 6 +2 6 2 8 +1 7 2 8 +0 8 2 8 +2 8 2 10 +2 3 3 4 +2 8 10/3 28/3 +2 10 10/3 28/3 +2 3 4 3 +10/3 28/3 4 10 +2 0 6 4 +6 5 6 4 +6 5 5 5 +6 6 6 5 +6 6 2 4 +2 6 6 6 +6 7 6 6 +4 7 6 7 +6 8 6 7 +10/3 28/3 6 8 +8 5 6 5 +8 6 8 5 +8 7 8 6 +6 7 8 7 +9 5 8 6 +9 7 8 6 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test52.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test52.txt new file mode 100644 index 00000000000..e54693b507c --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test52.txt @@ -0,0 +1,29 @@ +3 +0 4 4 0 +0 0 4 4 +2 5 2 -1 +6 +2 2 2 -1 +0 0 2 2 +0 4 2 2 +2 5 2 2 +2 2 4 0 +2 2 4 4 +7 +0 0 +0 4 +2 -1 +64/32 64/32 +2 5 +4 0 +4 4 +1 +64/32 64/32 +# No. of faces: 1 +6 +2 2 2 -1 +0 0 2 2 +0 4 2 2 +2 5 2 2 +2 2 4 0 +2 2 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test53.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test53.txt new file mode 100644 index 00000000000..03bc28fe6ca --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test53.txt @@ -0,0 +1,19 @@ +3 +0 5 0 3 +0 3 0 2 +0 2 0 0 +3 +0 2 0 0 +0 3 0 2 +0 5 0 3 +4 +0 0 +0 2 +0 3 +0 5 +0 +# No. of faces: 1 +3 +0 2 0 0 +0 3 0 2 +0 5 0 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test54.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test54.txt new file mode 100644 index 00000000000..75d46976285 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test54.txt @@ -0,0 +1,23 @@ +3 +8 7 8 5 +8 6 9 7 +8 6 9 5 +4 +8 6 8 5 +8 7 8 6 +8 6 9 5 +8 6 9 7 +5 +8 5 +8 6 +8 7 +9 5 +9 7 +1 +8 6 +# No. of faces: 1 +4 +8 6 8 5 +8 7 8 6 +8 6 9 5 +8 6 9 7 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test55.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test55.txt new file mode 100644 index 00000000000..f2f078a9329 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test55.txt @@ -0,0 +1,27 @@ +3 +0 0 0 2 +0 1 2 1 +2 0 2 2 +5 +0 0 0 1 +0 1 0 2 +2 0 2 1 +0 1 2 1 +2 1 2 2 +6 +0 0 +0 1 +0 2 +2 0 +2 1 +2 2 +2 +0 1 +2 1 +# No. of faces: 1 +5 +0 0 0 1 +0 1 0 2 +2 0 2 1 +0 1 2 1 +2 1 2 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test56.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test56.txt new file mode 100644 index 00000000000..bac5d28e69c --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test56.txt @@ -0,0 +1,26 @@ +3 +3 0 3 6 +0 1 6 5 +3 3 7 3 +5 +3 0 3 3 +0 1 3 3 +3 3 3 6 +3 3 6 5 +3 3 7 3 +6 +0 1 +3 0 +3 3 +3 6 +6 5 +7 3 +1 +3 3 +# No. of faces: 1 +5 +3 0 3 3 +0 1 3 3 +3 3 3 6 +3 3 6 5 +3 3 7 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test60.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test60.txt new file mode 100644 index 00000000000..580ad875127 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test60.txt @@ -0,0 +1,21 @@ +2 +0 0 4 0 +3 0 7 0 +3 +0 0 3 0 +3 0 4 0 +4 0 7 0 +4 +0 0 +3 0 +4 0 +7 0 +2 +3 0 +4 0 +# No. of faces: 1 +4 +0 0 3 0 +3 0 4 0 +3 0 4 0 +4 0 7 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test61.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test61.txt new file mode 100644 index 00000000000..56f8052dbd5 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test61.txt @@ -0,0 +1,33 @@ +3 +3 0 6 0 +0 0 4 0 +2 0 8 0 +5 +0 0 2 0 +2 0 3 0 +3 0 4 0 +4 0 6 0 +6 0 8 0 +6 +0 0 +2 0 +3 0 +4 0 +6 0 +8 0 +4 +2 0 +3 0 +4 0 +6 0 +# No. of faces: 1 +9 +0 0 2 0 +2 0 3 0 +2 0 3 0 +3 0 4 0 +3 0 4 0 +3 0 4 0 +4 0 6 0 +4 0 6 0 +6 0 8 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test62.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test62.txt new file mode 100644 index 00000000000..a975379f310 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test62.txt @@ -0,0 +1,13 @@ +2 +0 0 3 0 +0 0 3 0 +1 +0 0 3 0 +2 +0 0 +3 0 +0 +# No. of faces: 1 +2 +0 0 3 0 +0 0 3 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test63.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test63.txt new file mode 100644 index 00000000000..0bf64d49d7f --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test63.txt @@ -0,0 +1,25 @@ +4 +0 0 2 0 +3 0 5 0 +0 0 5 0 +2 0 3 0 +3 +0 0 2 0 +2 0 3 0 +3 0 5 0 +4 +0 0 +2 0 +3 0 +5 0 +2 +2 0 +3 0 +# No. of faces: 1 +6 +0 0 2 0 +0 0 2 0 +2 0 3 0 +2 0 3 0 +3 0 5 0 +3 0 5 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test64.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test64.txt new file mode 100644 index 00000000000..b27adefbb3b --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test64.txt @@ -0,0 +1,15 @@ +3 +0 0 6 6 +0 0 6 6 +6 6 0 0 +1 +0 0 6 6 +2 +0 0 +6 6 +0 +# No. of faces: 1 +3 +0 0 6 6 +0 0 6 6 +6 6 0 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test65.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test65.txt new file mode 100644 index 00000000000..d1ebcea2dc1 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test65.txt @@ -0,0 +1,25 @@ +3 +0 0 4 4 +0 0 4 4 +0 4 4 0 +4 +0 0 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 4 +5 +0 0 +0 4 +64/32 64/32 +4 0 +4 4 +1 +64/32 64/32 +# No. of faces: 1 +6 +0 0 64/32 64/32 +0 0 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 4 +64/32 64/32 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test66.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test66.txt new file mode 100644 index 00000000000..420a030dada --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test66.txt @@ -0,0 +1,28 @@ +4 +0 0 4 4 +0 0 4 4 +0 4 4 0 +0 4 4 0 +4 +0 0 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 4 +5 +0 0 +0 4 +64/32 64/32 +4 0 +4 4 +1 +64/32 64/32 +# No. of faces: 1 +8 +0 0 64/32 64/32 +0 0 64/32 64/32 +0 4 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 0 +64/32 64/32 4 4 +64/32 64/32 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test67.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test67.txt new file mode 100644 index 00000000000..cdd01dcd119 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test67.txt @@ -0,0 +1,35 @@ +5 +0 0 4 4 +0 0 4 4 +0 4 4 0 +0 4 4 0 +-1 2 5 2 +6 +0 0 48/24 48/24 +-1 2 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 4 0 +48/24 48/24 4 4 +48/24 48/24 5 2 +7 +-1 2 +0 0 +0 4 +48/24 48/24 +4 0 +4 4 +5 2 +1 +48/24 48/24 +# No. of faces: 1 +10 +0 0 48/24 48/24 +0 0 48/24 48/24 +-1 2 48/24 48/24 +0 4 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 4 0 +48/24 48/24 4 0 +48/24 48/24 4 4 +48/24 48/24 4 4 +48/24 48/24 5 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test68.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test68.txt new file mode 100644 index 00000000000..4d739e20e78 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test68.txt @@ -0,0 +1,48 @@ +6 +0 0 4 4 +0 0 4 4 +0 4 4 0 +0 4 4 0 +-1 2 5 2 +1 1 3 3 +8 +0 0 1 1 +1 1 48/24 48/24 +-1 2 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 3 3 +48/24 48/24 4 0 +3 3 4 4 +48/24 48/24 5 2 +9 +-1 2 +0 0 +0 4 +1 1 +48/24 48/24 +3 3 +4 0 +4 4 +5 2 +3 +1 1 +48/24 48/24 +3 3 +# No. of faces: 1 +16 +0 0 1 1 +0 0 1 1 +1 1 48/24 48/24 +1 1 48/24 48/24 +1 1 48/24 48/24 +-1 2 48/24 48/24 +0 4 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 3 3 +48/24 48/24 3 3 +48/24 48/24 3 3 +48/24 48/24 4 0 +48/24 48/24 4 0 +3 3 4 4 +3 3 4 4 +48/24 48/24 5 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test69.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test69.txt new file mode 100644 index 00000000000..c353837bfed --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test69.txt @@ -0,0 +1,37 @@ +8 +1 1 0 2 +1 1 0 1 +0 0 1 1 +3 2 2 1 +2 1 3 1 +3 0 2 1 +1 1 2 1 +2 1 1 1 +7 +0 0 1 1 +1 1 0 1 +1 1 0 2 +1 1 2 1 +3 0 2 1 +2 1 3 1 +3 2 2 1 +8 +0 0 +0 1 +0 2 +1 1 +2 1 +3 0 +3 1 +3 2 +0 +# No. of faces: 1 +8 +0 0 1 1 +1 1 0 1 +1 1 0 2 +1 1 2 1 +2 1 1 1 +3 0 2 1 +2 1 3 1 +3 2 2 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test70.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test70.txt new file mode 100644 index 00000000000..cfc1576cd41 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test70.txt @@ -0,0 +1,41 @@ +5 +3 0 4 0 +4 0 7 0 +2 0 5 0 +1 0 4 0 +0 0 3 0 +6 +0 0 1 0 +1 0 2 0 +2 0 3 0 +3 0 4 0 +4 0 5 0 +5 0 7 0 +7 +0 0 +1 0 +2 0 +3 0 +4 0 +5 0 +7 0 +5 +1 0 +2 0 +3 0 +4 0 +5 0 +# No. of faces: 1 +12 +0 0 1 0 +1 0 2 0 +1 0 2 0 +2 0 3 0 +2 0 3 0 +2 0 3 0 +3 0 4 0 +3 0 4 0 +3 0 4 0 +4 0 5 0 +4 0 5 0 +5 0 7 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test71.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test71.txt new file mode 100644 index 00000000000..726cdc2d9d4 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test71.txt @@ -0,0 +1,25 @@ +3 +2 4 2 0 +0 2 4 2 +0 2 4 2 +4 +2 2 2 0 +0 2 2 2 +2 4 2 2 +2 2 4 2 +5 +0 2 +2 0 +2 2 +2 4 +4 2 +1 +2 2 +# No. of faces: 1 +6 +2 2 2 0 +0 2 2 2 +0 2 2 2 +2 4 2 2 +2 2 4 2 +2 2 4 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test72.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test72.txt new file mode 100644 index 00000000000..212a77a0f3c --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test72.txt @@ -0,0 +1,81 @@ +13 +0 0 4 4 +0 0 4 4 +0 4 4 0 +0 4 4 0 +-1 2 1 2 +5 4 9 0 +5 4 9 0 +5 0 9 4 +4 2 6 2 +9 2 11 2 +10 4 14 0 +10 0 14 4 +10 0 14 4 +15 +-1 2 1 2 +0 0 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 4 +4 2 6 2 +5 0 224/32 64/32 +5 4 224/32 64/32 +224/32 64/32 9 0 +224/32 64/32 9 4 +9 2 11 2 +10 0 384/32 64/32 +10 4 384/32 64/32 +384/32 64/32 14 0 +384/32 64/32 14 4 +21 +-1 2 +0 0 +0 4 +1 2 +64/32 64/32 +4 0 +4 2 +4 4 +5 0 +5 4 +6 2 +224/32 64/32 +9 0 +9 2 +9 4 +10 0 +10 4 +11 2 +384/32 64/32 +14 0 +14 4 +3 +64/32 64/32 +224/32 64/32 +384/32 64/32 +# No. of faces: 1 +23 +-1 2 1 2 +0 0 64/32 64/32 +0 0 64/32 64/32 +0 4 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 0 +64/32 64/32 4 4 +64/32 64/32 4 4 +4 2 6 2 +5 0 224/32 64/32 +5 4 224/32 64/32 +5 4 224/32 64/32 +224/32 64/32 9 0 +224/32 64/32 9 0 +224/32 64/32 9 4 +9 2 11 2 +10 0 384/32 64/32 +10 0 384/32 64/32 +10 4 384/32 64/32 +384/32 64/32 14 0 +384/32 64/32 14 4 +384/32 64/32 14 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test73.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test73.txt new file mode 100644 index 00000000000..5e2b5aafab2 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test73.txt @@ -0,0 +1,21 @@ +2 +3 0 3 4 +3 2 3 7 +3 +3 0 3 2 +3 2 3 4 +3 4 3 7 +4 +3 0 +3 2 +3 4 +3 7 +2 +3 2 +3 4 +# No. of faces: 1 +4 +3 0 3 2 +3 2 3 4 +3 2 3 4 +3 4 3 7 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test74.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test74.txt new file mode 100644 index 00000000000..c48b428b791 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test74.txt @@ -0,0 +1,33 @@ +3 +2 7 2 2 +2 4 2 0 +0 3 4 3 +6 +2 2 2 0 +2 2 2 3 +0 3 2 3 +2 3 2 4 +2 7 2 4 +2 3 4 3 +7 +0 3 +2 0 +2 2 +2 3 +2 4 +2 7 +4 3 +3 +2 2 +2 3 +2 4 +# No. of faces: 1 +8 +2 2 2 0 +2 2 2 3 +2 2 2 3 +0 3 2 3 +2 3 2 4 +2 3 2 4 +2 7 2 4 +2 3 4 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test75.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test75.txt new file mode 100644 index 00000000000..2b7af6f80e7 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test75.txt @@ -0,0 +1,25 @@ +3 +2 4 2 0 +2 4 2 0 +0 2 4 2 +4 +2 0 2 2 +0 2 2 2 +2 2 2 4 +2 2 4 2 +5 +0 2 +2 0 +2 2 +2 4 +4 2 +1 +2 2 +# No. of faces: 1 +6 +2 0 2 2 +2 0 2 2 +0 2 2 2 +2 2 2 4 +2 2 2 4 +2 2 4 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test76.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test76.txt new file mode 100644 index 00000000000..97bfc5d24fd --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test76.txt @@ -0,0 +1,33 @@ +3 +2 4 2 0 +4 4 4 0 +0 2 6 2 +7 +2 2 2 0 +0 2 2 2 +2 4 2 2 +4 2 4 0 +2 2 4 2 +4 4 4 2 +4 2 6 2 +8 +0 2 +2 0 +48/24 48/24 +2 4 +4 0 +96/24 48/24 +4 4 +6 2 +2 +48/24 48/24 +96/24 48/24 +# No. of faces: 1 +7 +2 2 2 0 +0 2 2 2 +2 4 2 2 +4 2 4 0 +2 2 4 2 +4 4 4 2 +4 2 6 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test77.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test77.txt new file mode 100644 index 00000000000..b3ec36e6744 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test77.txt @@ -0,0 +1,17 @@ +2 +0 3 0 0 +0 2 0 0 +2 +0 2 0 0 +0 3 0 2 +3 +0 0 +0 2 +0 3 +1 +0 2 +# No. of faces: 1 +3 +0 2 0 0 +0 2 0 0 +0 3 0 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test78.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test78.txt new file mode 100644 index 00000000000..a91fe60a739 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test78.txt @@ -0,0 +1,64 @@ +6 +1 5 1 0 +1 5 1 2 +4 0 4 4 +4 2 4 4 +0 3 5 3 +0 1 5 1 +14 +1 1 1 0 +0 1 1 1 +1 2 1 1 +1 2 1 3 +0 3 1 3 +1 3 1 5 +4 0 4 1 +1 1 4 1 +4 1 4 2 +4 2 4 3 +1 3 4 3 +4 3 4 4 +4 1 5 1 +4 3 5 3 +14 +0 1 +0 3 +1 0 +1 1 +1 2 +1 3 +1 5 +4 0 +4 1 +4 2 +4 3 +4 4 +5 1 +5 3 +6 +1 1 +1 2 +1 3 +4 1 +4 2 +4 3 +# No. of faces: 2 +18 +1 1 1 0 +0 1 1 1 +1 2 1 1 +1 2 1 3 +1 2 1 3 +0 3 1 3 +1 3 1 5 +1 3 1 5 +4 0 4 1 +1 1 4 1 +4 1 4 2 +4 2 4 3 +4 2 4 3 +1 3 4 3 +4 3 4 4 +4 3 4 4 +4 1 5 1 +4 3 5 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test79.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test79.txt new file mode 100644 index 00000000000..9390c7cc608 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test79.txt @@ -0,0 +1,34 @@ +4 +0 5 0 0 +0 5 0 2 +0 3 3 3 +0 1 3 1 +6 +0 1 0 0 +0 2 0 1 +0 2 0 3 +0 3 0 5 +0 1 3 1 +0 3 3 3 +7 +0 0 +0 1 +0 2 +0 3 +0 5 +3 1 +3 3 +3 +0 1 +0 2 +0 3 +# No. of faces: 1 +8 +0 1 0 0 +0 2 0 1 +0 2 0 3 +0 2 0 3 +0 3 0 5 +0 3 0 5 +0 1 3 1 +0 3 3 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test80.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test80.txt new file mode 100644 index 00000000000..3181a33c498 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test80.txt @@ -0,0 +1,30 @@ +8 +0 4 4 4 +0 4 4 4 +4 4 4 0 +4 4 4 0 +0 0 4 0 +0 0 4 0 +0 4 0 0 +0 4 0 0 +4 +0 0 0 4 +0 0 4 0 +4 0 4 4 +0 4 4 4 +4 +0 0 +0 4 +4 0 +4 4 +0 +# No. of faces: 2 +8 +0 0 0 4 +0 0 0 4 +0 0 4 0 +0 0 4 0 +4 0 4 4 +4 0 4 4 +0 4 4 4 +0 4 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test81.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test81.txt new file mode 100644 index 00000000000..4f7bc3a18d5 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test81.txt @@ -0,0 +1,50 @@ +6 +0 6 6 0 +0 2 6 8 +1 1 6 1 +1 1 6 1 +1 7 6 7 +1 7 6 7 +10 +0 2 2 4 +0 6 2 4 +1 1 5 1 +2 4 5 1 +2 4 5 7 +1 7 5 7 +5 1 6 0 +5 1 6 1 +5 7 6 7 +5 7 6 8 +11 +0 2 +0 6 +1 1 +1 7 +2 4 +5 1 +5 7 +6 0 +6 1 +6 7 +6 8 +3 +2 4 +5 1 +5 7 +# No. of faces: 1 +14 +0 2 2 4 +0 6 2 4 +1 1 5 1 +1 1 5 1 +2 4 5 1 +2 4 5 7 +1 7 5 7 +1 7 5 7 +5 1 6 0 +5 1 6 1 +5 1 6 1 +5 7 6 7 +5 7 6 7 +5 7 6 8 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test82.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test82.txt new file mode 100644 index 00000000000..723bf69b8ff --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test82.txt @@ -0,0 +1,25 @@ +3 +0 4 4 0 +0 4 4 0 +-1 2 5 2 +4 +-1 2 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 4 0 +48/24 48/24 5 2 +5 +-1 2 +0 4 +48/24 48/24 +4 0 +5 2 +1 +48/24 48/24 +# No. of faces: 1 +6 +-1 2 48/24 48/24 +0 4 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 4 0 +48/24 48/24 4 0 +48/24 48/24 5 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test83.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test83.txt new file mode 100644 index 00000000000..5ef7d44396b --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test83.txt @@ -0,0 +1,28 @@ +5 +0 3 5 5 +0 1 7 0 +0 3 5 1 +0 2 5 1 +0 4 5 5 +5 +0 2 5 1 +0 3 5 1 +0 3 5 5 +0 4 5 5 +0 1 7 0 +7 +0 1 +0 2 +0 3 +0 4 +5 1 +5 5 +7 0 +0 +# No. of faces: 1 +5 +0 2 5 1 +0 3 5 1 +0 3 5 5 +0 4 5 5 +0 1 7 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test84.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test84.txt new file mode 100644 index 00000000000..b7d779ff1b1 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test84.txt @@ -0,0 +1,30 @@ +4 +0 4 6 0 +0 0 6 4 +3 2 5 4 +3 2 5 0 +6 +0 0 3 2 +0 4 3 2 +3 2 5 0 +3 2 5 4 +3 2 6 0 +3 2 6 4 +7 +0 0 +0 4 +3 2 +5 0 +5 4 +6 0 +6 4 +1 +3 2 +# No. of faces: 1 +6 +0 0 3 2 +0 4 3 2 +3 2 5 0 +3 2 5 4 +3 2 6 0 +3 2 6 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test85.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test85.txt new file mode 100644 index 00000000000..53e394fb9dc --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test85.txt @@ -0,0 +1,23 @@ +3 +0 0 6 0 +2 0 4 3 +2 0 5 2 +4 +0 0 2 0 +2 0 4 3 +2 0 5 2 +2 0 6 0 +5 +0 0 +2 0 +4 3 +5 2 +6 0 +1 +2 0 +# No. of faces: 1 +4 +0 0 2 0 +2 0 4 3 +2 0 5 2 +2 0 6 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test86.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test86.txt new file mode 100644 index 00000000000..85ef8c50bc4 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test86.txt @@ -0,0 +1,23 @@ +3 +0 3 6 3 +3 3 6 1 +3 3 6 0 +4 +0 3 3 3 +3 3 6 0 +3 3 6 1 +3 3 6 3 +5 +0 3 +3 3 +6 0 +6 1 +6 3 +1 +3 3 +# No. of faces: 1 +4 +0 3 3 3 +3 3 6 0 +3 3 6 1 +3 3 6 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test87.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test87.txt new file mode 100644 index 00000000000..029e8e04e93 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test87.txt @@ -0,0 +1,23 @@ +3 +7 3 0 3 +3 3 5 0 +3 3 6 6 +4 +3 3 0 3 +3 3 5 0 +3 3 6 6 +7 3 3 3 +5 +0 3 +3 3 +5 0 +6 6 +7 3 +1 +3 3 +# No. of faces: 1 +4 +3 3 0 3 +3 3 5 0 +3 3 6 6 +7 3 3 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test88.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test88.txt new file mode 100644 index 00000000000..036b8c8b6bd --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test88.txt @@ -0,0 +1,26 @@ +3 +0 4 7 4 +1 0 5 8 +3 4 6 6 +5 +1 0 3 4 +0 4 3 4 +3 4 5 8 +3 4 6 6 +3 4 7 4 +6 +0 4 +1 0 +3 4 +5 8 +6 6 +7 4 +1 +3 4 +# No. of faces: 1 +5 +1 0 3 4 +0 4 3 4 +3 4 5 8 +3 4 6 6 +3 4 7 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp index 23ceebf559d..1171fabe614 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp @@ -1,6 +1,5 @@ // examples/Pm_with_intersections/example4 // --------------------------------------- -#include #include #include #include @@ -8,10 +7,14 @@ #include #include +#include +#include +// #include + #define CGAL_SEGMENT_TRAITS 1 -#define CGAL_SEGMENT_LEDA_TRAITS 2 #define CGAL_POLYLINE_TRAITS 11 #define CGAL_CONIC_TRAITS 21 +#define CGAL_POLYCONIC_TRAITS 22 // Picking a default Traits class (this, with the // PL flag enables the running of the test independently of cgal_make.) @@ -19,13 +22,12 @@ #define CGAL_ARR_TEST_TRAITS CGAL_SEGMENT_TRAITS #endif -// Making sure test doesn't fail if LEDA is not installed -#if ! defined(CGAL_USE_LEDA) && \ - (CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_LEDA_TRAITS || \ - CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS ) +// Making sure test doesn't fail if CORE is not installed +#if ! defined(CGAL_USE_CORE) && \ + ((CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS) || \ + (CGAL_ARR_TEST_TRAITS == CGAL_POLYCONIC_TRAITS)) -int main() -{ +int main() { std::cout << "A try to run test with LEDA traits but LEDA is not installed."; std::cout << std::endl; std::cout << "Test is not performed."; @@ -33,11 +35,12 @@ int main() return 0; } -#elif ! defined(CGAL_USE_GMP) && \ - (CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS) -int main() -{ +#elif ! defined(CGAL_USE_GMP) && \ + ((CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS) || \ + (CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_TRAITS)) + +int main() { std::cout << "A try to run test with GMP number type but GMP is not installed."; std::cout << std::endl; std::cout << "Test is not performed."; @@ -48,252 +51,491 @@ int main() #else - - // Choose traits #if CGAL_ARR_TEST_TRAITS==CGAL_SEGMENT_TRAITS #include -#include -#include +#include #include -#include -#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_LEDA_TRAITS -#include -#include -#include #elif CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_TRAITS +#include #include -#include -#include #include #include #elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS #include -#include #include +#include +#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYCONIC_TRAITS +#include +#include +#include +#include #else #error No traits defined for test #endif #include #include + #include -#include "CompareCurveList.h" -#if CGAL_ARR_TEST_TRAITS==CGAL_SEGMENT_TRAITS - typedef CGAL::Gmpq NT; - typedef CGAL::Cartesian Kernel; - typedef CGAL::Arr_segment_traits_2 Traits; +#include "Compare_curves.h" -#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_LEDA_TRAITS - typedef leda_rational NT; - typedef CGAL::Pm_segment_traits_leda_kernel_2 Kernel; - typedef CGAL::Arr_leda_segment_traits_2 Traits; +#if CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS +typedef CGAL::Gmpq NT; +typedef CGAL::Cartesian Kernel; +typedef CGAL::Arr_segment_traits_2 Traits; #elif CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_TRAITS - typedef CGAL::Quotient NT; - typedef CGAL::Cartesian Kernel; - typedef CGAL::Arr_segment_cached_traits_2 Seg_traits; - typedef CGAL::Arr_polyline_traits_2 Traits; +typedef CGAL::Gmpq NT; +typedef CGAL::Cartesian Kernel; +typedef CGAL::Arr_segment_traits_2 Seg_traits; +typedef CGAL::Arr_polyline_traits_2 Traits; #elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS -typedef leda_real NT; -typedef CGAL::Cartesian Kernel; -typedef CGAL::Arr_conic_traits_2 Traits; +typedef CGAL::CORE_algebraic_number_traits Nt_traits; +typedef Nt_traits::Rational Rational; +typedef Nt_traits::Algebraic Algebraic; +typedef CGAL::Cartesian Rat_kernel; +typedef Rat_kernel::Point_2 Rat_point_2; +typedef Rat_kernel::Segment_2 Rat_segment_2; +typedef Rat_kernel::Circle_2 Rat_circle_2; +typedef CGAL::Cartesian Alg_kernel; +typedef CGAL::Arr_conic_traits_2 + Traits; +#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYCONIC_TRAITS +typedef CGAL::CORE_algebraic_number_traits Nt_traits; +typedef Nt_traits::Rational Rational; +typedef Nt_traits::Algebraic Algebraic; +typedef CGAL::Cartesian Rat_kernel; +typedef Rat_kernel::Point_2 Rat_point_2; +typedef Rat_kernel::Segment_2 Rat_segment_2; +typedef Rat_kernel::Circle_2 Rat_circle_2; +typedef CGAL::Cartesian Alg_kernel; +typedef CGAL::Arr_conic_traits_2 + Conic_traits; +typedef CGAL::Arr_polycurve_traits_2 Traits; + #endif -typedef Traits::Point_2 Point_2; -typedef Traits::X_monotone_curve_2 X_monotone_curve_2; +typedef Traits::Point_2 Point_2; +typedef Traits::Curve_2 Curve_2; +typedef Traits::X_monotone_curve_2 X_monotone_curve_2; -typedef std::list PointList; -typedef PointList::iterator PointListIter; +typedef std::list Points; +typedef std::list Curves; +typedef std::list X_monotone_curves; -typedef std::list CurveList; -typedef CurveList::iterator CurveListIter; +bool curves_identical(X_monotone_curves& list1, X_monotone_curves& list2); +bool points_identical(Points& list1, Points& list2); -void ReadCurveList(std::ifstream &inp, CurveList &clist); -void ReadCurveListRational(std::ifstream &inp, CurveList &clist); -void ReadPointList(std::ifstream &inp, PointList &plist); -bool IsCurveListIdentical(CurveList &list1, CurveList &list2); -bool IsPointListIdentical(PointList &list1, PointList &list2); +// istream modifier skips chars until end of line. +std::istream& skip_until_eol(std::istream& in) { + if (in.eof()) return in; + char c; + while (in.get(c) && (c != '\n')); + return in; +} -int main(int argc, char * argv[]) -{ +// istream modifier that checks for OFF comments and removes them. +std::istream& skip_comment(std::istream& in) { + char c; + while ((in >> c) && (c == '#')) in >> skip_until_eol; + in.putback(c); + return in; +} - if ( argc != 2 ) - { +#if CGAL_ARR_TEST_TRAITS != CGAL_CONIC_TRAITS + +bool read_points(std::ifstream& inp, Points& points, const Traits&) { + int count; + inp >> skip_comment >> count; + + // std::cout << "read_points " << count << "\n"; + for (int i = 0; i < count; i++) { + NT x, y; + inp >> skip_comment >> x >> y; + Point_2 p(x, y); + // std::cout << p << "\n"; + points.push_back(p); + } + return true; +} + +#endif + +#if CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS + +bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { + int count; + inp >> skip_comment >> count; + // std::cout << "read_curves " << count << "\n"; + + for (int i = 0; i < count; ++i) { + NT x0, y0, x1, y1; + inp >> skip_comment >> x0 >> y0 >> x1 >> y1; + Point_2 p1(x0, y0); + Point_2 p2(x1, y1); + Curve_2 curve(p1, p2); + curves.push_back(curve); + // std::cout << curve << "\n"; + } + return true; +} + +bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, + const Traits& traits) +{ return read_curves(inp, xcurves, traits); } + +#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_TRAITS + +template +bool read_curves_(std::ifstream& inp, Curves_& curves, const Traits& traits, + const Ctr& ctr) { + int count; + inp >> skip_comment >> count; + // std::cout << "read_curves " << count << "\n"; + for (int i = 0; i < count; ++i) { + Points points; + auto rc = read_points(inp, points, traits); + if (! rc) return false; + auto cv = ctr(points.begin(), points.end()); + // std::cout << cv << "\n"; + curves.push_back(cv); + } + return true; +} + +/*! Read curves. + */ +bool read_curves(std::ifstream& inp, Curves& curves, const Traits& traits) { + auto ctr_cv = traits.construct_curve_2_object(); + return read_curves_(inp, curves, traits, ctr_cv); +} + +/*! Read x-monotone curves. + */ +bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, + const Traits& traits) { + auto ctr_xcv = traits.construct_x_monotone_curve_2_object(); + return read_curves_(inp, xcurves, traits, ctr_xcv); +} + +#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS + +void read_curve(std::ifstream& is, Curve_2& cv, const Traits& traits) { + // Read a line from the input file. + char one_line[128]; + auto ctr_curve_2 = traits.construct_curve_2_object(); + + is >> skip_comment; + is.getline(one_line, 128); + std::string stringvalues(one_line); + std::istringstream str_line(stringvalues, std::istringstream::in); + + // Get the arc type. + // Supported types are: 'f' - Full ellipse (or circle). + // 'e' - Elliptic arc (or circular arc). + // 's' - Line segment. + char type; + bool is_circle = false; // Is this a circle. + Rat_circle_2 circle; + Rational r, s, t, u, v, w; // The conic coefficients. + + str_line >> type; + + // An ellipse (full ellipse or a partial ellipse): + if (type == 'f' || type == 'F' || type == 'e' || type == 'E') { + // Read the ellipse (using the format "a b x0 y0"): + // + // x - x0 2 y - y0 2 + // ( -------- ) + ( -------- ) = 1 + // a b + // + int a, b, x0, y0; + + str_line >> a >> b >> x0 >> y0; + + Rational a_sq = Rational(a*a); + Rational b_sq = Rational(b*b); + + if (a == b) { + is_circle = true; + circle = + Rat_circle_2(Rat_point_2(Rational(x0), Rational(y0)), Rational(a*b)); + } + else { + r = b_sq; + s = a_sq; + t = 0; + u = Rational(-2*x0*b_sq); + v = Rational(-2*y0*a_sq); + w = Rational(x0*x0*b_sq + y0*y0*a_sq - a_sq*b_sq); + } + + if (type == 'f' || type == 'F') { + // Create a full ellipse (or circle). + if (is_circle) cv = ctr_curve_2(circle); + else cv = ctr_curve_2(r, s, t, u, v, w); + } + else { + // Read the endpointd of the arc. + int x1, y1, x2, y2; + + str_line >> x1 >> y1 >> x2 >> y2; + + Point_2 source = Point_2(Algebraic(x1), Algebraic(y1)); + Point_2 target = Point_2(Algebraic(x2), Algebraic(y2)); + + // Create the arc. Note that it is always clockwise oriented. + if (is_circle) cv = ctr_curve_2(circle, CGAL::CLOCKWISE, source, target); + else cv = ctr_curve_2(r, s, t, u, v, w, CGAL::CLOCKWISE, source, target); + } + } + else if (type == 's' || type == 'S') { + // Read a segment, given by its endpoints (x1,y1) and (x2,y2); + int x1, y1, x2, y2; + + str_line >> x1 >> y1 >> x2 >> y2; + + // Create the segment. + Rat_point_2 source = Rat_point_2 (Rational(x1), Rational(y1)); + Rat_point_2 target = Rat_point_2 (Rational(x2), Rational(y2)); + + cv = ctr_curve_2(Rat_segment_2 (source, target)); + } + + // std::cout << cv << std::endl; +} + +/*! Read curves. + */ +bool read_curves(std::ifstream& inp, Curves& curves, const Traits& traits) { + // auto ctr_cv = traits.construct_curve_2_object(); + int count; + inp >> skip_comment >> count; + Curve_2 cv; + char dummy[256]; + inp.getline(dummy, sizeof(dummy)); + for (int i = 0; i < count; ++i) { + read_curve(inp, cv, traits); + curves.push_back(cv); + } + return true; +} + +#else +#error No traits defined for test +#endif + +#if CGAL_ARR_TEST_TRAITS != CGAL_CONIC_TRAITS + +// Test subcurves w/o overlapping +bool test_curves_no_overlap(std::ifstream& inp, Curves& /* curves */, + const X_monotone_curves& curves_no_overlap_out, + const Traits& tr) { + X_monotone_curves curves_no_overlap; + if (! read_xcurves(inp, curves_no_overlap, tr)) return false; + + if (! compare_lists(curves_no_overlap_out, curves_no_overlap, tr)) { + std::cerr << "Error: Curves w/o overlapping do not match!\n"; + for (const auto& xcv : curves_no_overlap_out) std::cerr << xcv << std::endl; + return false; + } + + return true; +} + +// Test subcurves w/ overlapping +bool test_curves_with_overlap(std::ifstream& inp, Curves& /* curves */, + const X_monotone_curves& curves_with_overlap_out, + const Traits& tr) { + X_monotone_curves curves_with_overlap; + if (! read_xcurves(inp, curves_with_overlap, tr)) return false; + + if (! compare_lists(curves_with_overlap_out, curves_with_overlap, tr)) { + std::cerr << "Error: Curves w/ overlapping do not match!\n"; + for (const auto& xcv : curves_with_overlap_out) + std::cerr << xcv << std::endl; + return false; + } + + return true; +} + +// Test intersection points (with endpoints) +bool test_points_with_ends(std::ifstream& inp, Curves& /* curves */, + const Points& points_with_ends_out, + const Traits& tr) { + Points points_with_ends; + if (! read_points(inp, points_with_ends, tr)) return false; + + if (! compare_lists(points_with_ends_out, points_with_ends, tr)) { + std::cerr << "Error: Endpoints do not match!\n"; + for (const auto& p : points_with_ends_out) std::cerr << p << std::endl; + return false; + } + + return true; +} + +// Test intersection points w/o end points +bool test_points_no_ends(std::ifstream& inp, Curves& /* curves */, + const Points& points_no_ends_out, + const Traits& tr) { + Points points_no_ends; + if (! read_points(inp, points_no_ends, tr)) return false; + + if (! compare_lists(points_no_ends_out, points_no_ends, tr)) { + std::cerr << "Error: Intersection points do not match!\n"; + for (const auto& p : points_no_ends_out) std::cerr << p << std::endl; + return false; + } + + return true; +} + +#else + +/*! Test the surface sweep with conic traits. + */ +bool test_conic(std::ifstream& inp, Curves& curves, + const X_monotone_curves& curves_no_overlap_out, + const Points& points_with_ends_out, + const Points& points_no_ends_out, + const Traits& traits) { + auto ctr_bbox_2 = traits.construct_bbox_2_object(); + CGAL::Bbox_2 bbox = ctr_bbox_2(curves.front()); + for (auto it = std::next(curves.begin()); it != curves.end(); ++it) + bbox = bbox + ctr_bbox_2(*it); + + // generate the string for the output + std::stringstream out1; + for (const auto& xcv : curves_no_overlap_out) out1 << xcv << "\n"; + + // read the output from the file + std::stringstream out2; + char buf[1024]; + int count = 0; + + inp >> count; + inp.getline(buf, 1024); // to get rid of the new line + for (int i = 0; i < count; ++i) { + inp.getline(buf, 1024); + out2 << buf << "\n"; + } + + // std::cout << "Result: \n" << curves_no_overlap_out.size() << "\n"; + // for (const auto& xcv : curves_no_overlap_out) + // std::cout << xcv << "\n"; + + std::string calculated = out1.str(); + std::string infile = out2.str(); + + if (infile != calculated) { + std::cerr << "Error\n"; + std::cerr << "\ncalculated:\n"; + std::cerr << calculated << std::endl; + std::cerr << "\nin file:\n"; + std::cerr << infile << std::endl; + std::cerr << "--" << std::endl; + return false; + } + + std::size_t points_with_ends_size, points_no_ends_size; + inp >> skip_comment >> points_with_ends_size >> points_no_ends_size; + + auto points_with_ends_out_size = points_with_ends_out.size(); + if (points_with_ends_size != points_with_ends_out_size ) { + std::cerr << "Error: Number of endpoints do not match (" + << points_with_ends_out_size << ", " + << points_with_ends_size << ")\n"; + return false; + } + + auto points_no_ends_out_size = points_no_ends_out.size(); + if (points_no_ends_size != points_no_ends_out_size) { + std::cerr << "Error: Number of intersection points do not match (" + << points_no_ends_out_size << ", " + << points_no_ends_size << ")\n"; + return false; + } + + return true; +} + +#endif + +int main(int argc, char* argv[]) { + if (argc != 2) { std::cout << "Specify a file name " << std::endl; return -1; } std::ifstream inp(argv[1]); - if (!inp.is_open()) { - std::cerr << "Cannot open file " << argv[1] << "!" << std::endl; + if (! inp.is_open()) { + std::cerr << "Error: Cannot open file " << argv[1] << "!" << std::endl; return -1; } - CurveList curves; - ReadCurveList(inp, curves); - Traits tr; - // get subcurves w/o overlapping - CurveList curves_no_overlap_list_out; - CGAL::compute_subcurves(curves.begin(), - curves.end(), - std::back_inserter(curves_no_overlap_list_out)); + Curves curves; + if (! read_curves(inp, curves, tr)) return -1; + // { + // using Arrangement = CGAL::Arrangement_2; + // Arrangement arr(&tr); + // CGAL::insert(arr, curves.begin(), curves.end()); + // CGAL::draw(arr, "conics", true); + // } - // get subcurves w/ overlapping - CurveList curves_with_overlap_list_out; - CGAL::compute_subcurves(curves.begin(), - curves.end(), - std::back_inserter(curves_with_overlap_list_out), - true); + X_monotone_curves curves_no_overlap_out; + CGAL::compute_subcurves(curves.begin(), curves.end(), + std::back_inserter(curves_no_overlap_out), + false, tr); - /*std::copy(curves_no_overlap_list_out.begin(), - curves_no_overlap_list_out.end(), - std::ostream_iterator(std::cout, "\n")); - std::cout<<"\n\n*******************\n\n"; + X_monotone_curves curves_with_overlap_out; + CGAL::compute_subcurves(curves.begin(), curves.end(), + std::back_inserter(curves_with_overlap_out), + true, tr); - std::copy(curves_with_overlap_list_out.begin(), - curves_with_overlap_list_out.end(), - std::ostream_iterator(std::cout, "\n")); - return 0;*/ + Points points_with_ends_out; + CGAL::compute_intersection_points(curves.begin(), curves.end(), + std::back_inserter(points_with_ends_out), + true, tr); - //std::cout << mylist1.size() << " curves\n"; + Points points_no_ends_out; + CGAL::compute_intersection_points(curves.begin(), curves.end(), + std::back_inserter(points_no_ends_out), + false, tr); +#if CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS + if (! test_conic(inp, curves, curves_no_overlap_out, + points_with_ends_out, points_no_ends_out, tr)) + return -1; +#else + if (! test_curves_no_overlap(inp, curves, curves_no_overlap_out, tr)) + return -1; + if (! test_points_with_ends(inp, curves, points_with_ends_out, tr)) return -1; + if (! test_points_no_ends(inp, curves, points_no_ends_out, tr)) return -1; + if (! test_curves_with_overlap(inp, curves, curves_with_overlap_out, tr)) + return -1; +#endif - // get intersection points (with endpoints) - PointList points_with_ends_list_out; - CGAL::compute_intersection_points(curves.begin(), - curves.end(), - std::back_inserter(points_with_ends_list_out), - true); - - - // get intersection points w/o end points - PointList points_without_ends_list_out; - CGAL::compute_intersection_points(curves.begin(), - curves.end(), - std::back_inserter(points_without_ends_list_out), - false); - std::cout << points_without_ends_list_out.size() - << " points_without_ends_list_out(size)\n"; - - // check the do_curves_intersecting method + // Test the do_curves_intersecting method bool do_intersect_out = CGAL::do_curves_intersect(curves.begin(), curves.end()); - - - // read curves and points from file - CurveList curves_no_overlap_list; - ReadCurveListRational(inp, curves_no_overlap_list); - - PointList points_with_ends_list; - ReadPointList(inp, points_with_ends_list); - - PointList points_without_ends_list; - ReadPointList(inp, points_without_ends_list); - - int num_faces; - inp >> num_faces; - - CurveList curves_with_overlap_list; - ReadCurveListRational(inp, curves_with_overlap_list); - - if ( !compare_lists(curves_no_overlap_list_out, - curves_no_overlap_list, tr) ) + bool do_intersect = ! points_no_ends_out.empty() || + (curves_no_overlap_out.size() != curves_with_overlap_out.size()); + if (do_intersect_out != do_intersect) { + std::cerr << "Error: do_intersect()\n"; return -1; + } - if ( !compare_lists(curves_with_overlap_list_out, - curves_with_overlap_list, tr) ) - return -1; - - if ( !compare_lists(points_with_ends_list_out, - points_with_ends_list, tr)) - return -1; - - if ( !compare_lists(points_without_ends_list_out, - points_without_ends_list, tr)) - return -1; - - bool do_intersect = false; - if((points_without_ends_list.size() != 0) || - (curves_no_overlap_list_out.size() != - curves_with_overlap_list_out.size())) - do_intersect = true; - - if (do_intersect_out != do_intersect) - return -1; - - std::cout<<"OK\n"; + std::cout << "Passed\n"; return 0; } -void ReadCurveList(std::ifstream& inp, CurveList& clist) -{ - int count; - inp >> count; - //std::cout << "ReadCurveList " << count << "\n"; - - for (int i = 0; i < count; i++) { - NT x0, y0, x1, y1; - int ix0, iy0, ix1, iy1; - inp >> ix0 >> iy0 >> ix1 >> iy1; - x0 = ix0; y0 = iy0; x1 = ix1; y1 = iy1; - - Point_2 p1(x0, y0); - Point_2 p2(x1, y1); - X_monotone_curve_2 curve(p1, p2); - clist.push_back(curve); - //std::cout << curve << "\n"; - } -} - -void ReadCurveListRational(std::ifstream& inp, CurveList& clist) -{ - int count; - inp >> count; - std::cout << "ReadCurveListRational " << count << "\n"; - char ch; - - for (int i = 0; i < count; i++) { - int a, b; - inp >> a >> ch >> b; - NT x0(a,b); - inp >> a >> ch >> b; - NT y0(a,b); - Point_2 p1(x0, y0); - - inp >> a >> ch >> b; - NT x1(a,b); - inp >> a >> ch >> b; - NT y1(a,b); - Point_2 p2(x1, y1); - - X_monotone_curve_2 curve(p1, p2); - clist.push_back(curve); - std::cout << curve << "\n"; - } -} -void ReadPointList(std::ifstream &inp, PointList &plist) -{ - int count; - inp >> count; - char ch; - - std::cout << "ReadPointList " << count << "\n"; - for (int i = 0; i < count; i++) { - int a, b; - inp >> a >> ch >> b; - NT x0(a,b); - inp >> a >> ch >> b; - NT y0(a,b); - Point_2 p(x0, y0); - plist.push_back(p); - } -} - #endif diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep_conic.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep_conic.cpp deleted file mode 100644 index 90866e1a98d..00000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep_conic.cpp +++ /dev/null @@ -1,259 +0,0 @@ -#include - -#if !defined(CGAL_USE_CORE) -#include -int main() -{ - std::cout << "CORE is not installed. Test aborted!" << std::endl; - return 0; -} -#else - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -typedef CGAL::CORE_algebraic_number_traits Nt_traits; -typedef Nt_traits::Rational Rational; -typedef Nt_traits::Algebraic Algebraic; -typedef CGAL::Cartesian Rat_kernel; -typedef Rat_kernel::Point_2 Rat_point_2; -typedef Rat_kernel::Segment_2 Rat_segment_2; -typedef Rat_kernel::Circle_2 Rat_circle_2; -typedef CGAL::Cartesian Alg_kernel; -typedef CGAL::Arr_conic_traits_2 - Traits_2; - -typedef Traits_2::Curve_2 Curve_2; -typedef Traits_2::X_monotone_curve_2 X_monotone_curve_2; -typedef Traits_2::Point_2 Point_2; -typedef std::list CurveList; - -typedef std::list PointList; -typedef PointList::iterator PointListIter; - -/*! Conic reader */ -template -class Conic_reader { -private: - Traits_2 m_traits; - -public: - int read_data(const char* filename, CurveList& curves, CGAL::Bbox_2& bbox, - const Traits& traits) { - Curve_2 cv; - char dummy[256]; - - std::ifstream inp(filename); - if (!inp.is_open()) { - std::cerr << "Cannot open file " << filename << "!" << std::endl; - return -1; - } - int count; - inp >> count; - inp.getline(dummy, sizeof(dummy)); - for (int i = 0; i < count; ++i) { - read_curve(inp, cv); - curves.push_back(cv); - CGAL::Bbox_2 curve_bbox = traits.construct_bbox_2_object()(cv); - if (i == 0) bbox = curve_bbox; - else bbox = bbox + curve_bbox; - } - inp.close(); - return 0; - } - - void read_curve(std::ifstream& is, Curve_2& cv) { - auto ctr_cv = m_traits.construct_curve_2_object(); - - // Read a line from the input file. - char one_line[128]; - - skip_comments(is, one_line); - std::string stringvalues(one_line); - std::istringstream str_line(stringvalues, std::istringstream::in); - - // Get the arc type. - // Supported types are: 'f' - Full ellipse (or circle). - // 'e' - Elliptic arc (or circular arc). - // 's' - Line segment. - bool is_circle(false); // Is this a circle. - Rat_circle_2 circle; - Rational r, s, t, u, v, w; // The conic coefficients. - - char type; - str_line >> type; - - // An ellipse (full ellipse or a partial ellipse): - if (type == 'f' || type == 'F' || type == 'e' || type == 'E') { - // Read the ellipse (using the format "a b x0 y0"): - // - // x - x0 2 y - y0 2 - // ( -------- ) + ( -------- ) = 1 - // a b - // - int a, b, x0, y0; - str_line >> a >> b >> x0 >> y0; - - Rational a_sq = Rational(a*a); - Rational b_sq = Rational(b*b); - - if (a == b) { - is_circle = true; - circle = - Rat_circle_2(Rat_point_2(Rational(x0), Rational(y0)), Rational(a*b)); - } - else { - r = b_sq; - s = a_sq; - t = 0; - u = Rational(-2*x0*b_sq); - v = Rational(-2*y0*a_sq); - w = Rational(x0*x0*b_sq + y0*y0*a_sq - a_sq*b_sq); - } - - if (type == 'f' || type == 'F') { - // Create a full ellipse (or circle). - cv = (is_circle) ? ctr_cv(circle) : ctr_cv(r, s, t, u, v, w); - return; - } - - // Read the endpointd of the arc. - int x1, y1, x2, y2; - str_line >> x1 >> y1 >> x2 >> y2; - - Point_2 source = Point_2 (Algebraic(x1), Algebraic(y1)); - Point_2 target = Point_2 (Algebraic(x2), Algebraic(y2)); - - // Create the arc. Note that it is always clockwise oriented. - cv = (is_circle) ? - ctr_cv(circle, CGAL::CLOCKWISE, source, target) : - ctr_cv(r, s, t, u, v, w, CGAL::CLOCKWISE, source, target); - return; - } - - if (type == 's' || type == 'S') { - // Read a segment, given by its endpoints (x1,y1) and (x2,y2); - int x1, y1, x2, y2; - str_line >> x1 >> y1 >> x2 >> y2; - - // Create the segment. - Rat_point_2 source = Rat_point_2(Rational(x1), Rational(y1)); - Rat_point_2 target = Rat_point_2(Rational(x2), Rational(y2)); - - cv = ctr_cv(Rat_segment_2(source, target)); - return; - } - - std::cerr << "Invalid type (" << type << ")" << std::endl; - } - - void skip_comments( std::ifstream& is, char* one_line) { - while( !is.eof() ){ - is.getline( one_line, 128 ); - if( one_line[0] != '#' ){ - break; - } - } - } -}; - -//--------------------------------------------------------------------------- -// The main: -// -int main(int argc, char* argv[]) { - bool verbose = false; - - // Define a test objects to read the conic arcs from it. - if (argc<2) { - std::cerr << "Usage: Conic_traits_test " << std::endl; - exit(1); - } - - Traits_2 traits; - CGAL::Bbox_2 bbox; - CurveList curves; - - Conic_reader reader; - reader.read_data(argv[1], curves, bbox, traits); - - // run the sweep - std::list mylist; - - CGAL::compute_subcurves(curves.begin(), curves.end(), - std::back_inserter(mylist), false); - - - PointList point_list_with_ends; - CGAL::compute_intersection_points(curves.begin(), curves.end(), - std::back_inserter(point_list_with_ends), - true); - std::size_t point_count_with_ends_calculated = point_list_with_ends.size(); - - // generate the string for the output - std::stringstream out1; - for (auto iter = mylist.begin(); iter != mylist.end(); ++iter) - out1 << *iter << "\n"; - - // read the output from the file - std::stringstream out2; - char buf[1024]; - int count = 0; - - std::ifstream in_file(argv[1]); - in_file >> count; - in_file.getline(buf, 1024); // to get rid of the new line - for (int i = 0 ; i < count ; ++i) in_file.getline(buf, 1024); - in_file >> count; - in_file.getline(buf, 1024); // to get rid of the new line - for (int i = 0; i < count; ++i) { - in_file.getline(buf, 1024); - out2 << buf << "\n"; - } - std::size_t point_count_with_ends_from_file = 0; - in_file >> point_count_with_ends_from_file; - in_file.close(); - - if (verbose) { - std::cout << "Result: \n" << mylist.size() << "\n"; - for (auto i = mylist.begin(); i != mylist.end() ; ++i) - std::cout << *i << "\n"; - } - - std::string calculated = out1.str(); - std::string infile = out2.str(); - - if (infile == calculated) { - if (point_count_with_ends_from_file != point_count_with_ends_calculated) { - std::cout << "number of intersection points (with ends):" - << point_count_with_ends_calculated << ". Should be " - << point_count_with_ends_from_file << "\n"; - std::cout << argv[1] << " Error\n"; - return -1; - } - else { - std::cout << argv[1] << " OK!\n"; - } - } - else { - std::cout << argv[1] << " Error\n"; - std::cout << "\ncalculated:\n"; - std::cout << calculated << std::endl; - std::cout << "\nin file:\n"; - std::cout << infile << std::endl; - std::cout << "--" << std::endl; - return -1; - } - - return 0; -} - -#endif diff --git a/TDS_3/include/CGAL/Triangulation_utils_3.h b/TDS_3/include/CGAL/Triangulation_utils_3.h index d563fda6954..80c8c507977 100644 --- a/TDS_3/include/CGAL/Triangulation_utils_3.h +++ b/TDS_3/include/CGAL/Triangulation_utils_3.h @@ -80,6 +80,7 @@ struct Triangulation_utils_3 CGAL_precondition( ( i >= 0 && i < 4 ) && ( j >= 0 && j < 4 ) && ( i != j ) ); + CGAL_assume(i!=j); return tab_next_around_edge[i][j]; } diff --git a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt index 0500556f074..a2e1c0fb136 100644 --- a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt +++ b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt @@ -103,6 +103,12 @@ setting the named parameter `remesh_boundaries` to `false`. \cgalExample{Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp } +It is also possible to define the polyline features as the ones +stored as complex edges in a `Mesh_complex_3_in_triangulation_3` +(e.g. generated by the \ref PkgMesh3 package mesh generation algorithms). + +\cgalExample{Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp } + \subsection ssecEx4 Tetrahedral Remeshing After Mesh Generation diff --git a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt index 018dde26767..17d90d1f20d 100644 --- a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt +++ b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt @@ -4,5 +4,6 @@ \example Tetrahedral_remeshing/tetrahedral_remeshing_of_one_subdomain.cpp \example Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp \example Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features.cpp +\example Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp \example Tetrahedral_remeshing/tetrahedral_remeshing_from_mesh.cpp */ diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt index b5c4c1da2ab..94981f0550b 100644 --- a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt +++ b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt @@ -31,9 +31,13 @@ if(TARGET CGAL::Eigen3_support) create_single_source_cgal_program( "mesh_and_remesh_polyhedral_domain_with_features.cpp" ) target_link_libraries(mesh_and_remesh_polyhedral_domain_with_features PUBLIC CGAL::Eigen3_support) + create_single_source_cgal_program("mesh_and_remesh_c3t3.cpp") + target_link_libraries(mesh_and_remesh_c3t3 PUBLIC CGAL::Eigen3_support) + if(CGAL_ACTIVATE_CONCURRENT_MESH_3 AND TARGET CGAL::TBB_support) message(STATUS "Found TBB") target_link_libraries(mesh_and_remesh_polyhedral_domain_with_features PRIVATE CGAL::TBB_support) + target_link_libraries(mesh_and_remesh_c3t3 PRIVATE CGAL::TBB_support) endif() else() message(STATUS "NOTICE: Some examples require Eigen 3.1 (or greater), and will not be compiled.") diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp new file mode 100644 index 00000000000..b5a10784e92 --- /dev/null +++ b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp @@ -0,0 +1,96 @@ +#include + +#include +#include +#include + +#include +#include + +#include + +#include + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Mesh_polyhedron_3::type Polyhedron; +typedef CGAL::Polyhedral_mesh_domain_with_features_3 Mesh_domain; + +#ifdef CGAL_CONCURRENT_MESH_3 +typedef CGAL::Parallel_tag Concurrency_tag; +#else +typedef CGAL::Sequential_tag Concurrency_tag; +#endif + +// Triangulation for Meshing +typedef CGAL::Mesh_triangulation_3::type Tr; +typedef CGAL::Mesh_complex_3_in_triangulation_3< + Tr, Mesh_domain::Corner_index, Mesh_domain::Curve_index> C3t3; + +// Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; + +// Triangulation for Remeshing +typedef CGAL::Triangulation_3 Triangulation_3; +using Vertex_handle = Triangulation_3::Vertex_handle; + +using Vertex_pair = std::pair; +using Constraints_set = std::unordered_set>; +using Constraints_pmap = CGAL::Boolean_property_map; + + +// To avoid verbose function and named parameters call +using namespace CGAL::parameters; + +int main(int argc, char* argv[]) +{ + const std::string fname = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/fandisk.off"); + std::ifstream input(fname); + Polyhedron polyhedron; + input >> polyhedron; + if (input.fail() || !CGAL::is_triangle_mesh(polyhedron)) { + std::cerr << "Error: Input invalid " << fname << std::endl; + return EXIT_FAILURE; + } + + // Create domain + Mesh_domain domain(polyhedron); + + // Get sharp features + domain.detect_features(); + + // Mesh criteria + Mesh_criteria criteria(edge_size = 0.025, + facet_angle = 25, facet_size = 0.05, facet_distance = 0.005, + cell_radius_edge_ratio = 3, cell_size = 0.05); + + // Mesh generation + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria); + + CGAL::dump_c3t3(c3t3, "out"); + + Constraints_set constraints; + Constraints_pmap constraints_pmap(constraints); + + Triangulation_3 tr = CGAL::convert_to_triangulation_3(std::move(c3t3), + CGAL::parameters::edge_is_constrained_map(constraints_pmap)); + + //note we use the move semantic, with std::move(c3t3), + // to avoid a copy of the triangulation by the function + // `CGAL::convert_to_triangulation_3()` + // After the call to this function, c3t3 is an empty and valid C3t3. + //It is possible to use : CGAL::convert_to_triangulation_3(c3t3), + // Then the triangulation is copied and duplicated, and c3t3 remains as is. + + const double target_edge_length = 0.1;//coarsen the mesh + CGAL::tetrahedral_isotropic_remeshing(tr, target_edge_length, + CGAL::parameters::number_of_iterations(3) + .edge_is_constrained_map(constraints_pmap)); + + std::ofstream out("out_remeshed.mesh"); + CGAL::IO::write_MEDIT(out, tr); + out.close(); + + return EXIT_SUCCESS; +} diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp index 032cca7e1d3..4cb187d96f2 100644 --- a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp +++ b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp @@ -12,59 +12,16 @@ #include "tetrahedral_remeshing_generate_input.h" -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +using K = CGAL::Exact_predicates_inexact_constructions_kernel; -typedef CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3 Remeshing_triangulation; +using Remeshing_triangulation = CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3; +using Point = Remeshing_triangulation::Point; +using Vertex_handle = Remeshing_triangulation::Vertex_handle; -typedef Remeshing_triangulation::Point Point; -typedef Remeshing_triangulation::Vertex_handle Vertex_handle; -typedef Remeshing_triangulation::Cell_handle Cell_handle; -typedef Remeshing_triangulation::Edge Edge; +using Vertex_pair = std::pair; +using Constraints_set = std::unordered_set>; +using Constraints_pmap = CGAL::Boolean_property_map; -class Constrained_edges_property_map -{ -public: - typedef bool value_type; - typedef bool reference; - typedef std::pair key_type; - typedef boost::read_write_property_map_tag category; - -private: - std::unordered_set>* m_set_ptr; - -public: - Constrained_edges_property_map() - : m_set_ptr(nullptr) - {} - Constrained_edges_property_map(std::unordered_set>* set_) - : m_set_ptr(set_) - {} - -public: - friend void put(Constrained_edges_property_map& map, - const key_type& k, - const bool b) - { - assert(map.m_set_ptr != nullptr); - assert(k.first < k.second); - if (b) map.m_set_ptr->insert(k); - else map.m_set_ptr->erase(k); - } - - friend value_type get(const Constrained_edges_property_map& map, - const key_type& k) - { - assert(map.m_set_ptr != nullptr); - assert(k.first < k.second); - return (map.m_set_ptr->count(k) > 0); - } -}; - -void set_subdomain(Remeshing_triangulation& tr, const int index) -{ - for (auto cit : tr.finite_cell_handles()) - cit->set_subdomain_index(index); -} int main(int argc, char* argv[]) { @@ -73,16 +30,14 @@ int main(int argc, char* argv[]) const int nbv = (argc > 3) ? atoi(argv[3]) : 500; Remeshing_triangulation t3; - typedef std::pair Vertex_pair; - std::unordered_set> constraints; + Constraints_set constraints; CGAL::Tetrahedral_remeshing::generate_input_cube(nbv, t3, constraints); make_constraints_from_cube_edges(t3, constraints); CGAL::tetrahedral_isotropic_remeshing(t3, target_edge_length, - CGAL::parameters::edge_is_constrained_map( - Constrained_edges_property_map(&constraints)) - .number_of_iterations(nb_iter)); + CGAL::parameters::edge_is_constrained_map(Constraints_pmap(constraints)) + .number_of_iterations(nb_iter)); return EXIT_SUCCESS; } diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/peel_slivers.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/peel_slivers.h new file mode 100644 index 00000000000..9cbff2ba95a --- /dev/null +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/peel_slivers.h @@ -0,0 +1,117 @@ +// Copyright (c) 2020 GeometryFactory (France) and Telecom Paris (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Jane Tournois, Noura Faraj, Jean-Marc Thiery, Tamy Boubekeur + +#ifndef CGAL_INTERNAL_PEEL_SLIVERS_H +#define CGAL_INTERNAL_PEEL_SLIVERS_H + +#include + +#include + +namespace CGAL +{ +namespace Tetrahedral_remeshing +{ + +template +std::size_t peel_slivers(C3T3& c3t3, + const typename C3T3::Triangulation::Geom_traits::FT& sliver_angle, + const CellSelector& cell_selector) +{ + using FT = typename C3T3::Triangulation::Geom_traits::FT; + using Cell_handle = typename C3T3::Triangulation::Cell_handle; + using Surface_patch_index = typename C3T3::Surface_patch_index; + + auto& tr = c3t3.triangulation(); + + std::size_t nb_slivers_peel = 0; + std::vector > > peelable_cells; + +#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE + FT mindh = FT(180); +#endif + for (Cell_handle cit : c3t3.cells_in_complex()) + { + if(!get(cell_selector, cit)) + continue; + + std::array facets_on_surface; + + const FT dh = min_dihedral_angle(tr, cit); + if (dh < sliver_angle && is_peelable(c3t3, cit, facets_on_surface)) + peelable_cells.push_back(std::make_pair(cit, facets_on_surface)); + +#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE + mindh = (std::min)(dh, mindh); +#endif + } + +#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE + std::cout << "Min dihedral angle : " << mindh << std::endl; + std::cout << "Peelable cells : " << peelable_cells.size() << std::endl; +#endif + + for (auto c_i : peelable_cells) + { + Cell_handle c = c_i.first; + const std::array& f_on_surface = c_i.second; + + boost::optional patch; + for (int i = 0; i < 4; ++i) + { + if (f_on_surface[i]) + { + Surface_patch_index spi = c3t3.surface_patch_index(c, i); + if (patch != boost::none && patch != spi) + { + patch = boost::none; + break; + } + else + { + patch = spi; + } + } + } + if (patch == boost::none) + continue; + + for (int i = 0; i < 4; ++i) + { + if (f_on_surface[i]) + c3t3.remove_from_complex(c, i); + else + c3t3.add_to_complex(c, i, patch.get()); + } + + c3t3.remove_from_complex(c); + ++nb_slivers_peel; + } + +#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE + mindh = FT(180); + for (Cell_handle cit : c3t3.cells_in_complex()) + { + const FT dh = min_dihedral_angle(tr, cit); + mindh = (std::min)(dh, mindh); + } + std::cout << "Peeling done (removed " << nb_slivers_peel << " slivers, " + << "min dihedral angle = " << mindh << ")." << std::endl; +#endif + + return nb_slivers_peel; +} + +} // end namespace Tetrahedral_remeshing +} // end namespace CGAL + +#endif // CGAL_INTERNAL_PEEL_SLIVERS_H diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h index be3dfe8f276..7a905092870 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -291,67 +292,8 @@ public: std::cout.flush(); #endif - std::size_t nb_slivers_peel = 0; - std::vector > > peelable_cells; -#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE - double mindh = 180.; -#endif - for (Cell_handle cit : tr().finite_cell_handles()) - { - std::array facets_on_surface; - if (m_c3t3.is_in_complex(cit)) - { - const double dh = min_dihedral_angle(tr(), cit); - if(dh < sliver_angle && is_peelable(m_c3t3, cit, facets_on_surface)) - peelable_cells.push_back(std::make_pair(cit, facets_on_surface)); - -#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE - mindh = (std::min)(dh, mindh); -#endif - } - } - -#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE - std::cout << "Min dihedral angle : " << mindh << std::endl; - std::cout << "Peelable cells : " << peelable_cells.size() << std::endl; -#endif - - for (auto c_i : peelable_cells) - { - Cell_handle c = c_i.first; - const std::array& f_on_surface = c_i.second; - - std::optional patch; - for (int i = 0; i < 4; ++i) - { - if (f_on_surface[i]) - { - Surface_patch_index spi = m_c3t3.surface_patch_index(c, i); - if (patch != std::nullopt && patch != spi) - { - patch = std::nullopt; - break; - } - else - { - patch = spi; - } - } - } - if(patch == std::nullopt) - continue; - - for (int i = 0; i < 4; ++i) - { - if(f_on_surface[i]) - m_c3t3.remove_from_complex(c, i); - else - m_c3t3.add_to_complex(c, i, patch.value()); - } - - m_c3t3.remove_from_complex(c); - ++nb_slivers_peel; - } + const std::size_t nb_peeled + = CGAL::Tetrahedral_remeshing::peel_slivers(m_c3t3, sliver_angle, m_cell_selector); #ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG CGAL_assertion(tr().tds().is_valid(true)); @@ -360,21 +302,8 @@ public: #ifdef CGAL_DUMP_REMESHING_STEPS CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "99-postprocess"); #endif -#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE - mindh = 180.; - for (Cell_handle cit : tr().finite_cell_handles()) - { - if (m_c3t3.is_in_complex(cit)) - { - const double dh = min_dihedral_angle(tr(), cit); - mindh = (std::min)(dh, mindh); - } - } - std::cout << "Peeling done (removed " << nb_slivers_peel << " slivers, " - << "min dihedral angle = " << mindh << ")." << std::endl; -#endif - return nb_slivers_peel; + return nb_peeled; } void finalize() @@ -471,17 +400,8 @@ private: const Curve_index default_curve_id = default_curve_index(); for (const Edge& e : tr().finite_edges()) { - if (m_c3t3.is_in_complex(e)) - { - CGAL_assertion(m_c3t3.in_dimension(e.first->vertex(e.second)) <= 1); - CGAL_assertion(m_c3t3.in_dimension(e.first->vertex(e.third)) <= 1); -#ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG - ++nbe; -#endif - continue; - } - if (get(ecmap, CGAL::Tetrahedral_remeshing::make_vertex_pair(e)) + || m_c3t3.is_in_complex(e) || nb_incident_subdomains(e, m_c3t3) > 2 || nb_incident_surface_patches(e, m_c3t3) > 1) { @@ -539,6 +459,7 @@ private: CGAL::Tetrahedral_remeshing::debug::dump_vertices_by_dimension( m_c3t3.triangulation(), "0-c3t3_vertices_after_init_"); CGAL::Tetrahedral_remeshing::debug::check_surface_patch_indices(m_c3t3); + CGAL::Tetrahedral_remeshing::debug::count_far_points(m_c3t3); #endif } diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h index f566ab1890f..9ea06ce7d4e 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h @@ -568,6 +568,8 @@ void set_index(typename C3t3::Vertex_handle v, const C3t3& c3t3) case 0: v->set_index(Mesh_3::internal::get_index(v->index())); break; + case -1://far points from concurrent Mesh_3 + break; default: CGAL_assertion(false); } @@ -589,6 +591,27 @@ bool is_edge_in_complex(const typename C3t3::Vertex_handle& v0, return false; } +template +bool protecting_balls_intersect(const typename C3t3::Edge& e, + const C3t3& c3t3) +{ + const auto vv = c3t3.triangulation().vertices(e); + if( c3t3.in_dimension(vv[0]) > 1 + || c3t3.in_dimension(vv[1]) > 1) + return false; + + const auto& p0 = vv[0]->point(); + const auto& p1 = vv[1]->point(); + if(p0.weight() == 0 || p1.weight() == 0) + return false; + + const auto r0 = CGAL::approximate_sqrt(p0.weight()); + const auto r1 = CGAL::approximate_sqrt(p1.weight()); + const auto d = CGAL::approximate_sqrt(CGAL::squared_distance(p0, p1)); + + return d < r0 + r1; +} + template OutputIterator incident_subdomains(const typename C3t3::Vertex_handle v, const C3t3& c3t3, @@ -1268,6 +1291,18 @@ void check_surface_patch_indices(const C3t3& c3t3) } } +template +void count_far_points(const C3t3& c3t3) +{ + std::size_t count = 0; + for (auto v : c3t3.triangulation().finite_vertex_handles()) + { + if(c3t3.in_dimension(v) == -1) + ++count; + } + std::cout << "Nb far points : " << count << std::endl; +} + template bool are_cell_orientations_valid(const Tr& tr) { @@ -1678,13 +1713,17 @@ void dump_vertices_by_dimension(const Tr& tr, const char* prefix) typedef typename Tr::Vertex_handle Vertex_handle; std::vector< std::vector > vertices_per_dimension(4); + std::size_t nb_far_points = 0; for (typename Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin(); vit != tr.finite_vertices_end(); ++vit) { if (vit->in_dimension() == -1) + { + ++nb_far_points; continue;//far point + } CGAL_assertion(vit->in_dimension() >= 0 && vit->in_dimension() < 4); vertices_per_dimension[vit->in_dimension()].push_back(vit); @@ -1712,6 +1751,7 @@ void dump_vertices_by_dimension(const Tr& tr, const char* prefix) ofs.close(); } + std::cout << "Nb far points : " << nb_far_points << std::endl; } template diff --git a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h index 8a8ebe925b3..d11d72973b6 100644 --- a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h +++ b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h @@ -310,21 +310,64 @@ void tetrahedral_isotropic_remeshing( * @tparam CurveIndex is the type of the indices for feature curves. * If `c3t3` has been generated using `CGAL::make_mesh_3()`, it must match * `MeshDomainWithFeatures_3::Curve_index`. +* @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * * @param c3t3 the complex containing the triangulation to be remeshed. +* @param np optional sequence of \ref bgl_namedparameters "Named Parameters" +* among the ones listed below +* +* \cgalNamedParamsBegin +* \cgalParamNBegin{edge_is_constrained_map} +* \cgalParamDescription{a property map containing the constrained-or-not status of each edge of +* `c3t3.triangulation()`. +* For each edge `e` for which `c3t3.is_in_complex(e)` returns `true`, +* the constrained status of `e` is set to `true`.} +* \cgalParamType{a class model of `ReadWritePropertyMap` +* with `std::pair` +* as key type and `bool` as value type. It must be default constructible.} +* \cgalParamDefault{a default property map where no edge is constrained} +* \cgalParamNEnd +* +* \cgalNamedParamsEnd */ template + typename CurveIndex, + typename NamedParameters = parameters::Default_named_parameters> CGAL::Triangulation_3 convert_to_triangulation_3( - CGAL::Mesh_complex_3_in_triangulation_3 c3t3) + CGAL::Mesh_complex_3_in_triangulation_3 c3t3, + const NamedParameters& np = parameters::default_values()) { + using parameters::get_parameter; + using parameters::choose_parameter; + using GT = typename Tr::Geom_traits; using TDS = typename Tr::Triangulation_data_structure; + using Vertex_handle = typename Tr::Vertex_handle; + using Edge_vv = std::pair; + using Default_pmap = Constant_property_map; + using ECMap = typename internal_np::Lookup_named_param_def < + internal_np::edge_is_constrained_t, + NamedParameters, + Default_pmap + >::type; + ECMap ecmap = choose_parameter(get_parameter(np, internal_np::edge_is_constrained), + Default_pmap(false)); + + if (!std::is_same_v) + { + for (auto e : c3t3.edges_in_complex()) + { + const Edge_vv evv + = CGAL::Tetrahedral_remeshing::make_vertex_pair(e);//ordered pair + put(ecmap, evv, true); + } + } + CGAL::Triangulation_3 tr; tr.swap(c3t3.triangulation()); return tr; diff --git a/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h index a96be0e6d76..52c14ea54b7 100644 --- a/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h @@ -413,10 +413,8 @@ public: insert( boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =nullptr ) { diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h index 048b373187e..884644147f1 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -34,7 +34,6 @@ #include #include -#include #include #include @@ -96,9 +95,10 @@ namespace internal { template struct Itag { - typedef typename boost::mpl::if_::Is_exact, - Exact_intersections_tag, - Exact_predicates_tag>::type type; + using Is_exact = typename Algebraic_structure_traits::Is_exact; + typedef std::conditional_t type; }; } // namespace internal @@ -330,11 +330,11 @@ public: #if 1 template static decltype(auto) get_source(const Segment_2& segment){ - return segment.source(); + return segment[0]; } template static decltype(auto) get_target(const Segment_2& segment){ - return segment.target(); + return segment[1]; } static const Point& get_source(const Constraint& cst){ diff --git a/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h index 34a282b9162..617e8c23a8a 100644 --- a/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h @@ -385,10 +385,8 @@ public: insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* = nullptr) { return insert_with_info< boost::tuple::type> >(first,last); diff --git a/Triangulation_2/include/CGAL/Regular_triangulation_2.h b/Triangulation_2/include/CGAL/Regular_triangulation_2.h index f7e4a653060..3353b7d7603 100644 --- a/Triangulation_2/include/CGAL/Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Regular_triangulation_2.h @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -529,10 +528,8 @@ public: insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - typename std::is_convertible< typename std::iterator_traits::value_type, Weighted_point >, - typename std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Weighted_point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =nullptr ) {return insert_with_info< boost::tuple::type> >(first,last);} diff --git a/Triangulation_2/include/CGAL/Triangulation_2.h b/Triangulation_2/include/CGAL/Triangulation_2.h index c79aa0128d2..14e8604640f 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_2.h @@ -710,10 +710,8 @@ public: insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* = NULL) { return insert_with_info< boost::tuple::type> >(first,last); diff --git a/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h b/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h index 93e00b1680f..29513248384 100644 --- a/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h b/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h index 8b22fddd349..63ade11b5e8 100644 --- a/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h @@ -494,10 +494,8 @@ public: insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =nullptr) { return insert_with_info< boost::tuple #endif -#include #include #include #include @@ -613,10 +612,9 @@ public: insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - typename std::is_convertible< typename std::iterator_traits::value_type, Weighted_point >, - typename std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value >* =nullptr) + std::is_convertible_v< typename std::iterator_traits::value_type, Weighted_point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > + >* =nullptr) { return insert_with_info< boost::tuple #include -#include #include namespace CGAL { diff --git a/Triangulation_3/include/CGAL/Robust_weighted_circumcenter_filtered_traits_3.h b/Triangulation_3/include/CGAL/Robust_weighted_circumcenter_filtered_traits_3.h index 0ab43248e21..beddf4c0b3d 100644 --- a/Triangulation_3/include/CGAL/Robust_weighted_circumcenter_filtered_traits_3.h +++ b/Triangulation_3/include/CGAL/Robust_weighted_circumcenter_filtered_traits_3.h @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace CGAL { @@ -531,6 +532,13 @@ public: Robust_circumcenter_filtered_traits_3(const Kernel& k = Kernel()) : Kernel(k) { } }; + +template < class BaseGt > +struct Triangulation_structural_filtering_traits > { + typedef typename Triangulation_structural_filtering_traits::Use_structural_filtering_tag Use_structural_filtering_tag; +}; + + template class Robust_weighted_circumcenter_filtered_traits_3 : public Robust_circumcenter_filtered_traits_3 diff --git a/Triangulation_3/include/CGAL/Triangulation_3.h b/Triangulation_3/include/CGAL/Triangulation_3.h index 55f917036af..12e92b65447 100644 --- a/Triangulation_3/include/CGAL/Triangulation_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_3.h @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include @@ -1224,10 +1223,8 @@ public: insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =NULL) { return insert_with_info< boost::tuple #include #include -#include #include #include @@ -331,10 +330,8 @@ public: insert( boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =nullptr ) { diff --git a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h index 78b8822f598..01f08ac186c 100644 --- a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h +++ b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h @@ -25,7 +25,6 @@ #include #include -#include #include #include diff --git a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h index e93418c19cf..20c4351bc49 100644 --- a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h +++ b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h @@ -16,7 +16,6 @@ #include #include -#include template diff --git a/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp b/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp index e4f80d9149f..c1b00d9aca9 100644 --- a/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp +++ b/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp @@ -37,9 +37,9 @@ struct Tester void test_iterator_on_pair() const { typedef std::vector > Container; - typedef typename boost::mpl::if_, - std::add_const_t, - Container>::type Cast_type; + typedef std::conditional_t, + Container> Cast_type; Container points; points.push_back(std::make_pair(Weighted_point(Bare_point(0.160385, 0.599679, 0.374932), -0.118572), 0)); @@ -90,9 +90,9 @@ struct Tester void test_zip_iterator() const { typedef std::vector Container; - typedef typename boost::mpl::if_, - std::add_const_t, - Container >::type Cast_type; + typedef std::conditional_t, + Container > Cast_type; Container points; points.push_back(Weighted_point(Bare_point(0,0,0),1)); @@ -156,9 +156,9 @@ struct Tester void test_transform_iterator() const { typedef std::vector< Weighted_point > Container; - typedef typename boost::mpl::if_, - std::add_const_t, - Container >::type Cast_type; + typedef std::conditional_t, + Container > Cast_type; Container points; points.push_back(Weighted_point(Bare_point(0,0,0),1));