Merge pull request #7883 from janetournois/Mesh_3-update_benchmark-jtournois

Mesh_3 - update benchmark
This commit is contained in:
Laurent Rineau 2024-05-31 11:10:47 +02:00
commit 5ffa817b62
23 changed files with 2658 additions and 1649 deletions

View File

@ -4,52 +4,18 @@
cmake_minimum_required(VERSION 3.1...3.23) cmake_minimum_required(VERSION 3.1...3.23)
project(Mesh_3_benchmark) project(Mesh_3_benchmark)
# Creates a new CMake option, turned ON by default find_package(CGAL REQUIRED COMPONENTS ImageIO)
option(ACTIVATE_MSVC_PRECOMPILED_HEADERS "Activate precompiled headers in MSVC"
OFF)
# Macro to add precompiled headers for MSVC
# This function does two things:
# 1. Enable precompiled headers on each file which is listed in "SourcesVar".
# 2. Add the content of "PrecompiledSource" (e.g. "StdAfx.cpp") to "SourcesVar".
macro(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource
SourcesVar)
if(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS)
get_filename_component(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
set(Sources ${${SourcesVar}})
set_source_files_properties(
${PrecompiledSource} PROPERTIES COMPILE_FLAGS
"/Yc\"${PrecompiledHeader}\"")
set_source_files_properties(
${Sources}
PROPERTIES COMPILE_FLAGS
"/Yu\"${PrecompiledHeaders}\" /FI\"${PrecompiledHeader}\"")
# Add precompiled header to SourcesVar
list(APPEND ${SourcesVar} ${PrecompiledSource})
endif(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS)
endmacro(ADD_MSVC_PRECOMPILED_HEADER)
# The compiler might need more memory because of precompiled headers
if(MSVC
AND ACTIVATE_MSVC_PRECOMPILED_HEADERS
AND NOT (MSVC_VERSION LESS 1310))
set(CGAL_C_FLAGS "${CGAL_C_FLAGS} /Zm1000")
set(CGAL_CXX_FLAGS "${CGAL_CXX_FLAGS} /Zm1000")
endif()
include_directories(../../../Triangulation_3/include)
include_directories(../../../STL_Extension/include)
include_directories(../../../AABB_tree/include)
add_definitions(-DCGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX add_definitions(-DCGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX
-DCGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS) -DCGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS)
# Activate verbose mode? (turned OFF by default)
option(CGAL_ACTIVATE_CONCURRENT_MESH_3 "Activate verbose mode in Mesh_3" OFF)
if(MESH_3_VERBOSE) if(MESH_3_VERBOSE)
add_definitions(-DCGAL_MESH_3_VERBOSE) add_definitions(-DCGAL_MESH_3_VERBOSE)
endif() endif()
find_package(CGAL REQUIRED COMPONENTS ImageIO) # Activate concurrency? (turned OFF by default)
# Activate concurrency ? (turned OFF by default)
option(CGAL_ACTIVATE_CONCURRENT_MESH_3 "Activate parallelism in Mesh_3" OFF) option(CGAL_ACTIVATE_CONCURRENT_MESH_3 "Activate parallelism in Mesh_3" OFF)
# And add -DCGAL_CONCURRENT_MESH_3 if that option is ON # And add -DCGAL_CONCURRENT_MESH_3 if that option is ON
@ -58,8 +24,7 @@ if(CGAL_ACTIVATE_CONCURRENT_MESH_3)
find_package(TBB REQUIRED) find_package(TBB REQUIRED)
include(CGAL_TBB_support) include(CGAL_TBB_support)
else() else()
option(LINK_WITH_TBB option(LINK_WITH_TBB "Link with TBB anyway so we can use TBB timers for profiling" ON)
"Link with TBB anyway so we can use TBB timers for profiling" ON)
if(LINK_WITH_TBB) if(LINK_WITH_TBB)
find_package(TBB) find_package(TBB)
include(CGAL_TBB_support) include(CGAL_TBB_support)
@ -67,19 +32,18 @@ else()
endif() endif()
# Compilable benchmark # Compilable benchmark
set(BENCHMARK_SOURCE_FILES "concurrency.cpp") create_single_source_cgal_program("benchmark_mesh_3.cpp")
add_msvc_precompiled_header("StdAfx.h" "StdAfx.cpp" BENCHMARK_SOURCE_FILES)
create_single_source_cgal_program(${BENCHMARK_SOURCE_FILES})
if(TARGET CGAL::TBB_support) if(TARGET CGAL::TBB_support)
target_link_libraries(concurrency PUBLIC CGAL::TBB_support) target_link_libraries(benchmark_mesh_3 PUBLIC CGAL::TBB_support)
endif() endif()
# Link with Boost.ProgramOptions (optional) # Link with Boost.ProgramOptions (optional)
find_package(Boost QUIET COMPONENTS program_options) find_package(Boost QUIET COMPONENTS program_options)
if(Boost_PROGRAM_OPTIONS_FOUND) if(Boost_PROGRAM_OPTIONS_FOUND)
if(TARGET Boost::program_options) if(TARGET Boost::program_options)
target_link_libraries(concurrency PRIVATE Boost::program_options) target_link_libraries(benchmark_mesh_3 PRIVATE Boost::program_options)
else() else()
target_link_libraries(concurrency PRIVATE ${Boost_PROGRAM_OPTIONS_LIBRARY}) target_link_libraries(benchmark_mesh_3 PRIVATE ${Boost_PROGRAM_OPTIONS_LIBRARY})
endif() endif()
endif() endif()

View File

@ -0,0 +1,161 @@
#!/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=""
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 == "-o":
outputdir = arg
elif opt == "-c":
commit_hash = arg
elif opt == "-d":
diff_hash = arg
do_diff = True
elif opt == "-p":
diffdir = arg
print("Generating performance charts for inputdir =", inputdir)
print("Outputdir =", outputdir)
print("Commit hash =", commit_hash)
print("Do diff =", do_diff)
print("Diff hash =", diff_hash)
print("Diffdir =", diffdir)
all_metric = {
"Facet_Scan_Time_(second)" : {},
"Facet_Refine_Time_(second)" : {},
"Cell_Scan_Time_(second)" : {},
"Cell_Refine_Time_(second)" : {},
"Lloyd_Time_(second)" : {},
"ODT_Time_(second)" : {},
"Perturber_Time_(second)" : {},
"Exuder_Time_(second)" : {},
"Total_Time_(second)" : {},
"Memory_Peak_(mbytes)" : {}}
num_input = 0
for filename in os.listdir(inputdir) :
mesh_id = str(filename.split('.')[0])
print("perf charting, filename", filename)
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_entry = new_file.readline().strip()
old_entry = old_file.readline().strip()
new_val = float(new_entry) if new_entry else 0.
old_val = float(old_entry) if old_entry else 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_entry = new_file.readline().strip()
new_val = float(new_entry) if new_entry else 0.
all_metric[key][mesh_id] = [new_val, new_val]
num_input = num_input+1
if num_input == 0 :
sys.exit(0)
# 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"
else :
title += "Benchmarking on " + str(num_input) + " meshes"
avg_str = str(format(abs(avg), '.4f'))
if key == "Memory_Peak_(mbytes)" :
title += "\nIn average we use up to " + avg_str + " mbytes"
else :
title += "\nIn average we spend " + avg_str + " seconds"
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), '.4f'))
if key == "Memory_Peak_(mbytes)" :
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 += " mbytes"
else :
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"
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("Performance charts have been generated")
sys.exit()
if __name__ == "__main__":
main(sys.argv[1:])

View File

@ -0,0 +1,244 @@
# 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=""
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 == "-o":
outputdir = arg
elif opt == "-c":
commit_hash = arg
elif opt == "-d":
diff_hash = arg
do_diff = True
elif opt == "-p":
diffdir = arg
print("Generating quality charts for inputdir =", inputdir)
print("Outputdir =", outputdir)
print("Commit hash =", commit_hash)
print("Do diff =", do_diff)
print("Diff hash =", diff_hash)
print("Diffdir =", diffdir)
all_metric = {
"Complexity_(#_of_Vertices)" : {},
"Complexity_(#_of_Facets)" : {},
"Complexity_(#_of_Cells)" : {},
"Minimum_Edge_Length_" : {},
"Mean_Edge_Length_" : {},
"Maximum_Edge_Length_" : {},
"Minimum_Facet_Area_" : {},
"Mean_Facet_Area_" : {},
"Maximum_Facet_Area_" : {},
"Total_Area_" : {},
"Minimum_Facet_Angle_(degree)" : {},
"Maximum_Facet_Angle_(degree)" : {},
"Minimum_Cell_Volume_" : {},
"Mean_Cell_Volume_" : {},
"Maximum_Cell_Volume_" : {},
"Total_Volume_" : {},
"Minimum_Cell_Angle_(degree)" : {},
"Mean_Cell_Angle_(degree)" : {},
"Maximum_Cell_Angle_(degree)" : {},
"Smallest_edge_radius_ratio" : {},
"Smallest_radius_radius_ratio" : {},
"Bigget_V_SMA" : {}}
num_input = 0
for filename in os.listdir(inputdir) :
mesh_id = str(filename.split('.')[0])
new_path = os.path.join(inputdir,filename)
print("new_path?", new_path)
new_file = open(new_path)
is_empty_new = os.path.getsize(new_path) <= 1
print("is_empty_new?", is_empty_new)
if do_diff :
old_path = os.path.join(diffdir,filename)
old_file = open(old_path)
is_empty_old = os.path.getsize(old_path) <= 1
print("is_empty_old?", is_empty_old)
for key in all_metric :
if is_empty_new or is_empty_old :
new_val = 0.
old_val = 0.
else :
new_entry = new_file.readline().strip()
old_entry = old_file.readline().strip()
new_val = float(new_entry) if new_entry else 0.
old_val = float(old_entry) if old_entry else 0.
print("new entry, val", new_entry, new_val)
print("old entry, val", new_entry, new_val)
all_metric[key][mesh_id] = [new_val, old_val]
else :
for key in all_metric :
if is_empty_new :
new_val = 0.
else :
new_entry = new_file.readline().strip()
new_val = float(new_entry) if new_entry else 0.
all_metric[key][mesh_id] = [new_val, new_val]
num_input = num_input+1
if num_input == 0 :
sys.exit(0)
# 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 == "Minimum_Facet_Angle_(degree)" or key == "Maximum_Facet_Angle_(degree)" :
goal = 60.
elif key == "Minimum_Cell_Angle_(degree)" or key == "Mean_Cell_Angle_(degree)" or key == "Maximum_Cell_Angle_(degree)" :
goal = 70.5 # for a regular tetrahedron
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"
else :
title += "Benchmarking on " + str(num_input) + " meshes"
avg_str = str(format(abs(avg), '.4f'))
if key == "Complexity_(#_of_Vertices)":
title += "\nIn average we have " + avg_str + " vertices"
elif key == "Complexity_(#_of_Facets)":
title += "\nIn average we have " + avg_str + " facets"
elif key == "Complexity_(#_of_Cells)":
title += "\nIn average we have " + avg_str + " cells"
elif key == "Minimum_Edge_Length_":
title += "\nIn average we have a minimum edge length of " + avg_str
elif key == "Mean_Edge_Length_":
title += "\nIn average we have an average edge length of " + avg_str
elif key == "Maximum_Edge_Length_":
title += "\nIn average we have a maximum edge of length " + avg_str
elif key == "Minimum_Facet_Area_":
title += "\nIn average we have a minimum facet area of " + avg_str
elif key == "Mean_Facet_Area_":
title += "\nIn average we have an average facet area of " + avg_str
elif key == "Maximum_Facet_Area_":
title += "\nIn average we have a maximum facet area of " + avg_str
elif key == "Total_Area_":
title += "\nIn average we have a total area of " + avg_str
elif key == "Minimum_Facet_Angle_(degree)":
title += "\nIn average we have a minimum facet angle of " + avg_str + "°"
elif key == "Maximum_Facet_Angle_(degree)":
title += "\nIn average we have a maximum facet angle of " + avg_str + "°"
elif key == "Minimum_Cell_Volume_":
title += "\nIn average we have a minimum cell volume of " + avg_str
elif key == "Mean_Cell_Volume_":
title += "\nIn average we have an average cell volume of " + avg_str
elif key == "Maximum_Cell_Volume_":
title += "\nIn average we have a maximum cell volume " + avg_str
elif key == "Total_Volume_":
title += "\nIn average we have a total volume of " + avg_str
elif key == "Minimum_Cell_Angle_(degree)":
title += "\nIn average we have a minimum dihedral angle of " + avg_str + "°"
elif key == "Mean_Cell_Angle_(degree)":
title += "\nIn average we have an average dihedral angle of " + avg_str + "°"
elif key == "Maximum_Cell_Angle_(degree)":
title += "\nIn average we have a maximum dihedral angle of " + avg_str + "°"
elif key == "Smallest_edge_radius_ratio":
title += "\nIn average we have a minimum edge radius ratio of " + avg_str
elif key == "Smallest_radius_radius_ratio":
title += "\nIn average we have a minimum radius radius ratio of " + avg_str
elif key == "Bigget_V_SMA":
title += "\nIn average we have a maximum V_SMA of " + avg_str
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), '.4f'))
if key == "Minimum_Facet_Angle_(degree)" or key == "Maximum_Facet_Angle_(degree)":
if avg_diff_to_goal < 0 :
title += "\nIn average we lose "
else :
title += "\nIn average we gain "
title += avg_diff_str + "° toward 60°"
elif key == "Minimum_Cell_Angle_(degree)" or key == "Mean_Cell_Angle_(degree)" or key == "Maximum_Cell_Angle_(degree)":
if avg_diff_to_goal < 0 :
title += "\nIn average we lose "
else :
title += "\nIn average we gain "
title += avg_diff_str + "° toward 70.5°"
else :
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 += " " + key.replace("_"," ")
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("Quality charts have been generated")
sys.exit()
if __name__ == "__main__":
main(sys.argv[1:])

View File

@ -0,0 +1,127 @@
#!/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=""
try:
opts, args = getopt.getopt(sys.argv[1:], 'i:o:c:')
except getopt.GetoptError:
sys.exit(2)
for opt, arg in opts:
if opt == "-i":
inputdir = arg
elif opt == "-o":
outputdir = arg
elif opt == "-c":
commit_hash = arg
print("Generating performance charts for inputdir =", inputdir)
print("Outputdir =", outputdir)
print("Commit hash =", commit_hash)
exit_codes = {
0 : "VALID_SOLID_OUTPUT",
1 : "INPUT_IS_INVALID",
2 : "OUTPUT_IS_INVALID",
3 : "SIGSEGV",
4 : "SIGABRT",
5 : "SIGFPE",
6 : "TIMEOUT"
}
current_run_data = {
"VALID_SOLID_OUTPUT" : 0,
"INPUT_IS_INVALID" : 0,
"OUTPUT_IS_INVALID" : 0,
"SIGSEGV" : 0,
"SIGABRT" : 0,
"SIGFPE" : 0,
"TIMEOUT" : 0
}
filenames_per_codes = {}
for key in current_run_data :
filenames_per_codes[key] = []
num_input = 0
for filename in os.listdir(inputdir) :
print("filename = ", filename)
f = open(os.path.join(inputdir,filename))
status = f.readline().strip();
current_run_data[status] += 1
filenames_per_codes[status].append(filename.rstrip('.log'))
num_input = num_input+1
# sort current_run_data by value
current_run_data = {k: v for k, v in sorted(current_run_data.items(), key=lambda item: item[1], reverse=True)}
# update chart data files
date_now = datetime.datetime.now()
date = str(date_now.year) +"-"+ str(date_now.month) +"-"+ str(date_now.day) +" "+ str(date_now.hour) +"h"+ str(date_now.minute) +"mn"
for key_filename in current_run_data:
f = open(os.path.join(outputdir+"/charts_data", key_filename+".txt"), "a+")
f.write(str(current_run_data[key_filename]) + " " + commit_hash + " " + date + "\n")
print("chart data updated")
# update .pdf chart
chart = plt.figure(figsize=(10, 7))
colormap = ["tab:blue","tab:orange","tab:green","tab:red","tab:purple","tab:brown","tab:pink","tab:gray","tab:olive","tab:cyan","b","palegreen", "peachpuff"]
plt.gca().set_prop_cycle('color', colormap)
plt.style.use('tableau-colorblind10')
for key_filename in current_run_data:
f = open(os.path.join(outputdir+"/charts_data", key_filename+".txt"), "r")
lines = f.readlines()
x_number_values = []
y_number_values = []
i = 0
for line in lines :
if i < (len(lines) - 10) :
i=i+1
continue
i=i+1
words = line.strip().split()
x_number_values.append(words[1]+"\n"+words[2]+"\n"+words[3])
y_number_values.append(int(words[0]))
plt.plot(x_number_values, y_number_values, marker='o', label=key_filename+": "+str(current_run_data[key_filename]))
plt.xlabel("Version", fontsize=14)
plt.ylabel("# of mesh", fontsize=14)
plt.tick_params(axis="both", labelsize=9)
plt.title("Benchmarking on " + str(num_input) + " meshes", fontsize=15)
plt.legend(loc='lower left', bbox_to_anchor= (1.01, 0.58), ncol=1,
borderaxespad=0, frameon=False)
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"
chart_filename = os.path.join(outputdir+"/charts","benchmarking_version_"+commit_hash+"-"+date_for_filename+".pdf")
if os.path.isfile(chart_filename) :
os.remove(chart_filename)
chart.savefig(chart_filename, bbox_inches="tight")
plt.close(chart)
print("Robustness charts have been generated")
# dump filenames per codes
log_dirname = os.path.join(outputdir, "logs/"+commit_hash+"-"+date_for_filename)
if not os.path.exists(log_dirname):
os.mkdir(log_dirname)
for key in filenames_per_codes :
file = open(os.path.join(log_dirname, key+".txt"), "w+")
for filename in filenames_per_codes[key] :
file.write(filename + "\n")
file.close()
sys.exit()
if __name__ == "__main__":
main(sys.argv[1:])

View File

@ -0,0 +1,192 @@
#!/bin/bash
# ###################################################################################################
# # INTRODUCTION
# ###################################################################################################
# This script is meant to benchmark Mesh_3 over a directory of data files (e.g. Thingi10k/raw_meshes)
# with unique names. It checks a number of metrics in 3 categories: Robustness (did it finish without
# errors, and did it produce a valid result?), Performance (how long did it take to run?), and Quality
# (how good is the result mesh?).
#
# This script gives access to the mesh criteria for convenience, but all the other parameters
# are fixed and chosen two configuration files.
#
# If `benchmark_mesh_3.cpp` is in parallel mode, you should use a single thread.
# You also probably don't want to use "BENCHMARK_WITH_1_TO_MAX_THREADS", so be sure it's off.
#
# ###################################################################################################
# # QUICK START
# ###################################################################################################
#
# Set up your preferences in the files:
# - CGAL_root/Mesh_3/benchmark/Mesh_3/benchmarking_config.h (Mesh_3 options)
# - CGAL_root/Mesh_3/benchmark/Mesh_3/concurrent_mesher_config.cfg (parallel options)
#
# Compile benchmark_mesh_3.cpp in a folder called `build-release`
# Go to Mesh_3/benchmark/Mesh_3/Charting
#
# Call:
# sh benchmarking.sh $1 ... $12
# Arguments:
# $1: directory containing the Mesh_3 project (i.e. CGAL_root)
# $2: directory containing the input data folder (e.g. "~/Data/Thingi10k/raw_meshes")
# $3: directory containing the output results (recommended to be CGAL_root/Mesh_3/benchmark/Mesh_3/Charting)
# $4: facet size
# $5: facet distance
# $6: facet angle
# $7: cell size
# $8: cell radius-edge ratio
# $9: timeout value (in seconds)
# $10: number of threads used (runs multiple data in parallel. Do NOT use if benching parallel mode!!)
# $11: test identifier (e.g. hash of the last commit)
# $12: test identifier of a previous test, to perform the difference with ${11} [optional]
#
# Find the result in the output_dir/charts.
#
# ###################################################################################################
# # SCRIPT DETAILS
# ###################################################################################################
# The script generates data by calling `run_benchmark.py`, which runs `benchmark_mesh_3.cpp`.
# The data is written in an XML file (see the macro CGAL_MESH_3_SET_PERFORMANCE_DATA
# and the file benchmark.xml). One XML file per input data.
# The XML file is parsed by the scripts `generate_[robustness|performance|quality]_benchmark_charts.py`
# to generate individual charts for each metric, which are then merged together at the end
# of this script.
#
# To add a new metric to the benchmark, one must:
# - Add it into the benchmark.xml
# - Measure it (either in Mesh_3/include, or in benchmark_mesh_3.cpp) and log it with the macro
# CGAL_MESH_3_SET_PERFORMANCE_DATA.
# - Parse it and plot it in the corresponding script (e.g. generate_robustness_benchmark_charts.py)
# - change the "tail -n" at the end of this file, and the "3x10" (layout of the final chart)
# ###################################################################################################
# # TODO
# ###################################################################################################
# - Make it work for other OS
# - Other metrics (edge radius ratio, Hausdorff distance)
# --------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------
# $1: directory containing the Mesh_3 project
# $2: directory containing the output results
# $3: facet size
# $4: facet distance
# $5: facet angle
# $6: cell size
# $7: cell radius-edge ratio
# $8: timeout value (in seconds)
# $9: test identifier (e.g. hash of the last commit)
# $10: the input file path
function compute_benchmark_data() {
filename=$(basename -- "${10}")
filename="${filename%.*}"
# print filename:
echo "param #1 (directory containing the Mesh_3 project): " $1
echo "param #2 (directory containing the output results): " $2
echo "param #3 (facet size): " $3
echo "param #4 (facet distance): " $4
echo "param #5 (facet angle): " $5
echo "param #6 (cell size): " $6
echo "param #7 (cell radius-edge ratio): " $7
echo "param #8 (timeout value): " $8
echo "param #9 (test ID): " $9
echo "param #10 (the input file path): " ${10}
python3 $1/Mesh_3/benchmark/Mesh_3/Charting/run_benchmark.py \
--exec $1/Mesh_3/benchmark/Mesh_3/build-release/benchmark_mesh_3 \
-i ${10} \
--facet_size $3 --facet_approx $4 --facet_angle $5 \
--cell_size $6 --cell_shape $7 -t $8 \
--out $2 \
--test_ID $9 \
> $2/logs/$9/$filename.log
}
export -f compute_benchmark_data
echo "param #1 (directory containing the Mesh_3 project): " $1
echo "param #2 (directory containing the input data folder): " $2
echo "param #3 (directory containing the output results): " $3
echo "param #4 (facet size): " $4
echo "param #5 (facet distance): " $5
echo "param #6 (facet angle): " $6
echo "param #7 (cell size): " $7
echo "param #8 (cell radius-edge ratio): " $8
echo "param #9 (timeout value): " $9
echo "param #10 (number of threads used): " ${10}
echo "param #11 (test ID): " ${11}
echo "param #12 (another test ID, to perform the difference with ${11}): " ${12}
echo "---------------------------------"
echo $# "argument(s) provided."
if [[ $# -lt 11 ]]; then
echo "Expected 12 arguments, see list above."
exit 1
fi
# just for convenience: remove everything
# rm $3/*.mesh
# rm -rf $3/Robustness/logs
# rm -rf $3/Robustness/results
# rm -rf $3/Robustness/charts_data
# rm -rf $3/Robustness/charts
# rm -rf $3/Quality/logs
# rm -rf $3/Quality/results
# rm -rf $3/Quality/charts
# rm -rf $3/Performance/logs
# rm -rf $3/Performance/results
# rm -rf $3/Performance/charts
# rm -rf $3/logs
# rm -rf $3/charts
# exit
rm -rf $3/Robustness/logs/${11}
rm -rf $3/Robustness/results/${11}
rm -rf $3/Quality/logs/${11}
rm -rf $3/Quality/results/${11}
rm -rf $3/Performance/logs/${11}
rm -rf $3/Performance/results/${11}
mkdir -p $3/Robustness/logs/${11}
mkdir -p $3/Robustness/results/${11}
mkdir -p $3/Robustness/charts_data
mkdir -p $3/Robustness/charts
mkdir -p $3/Quality/logs/${11}
mkdir -p $3/Quality/results/${11}
mkdir -p $3/Quality/charts
mkdir -p $3/Performance/logs/${11}
mkdir -p $3/Performance/results/${11}
mkdir -p $3/Performance/charts
mkdir -p $3/logs/${11}
mkdir -p $3/charts
rm $3/Robustness/results/${11}/* # only for that one, others need to keep their results in case of diff
find $2 -mindepth 1 | parallel -j${10} compute_benchmark_data $1 $3 $4 $5 $6 $7 $8 $9 ${11} :::
python3 $1/Mesh_3/benchmark/Mesh_3/Charting/Robustness/generate_robustness_benchmark_charts.py -i $3/Robustness/results/${11} -o $3/Robustness -c ${11}
if [ -z "${12}" ]; then
python3 $1/Mesh_3/benchmark/Mesh_3/Charting/Performance/generate_performance_benchmark_charts.py -i $3/Performance/results/${11} -o $3/Performance -c ${11};
else
python3 $1/Mesh_3/benchmark/Mesh_3/Charting/Performance/generate_performance_benchmark_charts.py -i $3/Performance/results/${11} -o $3/Performance -c ${11} -p $3/Performance/results/${12} -d ${12};
fi
if [ -z "${12}" ]; then
python3 $1/Mesh_3/benchmark/Mesh_3/Charting/Quality/generate_quality_benchmark_charts.py -i $3/Quality/results/${11} -o $3/Quality -c ${11};
else
python3 $1/Mesh_3/benchmark/Mesh_3/Charting/Quality/generate_quality_benchmark_charts.py -i $3/Quality/results/${11} -o $3/Quality -c ${11} -p $3/Quality/results/${12} -d ${12};
fi
charts_path="$(ls "$3/Robustness/charts"/* -dArt | tail -n 1) $(ls "$3/Performance/charts"/* -dArt | tail -n 10) $(ls "$3/Quality/charts"/* -dArt | tail -n 22)"
pdfjam --nup 3x11 $charts_path --outfile $3/charts/results_${11}_${12}_$(date '+%Y-%m-%d_%H:%M:%S').pdf

View File

@ -0,0 +1,269 @@
#!/usr/bin/python
import os, sys, subprocess, datetime, time, signal, getopt
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import XMLParser
####################################################################################################
def signal_handler(signum, frame):
raise Exception("Timed out!")
####################################################################################################
def run_benchmark(execname, filename, facet_size, facet_approx, facet_angle, cell_size, cell_shape, max_time, test_ID, outpath):
exit_codes = {
0 : "VALID_SOLID_OUTPUT",
1 : "INPUT_IS_INVALID",
2 : "OUTPUT_IS_INVALID",
3 : "SIGSEGV",
4 : "SIGABRT",
5 : "SIGFPE",
6 : "TIMEOUT"
}
raw_filename = os.path.splitext(os.path.basename(filename))[0]
xml_filename = outpath + "/logs/" + test_ID + "/" + raw_filename + ".xml"
print("xml_filename = ", xml_filename)
exit_code = 0
output = ""
cmd = ("/usr/bin/time", "-v", execname, xml_filename, filename, facet_size, facet_approx, facet_angle, cell_size, cell_shape)
print("cmd = ", cmd)
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, start_new_session=True)
try:
outs, errs = proc.communicate(timeout=int(max_time))
exit_code = proc.returncode
output = outs.decode("utf-8") + errs.decode("utf-8")
print("output = ", output)
for output_line in output.split("\n"):
if output_line == "Command terminated by signal 11":
exit_code = 3
continue
elif output_line == "Command terminated by signal 6":
exit_code = 4
continue
elif output_line == "Command terminated by signal 8":
exit_code = 5
continue
except subprocess.TimeoutExpired:
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
exit_code = 6
output = "process ran too long"
print("EXIT CODE: ", exit_codes[exit_code])
outfile = outpath + "/Robustness/results/" + test_ID + "/" + raw_filename + ".txt"
print("writing to", outfile)
file = open(outfile, "w")
file.write(exit_codes[exit_code])
file.close()
return exit_code
####################################################################################################
def parse_xml_file(filename, tag):
tree = ET.parse(filename)
root = tree.getroot()
elems = root.findall(f'.//{tag}')
if len(elems) == 0:
print("Error: no elements found for ", tag)
return sys.exit(1)
elem = elems[0] # take the first
return elem.text.strip()
####################################################################################################
def main(argv):
execname=""
filename=""
facet_size=""
facet_approx=""
facet_angle=""
cell_size=""
cell_shape=""
max_time=""
test_ID=""
outpath=""
try:
opts, args = getopt.getopt(sys.argv[1:], 'i:t:', ["exec=", "facet_size=", "facet_approx=", "facet_angle=", "cell_size=", "cell_shape=", "test_ID=", "out="])
except getopt.GetoptError:
sys.exit(2)
for opt, arg in opts:
if opt == "--exec": # executable
execname = arg
elif opt == "-i": # filename
filename = arg
elif opt == "--facet_size":
facet_size = arg
elif opt == "--facet_approx":
facet_approx = arg
elif opt == "--facet_angle":
facet_angle = arg
elif opt == "--cell_size":
cell_size = arg
elif opt == "--cell_shape":
cell_shape = arg
elif opt == "-t":
max_time = arg
elif opt == "--test_ID":
test_ID = arg
elif opt == "--out": # output file
outpath = arg
print("execname = ", execname)
print("filename = ", filename)
print("facet_size = ", facet_size)
print("facet_approx = ", facet_approx)
print("facet_angle = ", facet_angle)
print("cell_size = ", cell_size)
print("cell_shape = ", cell_shape)
print("max_time = ", max_time)
print("test_ID = ", test_ID)
print("outpath = ", outpath)
exit_code = run_benchmark(execname, filename, facet_size, facet_approx, facet_angle, cell_size, cell_shape, max_time, test_ID, outpath)
# if the exit code is different from 0, then there is nothing to analyze
if exit_code != 0:
sys.exit(exit_code)
raw_filename = os.path.splitext(os.path.basename(filename))[0]
xml_filename = outpath + "/logs/" + test_ID + "/" + raw_filename + ".xml"
# Parse the XML output to extract performance and quality metrics
print("parsing", xml_filename)
parser = XMLParser(encoding="utf-8")
try:
ET.parse(xml_filename, parser)
print("XML is valid")
except Exception as e:
print("XML is invalid -", e)
# --- Performance
perf_results_filename = outpath + "/Performance/results/" + test_ID + "/" + raw_filename + ".txt"
perf_results = open(perf_results_filename, "w")
# Refinement
facet_scan_time = parse_xml_file(xml_filename, "Facets_scan_time")
facet_refine_time = parse_xml_file(xml_filename, "Facets_refine_time")
cell_scan_time = parse_xml_file(xml_filename, "Cells_scan_time")
cell_refine_time = parse_xml_file(xml_filename, "Cells_refine_time")
# Optimisation
lloyd_optim_time = parse_xml_file(xml_filename, "Lloyd_optim_time")
odt_optim_time = parse_xml_file(xml_filename, "Odt_optim_time")
perturber_optim_time = parse_xml_file(xml_filename, "Perturber_optim_time")
exuder_optim_time = parse_xml_file(xml_filename, "Exuder_optim_time")
# Total
total_time = parse_xml_file(xml_filename, "Total_time")
# Memory
memory = parse_xml_file(xml_filename, "Mem")
perf_results.write(facet_scan_time + "\n")
perf_results.write(facet_refine_time + "\n")
perf_results.write(cell_scan_time + "\n")
perf_results.write(cell_refine_time + "\n")
perf_results.write(lloyd_optim_time + "\n")
perf_results.write(odt_optim_time + "\n")
perf_results.write(perturber_optim_time + "\n")
perf_results.write(exuder_optim_time + "\n")
perf_results.write(total_time + "\n")
perf_results.write(memory + "\n")
perf_results.close()
# --- Quality
qual_results_filename = outpath + "/Quality/results/" + test_ID + "/" + raw_filename + ".txt"
qual_results = open(qual_results_filename, "w")
number_of_vertices = parse_xml_file(xml_filename, "V")
number_of_facets = parse_xml_file(xml_filename, "F")
number_of_cells = parse_xml_file(xml_filename, "C")
min_edge_size = parse_xml_file(xml_filename, "Minimum_edge_length")
mean_edge_size = parse_xml_file(xml_filename, "Mean_edge_length")
max_edge_size = parse_xml_file(xml_filename, "Maximum_edge_length")
min_facet_size = parse_xml_file(xml_filename, "Minimum_facet_area")
mean_facet_size = parse_xml_file(xml_filename, "Mean_facet_area")
max_facet_size = parse_xml_file(xml_filename, "Maximum_facet_area")
total_area = parse_xml_file(xml_filename, "Total_area")
# min_facet_distance = parse_xml_file(xml_filename, "Min_facet_distance")
# mean_facet_distance = parse_xml_file(xml_filename, "Mean_facet_distance")
# max_facet_distance = parse_xml_file(xml_filename, "Mean_facet_distance")
min_facet_angle = parse_xml_file(xml_filename, "Minimum_facet_angle")
max_facet_angle = parse_xml_file(xml_filename, "Maximum_facet_angle")
min_cell_size = parse_xml_file(xml_filename, "Minimum_cell_volume")
mean_cell_size = parse_xml_file(xml_filename, "Mean_cell_volume")
max_cell_size = parse_xml_file(xml_filename, "Maximum_cell_volume")
total_volume = parse_xml_file(xml_filename, "Total_volume")
min_cell_shape = parse_xml_file(xml_filename, "Minimum_dihedral_angle")
mean_cell_shape = parse_xml_file(xml_filename, "Mean_dihedral_angle")
max_cell_shape = parse_xml_file(xml_filename, "Maximum_dihedral_angle")
smallest_edge_radius_ratio = parse_xml_file(xml_filename, "Smallest_edge_radius_ratio")
smallest_radius_radius_ratio = parse_xml_file(xml_filename, "Smallest_radius_radius_ratio")
biggest_v_sma = parse_xml_file(xml_filename, "Biggest_V_SMA")
print("number_of_vertices = ", number_of_vertices)
print("number_of_facets = ", number_of_facets)
print("number_of_cells = ", number_of_cells)
print("min_edge_size = ", min_edge_size)
print("mean_edge_size = ", mean_edge_size)
print("max_edge_size = ", max_edge_size)
print("min_facet_size = ", min_facet_size)
print("mean_facet_size = ", mean_facet_size)
print("max_facet_size = ", max_facet_size)
print("total_area = ", total_area)
# print("min_facet_distance = ", min_facet_distance)
# print("mean_facet_distance = ", mean_facet_distance)
# print("max_facet_distance = ", max_facet_distance)
print("min_facet_angle = ", min_facet_angle)
print("max_facet_angle = ", max_facet_angle)
print("min_cell_size = ", min_cell_size)
print("mean_cell_size = ", mean_cell_size)
print("max_cell_size = ", max_cell_size)
print("total_volume = ", total_volume)
print("min_cell_shape = ", min_cell_shape)
print("mean_cell_shape = ", mean_cell_shape)
print("max_cell_shape = ", max_cell_shape)
print("smallest_edge_radius_ratio = ", smallest_edge_radius_ratio)
print("smallest_radius_radius_ratio = ", smallest_radius_radius_ratio)
print("biggest_v_sma = ", biggest_v_sma)
qual_results.write(number_of_vertices + "\n")
qual_results.write(number_of_facets + "\n")
qual_results.write(number_of_cells + "\n")
qual_results.write(min_edge_size + "\n")
qual_results.write(mean_edge_size + "\n")
qual_results.write(max_edge_size + "\n")
qual_results.write(min_facet_size + "\n")
qual_results.write(mean_facet_size + "\n")
qual_results.write(max_facet_size + "\n")
qual_results.write(total_area + "\n")
qual_results.write(min_facet_angle + "\n")
qual_results.write(max_facet_angle + "\n")
qual_results.write(min_cell_size + "\n")
qual_results.write(mean_cell_size + "\n")
qual_results.write(max_cell_size + "\n")
qual_results.write(total_volume + "\n")
qual_results.write(min_cell_shape + "\n")
qual_results.write(mean_cell_shape + "\n")
qual_results.write(max_cell_shape + "\n")
qual_results.write(smallest_edge_radius_ratio + "\n")
qual_results.write(smallest_radius_radius_ratio + "\n")
qual_results.write(biggest_v_sma + "\n")
qual_results.close()
if __name__ == "__main__":
main(sys.argv[1:])

View File

@ -1,2 +0,0 @@
// Build the precompiled headers.
#include "StdAfx.h"

View File

@ -1,273 +0,0 @@
#ifndef STDAFX_H
#define STDAFX_H
#include <cmath>
#include <cassert>
#include <crtdefs.h>
// STL
#include <algorithm>
#include <map>
#include <vector>
#include <stack>
#include <deque>
#include <fstream>
#include <typeindex>
#include <iterator>
// Windows
#include <windows.h>
// Boost
#include <boost/assert.hpp>
#include <boost/call_traits.hpp>
#include <boost/concept_archetype.hpp>
#include <boost/concept_check.hpp>
#include <boost/config.hpp>
#include <boost/format.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <CGAL/boost/iterator/transform_iterator.hpp>
#include <boost/iterator/zip_iterator.hpp>
#include <boost/mpl/always.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/apply_wrap.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/clear.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/has_key.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/insert_fwd.hpp>
#include <boost/mpl/iterator_range.hpp>
#include <boost/mpl/iterator_tags.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/reverse_fold.hpp>
#include <boost/mpl/sequence_tag.hpp>
#include <boost/mpl/set/set0.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/none.hpp>
#include <optional>
//#include <boost/parameter.hpp>
//#include <boost/parameter/binding.hpp>
//#include <boost/parameter/config.hpp>
//#include <boost/parameter/keyword.hpp>
//#include <boost/parameter/macros.hpp>
//#include <boost/parameter/match.hpp>
//#include <boost/parameter/name.hpp>
//#include <boost/parameter/parameters.hpp>
//#include <boost/parameter/preprocessor.hpp>
//#include <boost/parameter/value_type.hpp>
#include <boost/pending/cstddef.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/comparison/equal.hpp>
#include <boost/preprocessor/comparison/less_equal.hpp>
#include <boost/preprocessor/comparison/not_equal.hpp>
#include <boost/preprocessor/config/config.hpp>
#include <boost/preprocessor/control/expr_if.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/control/iif.hpp>
#include <boost/preprocessor/debug/error.hpp>
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/facilities/is_empty.hpp>
#include <boost/preprocessor/for.hpp>
#include <boost/preprocessor/identity.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/logical/bool.hpp>
#include <boost/preprocessor/logical/compl.hpp>
#include <boost/preprocessor/logical/not.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/repetition/deduce_r.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/for.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/selection/max.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/first_n.hpp>
#include <boost/preprocessor/seq/fold_left.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/push_back.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/tuple/eat.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/tuple/rem.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/property_map/vector_property_map.hpp>
#include <boost/random.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_smallint.hpp>
#include <boost/random/variate_generator.hpp>
#include <memory>
#include <boost/thread/tss.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/utility.hpp>
#include <variant>
#include <boost/version.hpp>
// CGAL
//#include <CGAL/AABB_traits_3.h>
//#include <CGAL/AABB_tree.h>
#include <CGAL/assertions.h>
#include <CGAL/basic.h>
#include <CGAL/Bbox_2.h>
#include <CGAL/Bbox_3.h>
#include <CGAL/Cartesian_converter.h>
#include <CGAL/circulator_bases.h>
//#include <CGAL/Compact_container.h>
#include <CGAL/config.h>
#include <CGAL/Default.h>
#include <CGAL/determinant.h>
#include <CGAL/Dimension.h>
#include <CGAL/enum.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Filtered_kernel.h>
#include <CGAL/Filtered_kernel/Cartesian_coordinate_iterator_2.h>
#include <CGAL/Filtered_kernel/Cartesian_coordinate_iterator_3.h>
#include <CGAL/Filtered_predicate.h>
#include <CGAL/function_objects.h>
#include <CGAL/Hilbert_policy_tags.h>
#include <CGAL/hilbert_sort.h>
#include <CGAL/Hilbert_sort_2.h>
#include <CGAL/Hilbert_sort_3.h>
#include <CGAL/Hilbert_sort_base.h>
#include <CGAL/Hilbert_sort_d.h>
#include <CGAL/Hilbert_sort_median_2.h>
#include <CGAL/Hilbert_sort_median_3.h>
#include <CGAL/Hilbert_sort_median_d.h>
#include <CGAL/Hilbert_sort_middle_2.h>
#include <CGAL/Hilbert_sort_middle_3.h>
#include <CGAL/Hilbert_sort_middle_base.h>
#include <CGAL/Hilbert_sort_middle_d.h>
#include <CGAL/Image_3.h>
#include <CGAL/TDS_3/internal/Dummy_tds_3.h>
#include <CGAL/Number_types/internal/Exact_type_selector.h>
#include <CGAL/STL_Extension/internal/info_check.h>
//#include <CGAL/internal/Regular_triangulation_filtered_traits_3.h>
#include <CGAL/Filtered_kernel/internal/Static_filters/Compare_weighted_squared_radius_3.h>
#include <CGAL/Filtered_kernel/internal/Static_filters/Power_side_of_oriented_power_sphere_3.h>
//#include <CGAL/internal/Static_filters/Regular_triangulation_static_filters_traits_3.h>
#include <CGAL/Filtered_kernel/internal/Static_filters/Static_filter_error.h>
#include <CGAL/Filtered_kernel/internal/Static_filters/tools.h>
//#include <CGAL/TDS_3/internal/Triangulation_ds_circulators_3.h>
//#include <CGAL/TDS_3/internal/Triangulation_ds_iterators_3.h>
#include <CGAL/Interval_nt.h>
#include <CGAL/IO/File_medit.h>
#include <CGAL/iterator.h>
#include <CGAL/Iterator_project.h>
#include <CGAL/Kernel/interface_macros.h>
#include <CGAL/Kernel/Type_equality_wrapper.h>
#include <CGAL/Kernel_traits.h>
#include <CGAL/Labeled_mesh_domain_3.h>
#include <CGAL/Lazy.h>
#include <CGAL/Lazy_exact_nt.h>
#include <CGAL/Lazy_kernel.h>
//#include <CGAL/Mesher_level.h>
//#include <CGAL/Mesher_level_default_implementations.h>
//#include <CGAL/Mesher_level_visitors.h>
//#include <CGAL/Meshes/Filtered_multimap_container.h>
//#include <CGAL/Meshes/Triangulation_mesher_level_traits_3.h>
//#include <CGAL/Mesh_3/global_parameters.h>
//#include <CGAL/Mesh_3/Mesher_3.h>
//#include <CGAL/Mesh_3/mesh_standard_cell_criteria.h>
//#include <CGAL/Mesh_3/mesh_standard_criteria.h>
//#include <CGAL/Mesh_3/mesh_standard_facet_criteria.h>
//#include <CGAL/Mesh_3/Mesh_surface_cell_base_3.h>
//#include <CGAL/Mesh_3/Refine_cells_3.h>
//#include <CGAL/Mesh_3/Refine_facets_3.h>
//#include <CGAL/Mesh_3/Refine_tets_visitor.h>
//#include <CGAL/Mesh_3/Robust_intersection_traits_3.h>
//#include <CGAL/Mesh_3/Triangle_accessor_primitive.h>
//#include <CGAL/Mesh_3/utilities.h>
//#include <CGAL/Mesh_cell_base_3.h>
#include <CGAL/Mesh_cell_criteria_3.h>
#include <CGAL/Mesh_constant_domain_field_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Mesh_edge_criteria_3.h>
#include <CGAL/Mesh_facet_criteria_3.h>
#include <CGAL/Mesh_facet_topology.h>
//#include <CGAL/Mesh_vertex_base_3.h>
#include <CGAL/Multiscale_sort.h>
#include <CGAL/number_utils_classes.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/Polygon_2/Polygon_2_simplicity.h>
#include <CGAL/Polygon_2/polygon_assertions.h>
#include <CGAL/Polygon_2_algorithms.h>
//#include <CGAL/Polyhedral_mesh_domain_3.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/predicates/predicates_on_weighted_points_cartesian_3.h>
//#include <CGAL/predicates/Regular_triangulation_ftC3.h>
//#include <CGAL/predicates/Regular_triangulation_rtH3.h>
//#include <CGAL/Profile_counter.h>
//#include <CGAL/Regular_triangulation_cell_base_3.h>
#include <CGAL/representation_tags.h>
#include <CGAL/Robust_construction.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/spatial_sort.h>
#include <CGAL/Spatial_sort_traits_adapter_3.h>
//#include <CGAL/Surface_mesh_vertex_base_3.h>
#include <CGAL/tags.h>
#include <CGAL/Timer.h>
#include <CGAL/Triangle_accessor_3.h>
//#include <CGAL/Triangulation_3.h>
//#include <CGAL/Triangulation_cell_base_3.h>
//#include <CGAL/Triangulation_data_structure_3.h>
//#include <CGAL/Triangulation_ds_cell_base_3.h>
//#include <CGAL/Triangulation_ds_vertex_base_3.h>
//#include <CGAL/Triangulation_simplex_3.h>
//#include <CGAL/Triangulation_structural_filtering_traits.h>
//#include <CGAL/Triangulation_utils_2.h>
//#include <CGAL/Triangulation_utils_3.h>
//#include <CGAL/Triangulation_vertex_base_3.h>
#include <CGAL/tuple.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/utility.h>
//#include <CGAL/Weighted_point.h>
// Mesh_3
/*#include <CGAL_demo/Viewer.h>
#include <CGAL_demo/Plugin_interface.h>
#include <CGAL_demo/Plugin_helper.h>
#include <ui_Meshing_dialog.h>
#include <Scene_polyhedron_item.h>
#include <implicit_functions/Implicit_function_interface.h>
#include <CGAL_demo/Scene_item_with_display_list.h>*/
#endif //STDAFX_H

View File

@ -0,0 +1,123 @@
//#define CHECK_MEMORY_LEAKS_ON_MSVC
#if defined(CHECK_MEMORY_LEAKS_ON_MSVC) && defined(_MSC_VER)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
// Without TBB_USE_THREADING_TOOL Intel Inspector XE will report false positives in Intel TBB
// (https://www.intel.com/content/www/us/en/developer/articles/technical/compiler-settings-for-threading-error-analysis-in-intel-inspector-xe.html)
#ifdef _DEBUG
# define TBB_USE_THREADING_TOOL
#endif
#include <CGAL/Mesh_3/config.h>
#include <CGAL/Memory_sizer.h>
// ==========================================================================
// BENCHMARK GENERAL PARAMETERS
// ==========================================================================
// #define CGAL_MESH_3_BENCHMARK_EXPORT_TO_MAYA
#define CGAL_MESH_3_BENCHMARK_EXPORT_TO_MESH
// ==========================================================================
// MESH_3 GENERAL PARAMETERS
// ==========================================================================
// #define CGAL_MESH_3_POLYHEDRON_WITH_FEATURES
// #define CGAL_MESH_3_IMPLICIT_WITH_FEATURES
// #define CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE // WARNING: VERY SLOW
#define CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING
// #define CGAL_MESH_3_BENCHMARK_LLOYD
// #define CGAL_MESH_3_BENCHMARK_ODT
// #define CGAL_MESH_3_BENCHMARK_PERTURB
// #define CGAL_MESH_3_BENCHMARK_EXUDE
// #define CGAL_MESH_3_MANIFOLD
// #define CGAL_MESH_3_VERBOSE
// #define CGAL_MESH_3_PERTURBER_VERBOSE
// #define CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY
// #define CGAL_MESH_3_EXUDER_VERBOSE
// #define CGAL_MESH_3_EXUDER_HIGH_VERBOSITY
// #define CGAL_MESH_3_VERY_VERBOSE
// #define CGAL_MESHES_DEBUG_REFINEMENT_POINTS
// #define CGAL_MESH_3_OPTIMIZER_VERBOSE
#define CGAL_MESH_3_PROFILING
// #define CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END
// ==========================================================================
// INPUTS
// ==========================================================================
const char* const BENCHMARK_INPUTS_FILENAME = "benchmark_inputs.txt";
const bool USE_RELATIVE_CRITERIA_VALUES = true; // relative to the bbox's diagonal
const double DEFAULT_FACE_SIZE = 100; // can be relative
const double DEFAULT_FACE_APPROX = 200; // can be relative
const double DEFAULT_FACE_ANGLE = 25; // cannot be relative
const double DEFAULT_CELL_SIZE = 100; // can be relative
const double DEFAULT_CELL_RADIUS_RATIO = 3; // cannot be relative
// ==========================================================================
// CONCURRENCY
// ==========================================================================
#ifdef CGAL_CONCURRENT_MESH_3
# include <tbb/task_arena.h>
# ifndef CGAL_LINKED_WITH_TBB
# pragma message(" : Warning: CGAL_LINKED_WITH_TBB not defined: EVERYTHING WILL BE SEQUENTIAL.")
# endif
// # define BENCHMARK_WITH_1_TO_MAX_THREADS
// # define CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE // default behavior
// # define CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE
// # define CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN // recommended
// # define CGAL_PARALLEL_MESH_3_DO_NOT_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE // not recommended
// ==========================================================================
// Verbose
// ==========================================================================
# define CGAL_CONCURRENT_MESH_3_VERBOSE
# define CGAL_CONCURRENT_MESH_3_VERY_VERBOSE
// ==========================================================================
// Concurrency config
// ==========================================================================
const char* const CONCURRENT_MESHER_CONFIG_FILENAME = "concurrent_mesher_config.cfg";
// =====================
// Worksharing strategy
// =====================
// #define CGAL_MESH_3_LOAD_BASED_WORKSHARING // Not recommended
// ==========================================================================
// Profiling
// ==========================================================================
// For profiling, etc.
# define CGAL_CONCURRENT_MESH_3_PROFILING
// # define CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT
#include <thread>
// ==========================================================================
// SEQUENTIAL
// ==========================================================================
#else // !CGAL_CONCURRENT_MESH_3
// # define CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE // default behavior
// # define CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE
// # define CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN // recommended
#endif // CGAL_CONCURRENT_MESH_3

View File

@ -0,0 +1,267 @@
# Input:
# Filename - facet_size - facet_approx - face_angle - cell_size - cell_shape - iterations
#########################################################
##### Benchmark MAX (warning: requires a lot of RAM!)
#########################################################
#meshes/elephant.off 0.0068 0.002 25 0.002 3 1
#meshes/fandisk.off 0.0068 0.003 25 0.003 3 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 25 0.0015 3 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.002 25 0.003 3 1
#Klein_function 0.0068 0.01 25 0.03 3 1
#Tanglecube_function 0.0068 0.005 25 0.025 3 1
#Sphere_function 0.0068 0.003 25 0.01 3 1
#Thin_cylinder_function 0.0068 0.001 25 0.002 3 1
#Pancake_function 0.0068 0.007 25 0.01 3 1
#meshes/elephant.off 0.0068 0.002 25 0.002 3 2
#meshes/fandisk.off 0.0068 0.003 25 0.003 3 2
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 25 0.0015 3 2
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.002 25 0.003 3 2
#Klein_function 0.0068 0.01 25 0.03 3 2
#Tanglecube_function 0.0068 0.005 25 0.025 3 2
#meshes/cheese.off 0.0068 0.002 25 0.002 3 1
#########################################################
##### Benchmark for refinement + optimization
#########################################################
#meshes/elephant.off 0.05 0.04 25 0.04 3 100
#meshes/elephant.off 0.01 0.004 25 0.004 3 1000
#meshes/elephant.off 0.0068 0.002 25 0.0025 3 10 # typical timing (11 thr): 4.4 2.3 9.9
#meshes/elephant.off 0.0068 0.002 25 0.0025 3 10000
#meshes/fandisk.off 0.0068 0.003 25 0.006 3 1 # typical timing (11 thr): 2.4 1.0 2.9
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 25 0.003 3 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.003 25 0.006 3 1
#meshes/cheese.off 0.0068 0.002 25 0.002 3 1
#Klein_function 0.0068 0.01 25 0.06 3 1
#Pancake_function 0.0068 0.02 25 0.02 3 1
#Tanglecube_function 0.0068 0.007 25 0.035 3 1
#Sphere_function 0.0068 0.006 25 0.02 3 1
#Thin_cylinder_function 0.0068 0.002 25 0.004 3 1
#########################################################
##### Benchmark according to number of elements
#########################################################
#meshes/elephant.off 0.0068 0.006 25 0.006 3 10
#meshes/elephant.off 0.0068 0.005 25 0.005 3 10
#########################################################
##### Middle class
#########################################################
#Klein_function 0.0068 0.005 25 2.02 3 1
#meshes/elephant.off 0.0068 0.005 25 0.005 3 1
#########################################################
##### A few seconds
#########################################################
Klein_function 0.0068 0.02 25 0.05 3 10
meshes/elephant.off 0.0068 0.003 25 0.003 3 1
meshes/elephant.off 0.0068 0.008 25 0.008 3 2
meshes/cheese.off 0.0068 0.005 25 0.005 3 1
#########################################################
##### Instant
#########################################################
Klein_function 0.0068 0.2 25 0.5 3 1
meshes/elephant.off 0.0068 0.03 25 0.03 3 5
meshes/elephant.off 0.0068 0.05 25 0.05 3 5
meshes/elephant.off 0.0068 0.068 25 0.068 3 1500
meshes/elephant.off 0.0068 2.68 25 2.68 3 150
meshes/elephant.off 0.0068 1.68 25 1.68 3 150
meshes/fandisk.off 0.0068 2.68 25 2.68 3 150
meshes/fandisk.off 0.0068 1.68 25 1.68 3 150
meshes/fandisk.off 0.0068 0.05 25 0.05 3 1
meshes/elephant.off 0.0200 0.05 25 0.25 3 2
#########################################################
##### Benchmark for TOMS article
#########################################################
meshes/elephant.off 0.0068 0.002 25 0.002 3 1
meshes/elephant.off 0.0068 0.003 25 0.003 3 1
meshes/elephant.off 0.0068 0.004 25 0.004 3 1
meshes/elephant.off 0.0068 0.005 25 0.005 3 1
meshes/elephant.off 0.0068 0.006 25 0.006 3 1
meshes/elephant.off 0.0068 0.007 25 0.007 3 1
meshes/elephant.off 0.0068 0.008 25 0.008 3 1
meshes/elephant.off 0.0068 0.010 25 0.010 3 1
meshes/fandisk.off 0.0068 0.003 25 0.003 3 1
meshes/fandisk.off 0.0068 0.0035 25 0.0035 3 1
meshes/fandisk.off 0.0068 0.004 25 0.004 3 1
meshes/fandisk.off 0.0068 0.005 25 0.005 3 1
meshes/fandisk.off 0.0068 0.006 25 0.006 3 1
meshes/fandisk.off 0.0068 0.007 25 0.007 3 1
meshes/fandisk.off 0.0068 0.008 25 0.008 3 1
meshes/fandisk.off 0.0068 0.010 25 0.010 3 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 25 0.0015 3 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.002 25 0.002 3 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.003 25 0.003 3 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.004 25 0.004 3 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.005 25 0.005 3 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.006 25 0.006 3 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.007 25 0.007 3 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.008 25 0.008 3 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.010 25 0.010 3 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.003 25 0.003 3 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.004 25 0.004 3 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.005 25 0.005 3 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.006 25 0.006 3 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.007 25 0.007 3 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.008 25 0.008 3 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.010 25 0.010 3 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0015 25 0.0015 3 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0017 25 0.0017 3 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.002 25 0.002 3 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0025 25 0.0025 3 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.003 25 0.003 3 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.004 25 0.004 3 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.005 25 0.005 3 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.006 25 0.006 3 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.007 25 0.007 3 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.008 25 0.008 3 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.010 25 0.010 3 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.003 25 0.003 3 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.004 25 0.004 3 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.005 25 0.005 3 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.006 25 0.006 3 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.007 25 0.007 3 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.008 25 0.008 3 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.010 25 0.010 3 1
meshes/turbine.off 0.0068 0.002 25 0.002 3 1
meshes/turbine.off 0.0068 0.003 25 0.003 3 1
meshes/turbine.off 0.0068 0.004 25 0.004 3 1
meshes/turbine.off 0.0068 0.005 25 0.005 3 1
meshes/turbine.off 0.0068 0.006 25 0.006 3 1
meshes/turbine.off 0.0068 0.007 25 0.007 3 1
meshes/turbine.off 0.0068 0.008 25 0.008 3 1
meshes/turbine.off 0.0068 0.010 25 0.010 3 1
meshes/cheese.off 0.0068 0.0004 25 0.0004 3 1
meshes/cheese.off 0.0068 0.0005 25 0.0005 3 1
meshes/cheese.off 0.0068 0.0007 25 0.0007 3 1
meshes/cheese.off 0.0068 0.001 25 0.001 3 1
meshes/cheese.off 0.0068 0.002 25 0.002 3 1
meshes/cheese.off 0.0068 0.004 25 0.004 3 1
meshes/cheese.off 0.0068 0.005 25 0.005 3 1
meshes/cheese.off 0.0068 0.007 25 0.007 3 1
meshes/cheese.off 0.0068 0.010 25 0.010 3 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.002 25 0.002 3 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.003 25 0.003 3 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.004 25 0.004 3 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.005 25 0.005 3 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.006 25 0.006 3 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.007 25 0.007 3 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.008 25 0.008 3 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.010 25 0.010 3 1
Thin_cylinder_function 0.0068 0.001 25 0.003 3 1
Thin_cylinder_function 0.0068 0.002 25 0.006 3 1
Thin_cylinder_function 0.0068 0.003 25 0.01 3 1
Thin_cylinder_function 0.0068 0.006 25 0.02 3 1
Thin_cylinder_function 0.0068 0.01 25 0.03 3 1
Thin_cylinder_function 0.0068 0.012 25 0.035 3 1
Thin_cylinder_function 0.0068 0.013 25 0.04 3 1
Thin_cylinder_function 0.0068 0.017 25 0.05 3 1
Thin_cylinder_function 0.0068 0.02 25 0.06 3 1
Thin_cylinder_function 0.0068 0.023 25 0.07 3 1
Thin_cylinder_function 0.0068 0.027 25 0.08 3 1
Thin_cylinder_function 0.0068 0.033 25 0.10 3 1
Pancake_function 0.0068 0.004 25 0.013 3 1
Pancake_function 0.0068 0.006 25 0.02 3 1
Pancake_function 0.0068 0.01 25 0.03 3 1
Pancake_function 0.0068 0.012 25 0.035 3 1
Pancake_function 0.0068 0.013 25 0.04 3 1
Pancake_function 0.0068 0.017 25 0.05 3 1
Pancake_function 0.0068 0.02 25 0.06 3 1
Pancake_function 0.0068 0.023 25 0.07 3 1
Pancake_function 0.0068 0.027 25 0.08 3 1
Pancake_function 0.0068 0.033 25 0.10 3 1
Klein_function 0.0068 0.01 25 0.03 3 1
Klein_function 0.0068 0.012 25 0.035 3 1
Klein_function 0.0068 0.013 25 0.04 3 1
Klein_function 0.0068 0.017 25 0.05 3 1
Klein_function 0.0068 0.02 25 0.06 3 1
Klein_function 0.0068 0.023 25 0.07 3 1
Klein_function 0.0068 0.027 25 0.08 3 1
Klein_function 0.0068 0.033 25 0.10 3 1
Tanglecube_function 0.0068 0.01 25 0.03 3 1
Tanglecube_function 0.0068 0.012 25 0.035 3 1
Tanglecube_function 0.0068 0.013 25 0.04 3 1
Tanglecube_function 0.0068 0.017 25 0.05 3 1
Tanglecube_function 0.0068 0.02 25 0.06 3 1
Tanglecube_function 0.0068 0.023 25 0.07 3 1
Tanglecube_function 0.0068 0.027 25 0.08 3 1
Tanglecube_function 0.0068 0.033 25 0.10 3 1
Sphere_function 0.0068 0.003 25 0.01 3 1
Sphere_function 0.0068 0.006 25 0.02 3 1
Sphere_function 0.0068 0.01 25 0.03 3 1
Sphere_function 0.0068 0.012 25 0.035 3 1
Sphere_function 0.0068 0.013 25 0.04 3 1
Sphere_function 0.0068 0.017 25 0.05 3 1
Sphere_function 0.0068 0.02 25 0.06 3 1
Sphere_function 0.0068 0.023 25 0.07 3 1
Sphere_function 0.0068 0.027 25 0.08 3 1
Sphere_function 0.0068 0.033 25 0.10 3 1
images/liver.inr.gz 0.5 5 25 5 3 1
images/liver.inr.gz 0.5 2 25 2 3 1
images/liver.inr.gz 0.5 1.5 25 1.5 3 1
images/liver.inr.gz 0.5 1 25 1 3 1
images/liver.inr.gz 0.5 0.8 25 0.8 3 1
images/liver.inr.gz 0.5 0.65 25 0.65 3 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 1.5 25 1.5 3 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 1 25 1 3 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.8 25 0.8 3 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.65 25 0.65 3 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.40 25 0.40 3 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.30 25 0.30 3 1
########### Bug maya ##########
Klein_function 0.0068 0.2 25 0.5 3 1
meshes/fandisk.off 0.0068 0.5 25 0.5 3 1
####### Divers #######
Klein_function 0.0068 1.1 25 1.1 3 10
Klein_function 0.0068 0.4 25 0.8 3 1
Klein_function 0.0068 0.04 25 0.1 3 1
Klein_function 0.0068 0.01 25 0.03 3 1
Klein_function 0.0068 0.01 25 0.03 3 1
meshes/elephant.off 0.0068 0.2 25 0.002 3 1000
meshes/elephant.off 0.0068 0.007 25 0.007 3 150
meshes/elephant.off 0.0068 0.02 25 0.02 3 15
meshes/elephant.off 0.0068 0.2 25 0.2 3 2
Tanglecube_function 0.0068 0.01 25 0.03 3 1000
####### Crash compact cell: SOLVED! ########
meshes/elephant.off 0.0068 0.005 25 0.005 3 100000
####### Test crash "A facet is not in conflict with its refinement point!" - SOLVED ########
meshes/elephant.off 0.0068 0.002 25 10 3 100000
####### Parallel optimizers ########
meshes/elephant.off 0.0068 0.005 25 0.005 3 1000
meshes/elephant.off 0.0068 0.002 25 0.003 3 100
meshes/elephant.off 0.0010 0.068 25 0.068 3 10000
meshes/elephant.off 0.0020 0.068 25 0.068 3 10000
meshes/elephant.off 0.0068 0.068 25 0.068 3 10000
meshes/fandisk.off 0.0068 0.006 25 0.006 3 10
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.003 25 0.003 3 10
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.005 25 0.006 3 10
Klein_function 0.0068 0.02 25 0.06 3 10
Tanglecube_function 0.0068 0.01 25 0.05 3 10
Sphere_function 0.0068 0.006 25 0.02 3 10
Thin_cylinder_function 0.0068 0.002 25 0.004 3 10
Pancake_function 0.0068 0.02 25 0.02 3 10
meshes/cheese.off 0.0068 0.002 25 0.002 3 10
Klein_function 0.068 0.04 25 0.15 3 1
meshes/cheese.off 0.0001 0.004 25 0.0086 3 100
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0061 0.061 25 0.061 3 10

View File

@ -0,0 +1,681 @@
#include "benchmark_config.h"
#include "benchmark_xml.h"
#include "mesh_quality.h"
std::string XML_perf_data::default_filename;
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Labeled_mesh_domain_3.h>
#include <CGAL/Mesh_polyhedron_3.h>
#include <CGAL/Polyhedral_mesh_domain_3.h>
#include <CGAL/Polyhedral_mesh_domain_with_features_3.h>
#include <CGAL/Mesh_domain_with_polyline_features_3.h>
#include <CGAL/make_mesh_3.h>
#include <CGAL/refine_mesh_3.h>
#include <CGAL/boost/graph/IO/polygon_mesh_io.h>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>
#ifdef CGAL_LINKED_WITH_TBB
# include <tbb/task_arena.h>
# define TBB_PREVIEW_GLOBAL_CONTROL 1
# include <tbb/global_control.h>
#endif
#include <filesystem>
#include <fstream>
#include <iostream>
#include <signal.h>
#include <string>
#include <sstream>
namespace PMP = CGAL::Polygon_mesh_processing;
// basic types from kernel
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Point_3 Point;
typedef K::Sphere_3 Sphere;
// To avoid verbose function and named parameters call
using namespace CGAL::parameters;
#include "implicit_functions.h"
std::string get_output_filename(const std::string& input_name)
{
std::string filename = std::string(input_name);
filename = filename.substr(filename.find_last_of("/") + 1, filename.length() - 1);
filename = filename.substr(0, filename.find_last_of("."));
return filename;
}
std::string get_technique()
{
std::string tech;
#ifdef CGAL_CONCURRENT_MESH_3
tech += "Task-scheduler (auto";
# ifdef CGAL_MESH_3_LOAD_BASED_WORKSHARING
tech += ", load-based worksharing";
#endif
tech += ")";
#else // !CGAL_CONCURRENT_MESH_3
tech += "Sequential ";
# if defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
# ifdef CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN
tech += "(sort after scan only";
# else
tech += "(unsorted";
# endif
# elif defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE)
tech += "(sorted";
# else
tech += "(NOT LAZY, sorted";
# endif
#ifdef CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE
tech += ", points on far sphere)";
#else
tech += ")";
#endif
#endif // CGAL_CONCURRENT_MESH_3
return tech;
}
void display_info(int num_threads)
{
std::cout << get_technique() << std::endl;
#ifdef CGAL_CONCURRENT_MESH_3
if(num_threads != -1)
std::cout << "Num threads = " << num_threads << std::endl;
else
std::cout << "Num threads = AUTO" << std::endl;
#else // !CGAL_CONCURRENT_MESH_3
# ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING
std::cout << "NO random shooting)" << std::endl;
# else
std::cout << "WITH random shooting)" << std::endl;
# endif
#endif // CGAL_CONCURRENT_MESH_3
}
void xml_perf_set_technique()
{
CGAL_MESH_3_SET_PERFORMANCE_DATA("Technique", get_technique());
}
#ifdef CGAL_MESH_3_IMPLICIT_WITH_FEATURES
// To add a crease (feature) to some implicit function
typedef std::vector<Point> Crease;
typedef std::list<Crease> Creases;
void add_crease(const Point& a,
const Point& b,
Creases& creases)
{
Crease crease;
crease.push_back(a);
crease.push_back(b);
creases.push_back(crease);
}
#endif
enum Exit_code
{
// Success
VALID_OUTPUT = 0,
// Failure
INPUT_IS_INVALID = 1,
OUTPUT_IS_INVALID = 2
};
// the call to Mesh_3 happens here
template <typename C3t3, typename Domain>
Exit_code make_mesh(const Domain& domain,
const CGAL::Mesh_criteria_3<typename C3t3::Triangulation>& criteria,
const std::string& output_filename)
{
#ifdef _DEBUG
double timelimit = 10;
double sliverbound = 2;
#else
double timelimit = 0; // when making charts, we run this executable a timeout
double sliverbound = 2;
#endif
CGAL::Real_timer t;
t.start();
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain
, criteria
# ifdef CGAL_MESH_3_BENCHMARK_LLOYD
, lloyd(time_limit=timelimit)
# else
, no_lloyd()
# endif
# ifdef CGAL_MESH_3_BENCHMARK_ODT
, odt(time_limit=timelimit)
# else
, no_odt()
#endif
# ifdef CGAL_MESH_3_BENCHMARK_PERTURB
, perturb(time_limit = timelimit,
sliver_bound = sliverbound)
# else
, no_perturb()
#endif
#ifdef CGAL_MESH_3_BENCHMARK_EXUDE
, exude(time_limit = timelimit,
sliver_bound = sliverbound)
#else
, no_exude()
#endif
#ifdef CGAL_MESH_3_MANIFOLD
, manifold()
#else
, non_manifold()
#endif
);
t.stop();
CGAL_MESH_3_SET_PERFORMANCE_DATA("V", c3t3.triangulation().number_of_vertices());
CGAL_MESH_3_SET_PERFORMANCE_DATA("F", c3t3.number_of_facets_in_complex());
CGAL_MESH_3_SET_PERFORMANCE_DATA("C", c3t3.number_of_cells_in_complex());
CGAL_MESH_3_SET_PERFORMANCE_DATA("Mem", CGAL::Memory_sizer().virtual_size() >> 20);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Total_time", t.time());
#ifdef CGAL_MESH_3_BENCHMARK_EXPORT_TO_MAYA
std::cout << "Exporting to " << output_filename + ".maya (Maya)... ";
std::ofstream out_maya(output_filename + ".maya");
c3t3.output_to_maya(out_maya, true);
std::cout << "done." << std::endl;
#endif
#ifdef CGAL_MESH_3_BENCHMARK_EXPORT_TO_MESH
std::cout << "Exporting to " << output_filename + ".mesh (Medit)... ";
// std::cout << "std::filesystem::current_path() = " << std::filesystem::current_path() << std::endl;
std::ofstream out_medit(output_filename + ".mesh");
c3t3.output_to_medit(out_medit, true);
std::cout << "done." << std::endl;
#endif
if(!c3t3.triangulation().is_valid() || !c3t3.is_valid())
{
std::cerr << "Error: invalid output" << std::endl;
return OUTPUT_IS_INVALID;
}
if(c3t3.number_of_facets_in_complex() == 0)
{
std::cerr << "Error: no facets in output" << std::endl;
return OUTPUT_IS_INVALID;
}
if(c3t3.number_of_cells_in_complex() == 0)
{
std::cerr << "Error: no cells in output" << std::endl;
return OUTPUT_IS_INVALID;
}
generate_quality_metrics(c3t3);
return VALID_OUTPUT;
}
template <typename C3t3, typename Domain>
Exit_code make_mesh(const Domain& domain,
double facet_sizing, double facet_approx, double facet_ang,
double cell_sizing, double cell_shape,
const std::string& output_filename)
{
typedef CGAL::Mesh_criteria_3<typename C3t3::Triangulation> Mesh_criteria;
const CGAL::Bbox_3 bbox = domain.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()));
if(USE_RELATIVE_CRITERIA_VALUES)
{
facet_sizing = diag_length / facet_sizing;
facet_approx = diag_length / facet_approx;
cell_sizing = diag_length / cell_sizing;
}
Mesh_criteria criteria(edge_size = facet_sizing,
facet_angle = facet_ang,
facet_size = facet_sizing,
facet_distance = facet_approx,
cell_size = cell_sizing,
cell_radius_edge_ratio = cell_shape);
std::cout << " * edge max size: " << facet_sizing << std::endl
<< " * facet max size: " << facet_sizing << std::endl
<< " * facet approx error: " << facet_approx << std::endl
<< " * facet min angle: " << facet_ang << std::endl
<< " * cell max size: " << cell_sizing << std::endl
<< " * cell shape (radius-edge): " << cell_shape << std::endl;
return make_mesh<C3t3>(domain, criteria, output_filename);
}
Exit_code make_mesh_polyhedron(const std::string& input_filename,
double facet_sizing, double facet_approx, double facet_angle,
double cell_sizing, double cell_shape)
{
std::cout << "make_mesh_polyhedron(" << input_filename << ")" << std::endl;
// Domain
#ifdef CGAL_MESH_3_POLYHEDRON_WITH_FEATURES
typedef CGAL::Mesh_polyhedron_3<K>::type Polyhedron;
typedef CGAL::Polyhedral_mesh_domain_with_features_3<K> Mesh_domain;
#else
typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef CGAL::Polyhedral_mesh_domain_3<Polyhedron, K> Mesh_domain;
#endif
// Triangulation
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<Mesh_domain,
CGAL::Kernel_traits<Mesh_domain>::Kernel,
CGAL::Parallel_tag>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
// C3t3
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Create input polyhedron
Polyhedron polyhedron;
if(!CGAL::IO::read_polygon_mesh(input_filename, polyhedron))
{
std::cerr << "Error: Could not read '" << input_filename << "'" << std::endl;
return INPUT_IS_INVALID;
}
if(is_empty(polyhedron) ||
!is_triangle_mesh(polyhedron) ||
!is_closed(polyhedron) ||
has_degenerate_faces(polyhedron) ||
PMP::does_self_intersect(polyhedron))
{
std::cerr << "Error: input has defects" << std::endl;
return INPUT_IS_INVALID;
}
std::cout << "Building AABB tree... " << std::endl;
// Create domain
Mesh_domain domain(polyhedron);
std::cout << "done." << std::endl;
#ifdef CGAL_MESH_3_POLYHEDRON_WITH_FEATURES
std::cout << "Detecting features..." << std::endl;
domain.detect_features();
std::cout << "done." << std::endl;
#endif
return make_mesh<C3t3>(domain,
facet_sizing, facet_approx, facet_angle,
cell_sizing, cell_shape,
get_output_filename(input_filename));
}
Exit_code make_mesh_3D_images(const std::string& input_filename,
double facet_sizing, double facet_approx, double facet_angle,
double cell_sizing, double cell_shape)
{
std::cout << "make_mesh_3D_images(" << input_filename << ")" << std::endl;
// Domain
typedef CGAL::Labeled_mesh_domain_3<K> Mesh_domain;
// Triangulation
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<Mesh_domain,
CGAL::Kernel_traits<Mesh_domain>::Kernel,
CGAL::Parallel_tag>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
// C3t3
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Load image
CGAL::Image_3 image;
image.read(input_filename.c_str());
// Create domain
Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image);
std::cout << "done." << std::endl;
return make_mesh<C3t3>(domain,
facet_sizing, facet_approx, facet_angle,
cell_sizing, cell_shape,
get_output_filename(input_filename));
}
template <class ImplicitFunction>
Exit_code make_mesh_implicit(const std::string& function_name,
ImplicitFunction func,
double facet_sizing, double facet_approx, double facet_angle,
double cell_sizing, double cell_shape)
{
std::cout << "make_mesh_implicit(" << function_name << ")" << std::endl;
// Domain
#ifdef CGAL_MESH_3_IMPLICIT_WITH_FEATURES
typedef CGAL::Labeled_mesh_domain_3<K> Implicit_domain;
typedef CGAL::Mesh_domain_with_polyline_features_3<Implicit_domain> Mesh_domain;
#else
typedef CGAL::Labeled_mesh_domain_3<K> Mesh_domain;
#endif
// Triangulation
#ifdef CGAL_CONCURRENT_MESH_3
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain,
typename CGAL::Kernel_traits<Mesh_domain>::Kernel,
CGAL::Parallel_tag>::type Tr;
#else
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
// C3t3
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Create domain
Sphere bounding_sphere(CGAL::ORIGIN, 10.0 * 10.0);
namespace p = CGAL::parameters;
Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain(p::function = func,
p::bounding_object = bounding_sphere
/*, p::relative_error_bound = 1e-7*/);
#ifdef CGAL_MESH_3_IMPLICIT_WITH_FEATURES
// Add 12 feature creases
Creases creases;
Point p1(-1.0, -1.0, -1.0);
Point p2(-1.0, -1.0, 1.0);
Point p3(-1.0, 1.0, 1.0);
Point p4(-1.0, 1.0, -1.0);
Point p5( 1.0, -1.0, -1.0);
Point p6( 1.0, -1.0, 1.0);
Point p7( 1.0, 1.0, 1.0);
Point p8( 1.0, 1.0, -1.0);
add_crease(p1, p2, creases);
add_crease(p2, p3, creases);
add_crease(p3, p4, creases);
add_crease(p4, p1, creases);
add_crease(p5, p6, creases);
add_crease(p6, p7, creases);
add_crease(p7, p8, creases);
add_crease(p8, p5, creases);
add_crease(p5, p1, creases);
add_crease(p6, p2, creases);
add_crease(p7, p3, creases);
add_crease(p8, p4, creases);
domain.add_features(creases.begin(), creases.end());
#endif
return make_mesh<C3t3>(domain,
facet_sizing, facet_approx, facet_angle,
cell_sizing, cell_shape,
function_name);
}
// logs the parameters, and dispatch to polyhedral, implicit or image domain
Exit_code run(const std::string& input,
double facet_approx, double facet_sizing, double facet_angle,
double cell_sizing, double cell_shape,
int num_iteration)
{
std::string domain = input;
size_t slash_index = domain.find_last_of('/');
if(slash_index == std::string::npos)
slash_index = domain.find_last_of('\\');
if(slash_index == std::string::npos)
slash_index = 0;
else
++slash_index;
domain = domain.substr(slash_index, domain.find_last_of('.') - slash_index);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Domain", domain);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Facet_size", facet_sizing);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Facet_approx", facet_approx);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Facet_angle", facet_angle);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Cell_size", cell_sizing);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Cell_shape", cell_shape);
xml_perf_set_technique();
Exit_code res;
for(int j=0; j<num_iteration; ++j)
{
std::cout << std::endl << "Refinement #" << j << "..." << std::endl;
if(input == "Klein_function")
{
res = make_mesh_implicit(input, Klein_function(),
facet_sizing, facet_approx, facet_angle,
cell_sizing, cell_shape);
}
else if(input == "Tanglecube_function")
{
res = make_mesh_implicit(input, Tanglecube_function(),
facet_sizing, facet_approx, facet_angle,
cell_sizing, cell_shape);
}
else if(input == "Sphere_function")
{
Sphere_function f(1.);
res = make_mesh_implicit(input, f,
facet_sizing, facet_approx, facet_angle,
cell_sizing, cell_shape);
}
else if(input == "Thin_cylinder_function")
{
Cylinder_function f(0.05, 3.);
res = make_mesh_implicit(input, f,
facet_sizing, facet_approx, facet_angle,
cell_sizing, cell_shape);
}
else if(input == "Pancake_function")
{
Cylinder_function f(3., 0.1);
res = make_mesh_implicit(input, f,
facet_sizing, facet_approx, facet_angle,
cell_sizing, cell_shape);
}
else // not a known implicit function
{
// Assume it's a CGAL data file...
std::string full_path = CGAL::data_file_path(input);
// ...and if it is not, then take it as it is
if(!std::ifstream(full_path).good())
full_path = input;
const std::string extension = CGAL::IO::internal::get_file_extension(input);
if(extension == "inr")
{
res = make_mesh_3D_images(full_path,
facet_sizing, facet_approx, facet_angle,
cell_sizing, cell_shape);
}
else // assume it's a polyhedron
{
res = make_mesh_polyhedron(full_path,
facet_sizing, facet_approx, facet_angle,
cell_sizing, cell_shape);
}
}
std::cout << "Refinement #" << j << " done." << std::endl;
std::cout << std::endl << "---------------------------------" << std::endl << std::endl;
XML_perf_data::commit();
}
return res;
}
// reads filename & input parameters either from argv or from a script file
int main(int argc, char** argv)
{
std::cout.precision(17);
std::cerr.precision(17);
// for the default xml filename, check XML_perf_data::build_filename()
if(argc > 1)
XML_perf_data::default_filename = argv[1];
#if defined(CHECK_MEMORY_LEAKS_ON_MSVC) && defined(_MSC_VER)
_CrtSetDbgFlag ( _CRTDtbbBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
#ifdef CGAL_CONCURRENT_MESH_3
Concurrent_mesher_config::load_config_file(CONCURRENT_MESHER_CONFIG_FILENAME, true);
int max_nb_threads = Concurrent_mesher_config::get().num_threads;
if(max_nb_threads == -1) // if not set in the config file, take the max available
max_nb_threads = tbb::this_task_arena::max_concurrency();
#endif
Exit_code res;
#ifdef CGAL_CONCURRENT_MESH_3
#ifdef BENCHMARK_WITH_1_TO_MAX_THREADS
for(int num_threads=1; num_threads<=max_nb_threads; ++num_threads)
#else
int num_threads = max_nb_threads;
#endif // BENCHMARK_WITH_1_TO_MAX_THREADS
#endif // CGAL_CONCURRENT_MESH_3
{
#ifdef CGAL_CONCURRENT_MESH_3
std::cout << "-- Parallel Mesh_3 --" << std::endl;
tbb::global_control control(tbb::global_control::max_allowed_parallelism, num_threads);
display_info(num_threads);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Num_threads", num_threads);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Lockgrid_size", Concurrent_mesher_config::get().locking_grid_num_cells_per_axis);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Lock_radius", Concurrent_mesher_config::get().first_grid_lock_radius);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Statgrid_size", Concurrent_mesher_config::get().work_stats_grid_num_cells_per_axis);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Num_work_items_per_batch", Concurrent_mesher_config::get().num_work_items_per_batch);
#else
std::cout << "-- Sequential Mesh_3 --" << std::endl;
CGAL_MESH_3_SET_PERFORMANCE_DATA("Num_threads", "N/A");
CGAL_MESH_3_SET_PERFORMANCE_DATA("Lockgrid_size", "N/A");
CGAL_MESH_3_SET_PERFORMANCE_DATA("Lock_radius", "N/A");
CGAL_MESH_3_SET_PERFORMANCE_DATA("Statgrid_size", "N/A");
CGAL_MESH_3_SET_PERFORMANCE_DATA("Num_work_items_per_batch", "N/A");
#endif
// Script file format: each line gives
// - Filename (polyhedron and image) or "XXX_function" (implicit)
// - Facet and cell criteria
// - Number of iterations with these parameters
std::ifstream script_file;
script_file.open(BENCHMARK_INPUTS_FILENAME);
if(script_file.is_open())
{
std::cout << "Found inputs file '" << BENCHMARK_INPUTS_FILENAME << "'" << std::endl;
std::string line;
while(std::getline(script_file, line))
{
if(line.empty() || line[0] == '#') // lines starting with '#' are ignored
continue;
std::cout << std::endl << std::endl;
std::cout << "*****************************************" << std::endl;
std::cout << "******* " << line << std::endl;
std::cout << "*****************************************" << std::endl;
std::stringstream sstr(line);
std::string input;
double facet_approx, facet_sizing, facet_angle;
double cell_sizing, cell_shape;
int num_iteration;
if(!(sstr >> input
>> facet_approx
>> facet_sizing
>> facet_angle
>> cell_sizing
>> cell_shape
>> num_iteration))
{
std::cerr << "Error: failed to read input" << std::endl;
return INPUT_IS_INVALID;
}
res = run(input,
facet_approx, facet_sizing, facet_angle,
cell_sizing, cell_shape,
num_iteration);
}
}
else // no script
{
std::cout << "Inputs file '" << BENCHMARK_INPUTS_FILENAME << "' NOT found." << std::endl;
// If the script is empty, use the command line arguments:
// [this_program]
// - filename
// - facet_sizing
// - facet_approx
// - facet_angle
// - cell_sizing
// - cell_shape
// - num_iteration
std::string input = (argc > 2) ? argv[2] : "Sphere_function"; // @fixme klein assertion?
double facet_sizing = (argc > 3) ? std::stod(argv[3]) : DEFAULT_FACE_SIZE;
double facet_approx = (argc > 4) ? std::stod(argv[4]) : DEFAULT_FACE_APPROX;
double facet_angle = (argc > 5) ? std::stod(argv[5]) : DEFAULT_FACE_ANGLE; // 25°
double cell_sizing = (argc > 6) ? std::stod(argv[6]) : DEFAULT_CELL_SIZE;
double cell_shape = (argc > 7) ? std::stod(argv[7]) : DEFAULT_CELL_RADIUS_RATIO; // 3
if(facet_sizing <= 0)
facet_sizing = DEFAULT_FACE_SIZE;
if(facet_approx <= 0)
facet_approx = DEFAULT_FACE_APPROX;
if(facet_angle <= 0)
facet_angle = DEFAULT_FACE_ANGLE;
if(cell_sizing <= 0)
cell_sizing = DEFAULT_CELL_SIZE;
if(cell_shape <= 0)
cell_shape = DEFAULT_CELL_RADIUS_RATIO;
res = run(input,
facet_approx, facet_sizing, facet_angle,
cell_sizing, cell_shape,
1 /*num_iteration*/);
}
}
return res;
}

View File

@ -0,0 +1,139 @@
#ifndef CGAL_MESH_3_BENCHMARK_BENCHMARK_XML_H
#define CGAL_MESH_3_BENCHMARK_BENCHMARK_XML_H
#include "../../test/Mesh_3/XML_exporter.h"
#define CGAL_MESH_3_EXPORT_PERFORMANCE_DATA
#define CGAL_MESH_3_SET_PERFORMANCE_DATA(value_name, value) \
XML_perf_data::set(value_name, value);
class XML_perf_data
{
public:
typedef Streaming_XML_exporter<std::string> XML_exporter;
private:
XML_exporter m_xml;
XML_exporter::Element_with_map m_current_element;
public:
static std::string default_filename;
XML_perf_data(const std::string& filename)
: m_xml(filename, "ContainerPerformance", "Perf", construct_subelements_names())
{}
virtual ~XML_perf_data()
{}
static XML_perf_data& get()
{
static XML_perf_data singleton(build_filename());
return singleton;
}
template <typename Value_type>
static void set(const std::string& name, Value_type value)
{
get().set_data(name, value);
}
static void commit()
{
get().commit_current_element();
}
protected:
static std::string build_filename()
{
if(default_filename != "")
return default_filename;
std::stringstream sstr;
sstr << "Performance_log_" << time(0) << ".xml";
return sstr.str();
}
static std::vector<std::string> construct_subelements_names()
{
std::vector<std::string> subelements;
subelements.push_back("Domain");
subelements.push_back("Facet_angle");
subelements.push_back("Facet_size");
subelements.push_back("Facet_approx");
subelements.push_back("Cell_size");
subelements.push_back("Cell_shape");
subelements.push_back("Technique");
subelements.push_back("Num_threads");
subelements.push_back("Lockgrid_size");
subelements.push_back("Lock_radius");
subelements.push_back("Statgrid_size");
subelements.push_back("Num_work_items_per_batch");
subelements.push_back("V");
subelements.push_back("F");
subelements.push_back("C");
subelements.push_back("Facets_scan_time");
subelements.push_back("Facets_refine_time");
subelements.push_back("Cells_scan_time");
subelements.push_back("Cells_refine_time");
subelements.push_back("Lloyd_optim_time");
subelements.push_back("Odt_optim_time");
subelements.push_back("Perturber_optim_time");
subelements.push_back("Exuder_optim_time");
subelements.push_back("Total_time");
subelements.push_back("Mem");
subelements.push_back("Minimum_edge_length");
subelements.push_back("Mean_edge_length");
subelements.push_back("Maximum_edge_length");
subelements.push_back("Minimum_facet_area");
subelements.push_back("Mean_facet_area");
subelements.push_back("Maximum_facet_area");
subelements.push_back("Total_area");
subelements.push_back("Minimum_facet_angle");
subelements.push_back("Maximum_facet_angle");
subelements.push_back("Minimum_cell_volume");
subelements.push_back("Mean_cell_volume");
subelements.push_back("Maximum_cell_volume");
subelements.push_back("Total_volume");
subelements.push_back("Minimum_dihedral_angle");
subelements.push_back("Mean_dihedral_angle");
subelements.push_back("Maximum_dihedral_angle");
subelements.push_back("Smallest_edge_radius_ratio");
subelements.push_back("Smallest_radius_radius_ratio");
subelements.push_back("Biggest_V_SMA");
return subelements;
}
void set_data(const std::string& name, const std::string& value)
{
m_current_element[name] = value;
}
template <typename Value_type>
void set_data(const std::string& name, Value_type value)
{
std::stringstream sstr;
sstr << value;
set_data(name, sstr.str());
}
void commit_current_element()
{
m_xml.add_element(m_current_element);
m_current_element.clear();
}
};
#endif // CGAL_MESH_3_BENCHMARK_BENCHMARK_XML_H

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +0,0 @@
#filename=D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off
filename=D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off
facet_sizing=0.01
cell_sizing=0.03
numthreads=11 # default = -1 (auto)

View File

@ -1,266 +0,0 @@
#########################################################
##### Benchmark MAX (warning: requires a lot of RAM!)
#########################################################
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 0.002 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.003 0.003 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 0.0015 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.002 0.003 1
#Klein_function 0.0068 0.01 0.03 1
#Tanglecube_function 0.0068 0.005 0.025 1
#Sphere_function 0.0068 0.003 0.01 1
#Thin_cylinder_function 0.0068 0.001 0.002 1
#Pancake_function 0.0068 0.007 0.01 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 0.002 2
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.003 0.003 2
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 0.0015 2
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.002 0.003 2
#Klein_function 0.0068 0.01 0.03 2
#Tanglecube_function 0.0068 0.005 0.025 2
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/cheese.off 0.0068 0.002 0.002 1
#########################################################
##### Benchmark for refinement+optim
#########################################################
#../../examples/Mesh_3/data/elephant.off 0.05 0.04 0.04 10000
#../../examples/Mesh_3/data/elephant.off 0.01 0.004 0.004 10000
../../examples/Mesh_3/data/elephant.off 0.0068 0.002 0.0025 10000 # typical timing (11 thr): 4.4 2.3 9.9
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 0.0025 10000
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.003 0.006 1 # typical timing (11 thr): 2.4 1.0 2.9
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 0.003 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.003 0.006 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/cheese.off 0.0068 0.002 0.002 1
#Klein_function 0.0068 0.01 0.06 1
#Pancake_function 0.0068 0.02 0.02 1
#Tanglecube_function 0.0068 0.007 0.035 1
#Sphere_function 0.0068 0.006 0.02 1
#Thin_cylinder_function 0.0068 0.002 0.004 1
#########################################################
##### Benchmark according to number of elements
#########################################################
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.006 0.006 10
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.005 0.005 10
#########################################################
##### Middle class
#########################################################
#Klein_function 0.0068 0.005 2.02 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.005 0.005 1
#########################################################
##### A few seconds
#########################################################
#Klein_function 0.0068 0.02 0.05 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.003 0.003 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.008 0.008 2
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/cheese.off 0.0068 0.005 0.005 1
#########################################################
##### Instant
#########################################################
#Klein_function 0.0068 0.2 0.5 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.03 0.03 5
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.05 0.05 5
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.068 0.068 1500
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 2.68 2.68 150
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 1.68 1.68 150
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 2.68 2.68 150
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 1.68 1.68 150
#D:/INRIA/CGAL/svn/cgal/trunk/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.05 0.05 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0200 0.05 0.25 2
#########################################################
##### Benchmark for TOMS article
#########################################################
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 0.002 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.003 0.003 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.004 0.004 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.005 0.005 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.006 0.006 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.007 0.007 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.008 0.008 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.010 0.010 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.003 0.003 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.0035 0.0035 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.004 0.004 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.005 0.005 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.006 0.006 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.007 0.007 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.008 0.008 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.010 0.010 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 0.0015 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.002 0.002 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.003 0.003 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.004 0.004 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.005 0.005 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.006 0.006 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.007 0.007 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.008 0.008 1
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.010 0.010 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.003 0.003 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.004 0.004 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.005 0.005 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.006 0.006 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.007 0.007 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.008 0.008 1
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.010 0.010 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0015 0.0015 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0017 0.0017 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.002 0.002 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0025 0.0025 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.003 0.003 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.004 0.004 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.005 0.005 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.006 0.006 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.007 0.007 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.008 0.008 1
#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.010 0.010 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.003 0.003 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.004 0.004 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.005 0.005 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.006 0.006 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.007 0.007 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.008 0.008 1
#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.010 0.010 1
#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.002 0.002 1
#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.003 0.003 1
#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.004 0.004 1
#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.005 0.005 1
#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.006 0.006 1
#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.007 0.007 1
#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.008 0.008 1
#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.010 0.010 1
#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.0004 0.0004 1
#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.0005 0.0005 1
#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.0007 0.0007 1
#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.001 0.001 1
#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.002 0.002 1
#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.004 0.004 1
#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.005 0.005 1
#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.007 0.007 1
#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.010 0.010 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.002 0.002 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.003 0.003 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.004 0.004 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.005 0.005 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.006 0.006 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.007 0.007 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.008 0.008 1
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.010 0.010 1
#Thin_cylinder_function 0.0068 0.001 0.003 1
#Thin_cylinder_function 0.0068 0.002 0.006 1
#Thin_cylinder_function 0.0068 0.003 0.01 1
#Thin_cylinder_function 0.0068 0.006 0.02 1
#Thin_cylinder_function 0.0068 0.01 0.03 1
#Thin_cylinder_function 0.0068 0.012 0.035 1
#Thin_cylinder_function 0.0068 0.013 0.04 1
#Thin_cylinder_function 0.0068 0.017 0.05 1
#Thin_cylinder_function 0.0068 0.02 0.06 1
#Thin_cylinder_function 0.0068 0.023 0.07 1
#Thin_cylinder_function 0.0068 0.027 0.08 1
#Thin_cylinder_function 0.0068 0.033 0.10 1
#Pancake_function 0.0068 0.004 0.013 1
#Pancake_function 0.0068 0.006 0.02 1
#Pancake_function 0.0068 0.01 0.03 1
#Pancake_function 0.0068 0.012 0.035 1
#Pancake_function 0.0068 0.013 0.04 1
#Pancake_function 0.0068 0.017 0.05 1
#Pancake_function 0.0068 0.02 0.06 1
#Pancake_function 0.0068 0.023 0.07 1
#Pancake_function 0.0068 0.027 0.08 1
#Pancake_function 0.0068 0.033 0.10 1
#Klein_function 0.0068 0.01 0.03 1
#Klein_function 0.0068 0.012 0.035 1
#Klein_function 0.0068 0.013 0.04 1
#Klein_function 0.0068 0.017 0.05 1
#Klein_function 0.0068 0.02 0.06 1
#Klein_function 0.0068 0.023 0.07 1
#Klein_function 0.0068 0.027 0.08 1
#Klein_function 0.0068 0.033 0.10 1
#Tanglecube_function 0.0068 0.01 0.03 1
#Tanglecube_function 0.0068 0.012 0.035 1
#Tanglecube_function 0.0068 0.013 0.04 1
#Tanglecube_function 0.0068 0.017 0.05 1
#Tanglecube_function 0.0068 0.02 0.06 1
#Tanglecube_function 0.0068 0.023 0.07 1
#Tanglecube_function 0.0068 0.027 0.08 1
#Tanglecube_function 0.0068 0.033 0.10 1
#Sphere_function 0.0068 0.003 0.01 1
#Sphere_function 0.0068 0.006 0.02 1
#Sphere_function 0.0068 0.01 0.03 1
#Sphere_function 0.0068 0.012 0.035 1
#Sphere_function 0.0068 0.013 0.04 1
#Sphere_function 0.0068 0.017 0.05 1
#Sphere_function 0.0068 0.02 0.06 1
#Sphere_function 0.0068 0.023 0.07 1
#Sphere_function 0.0068 0.027 0.08 1
#Sphere_function 0.0068 0.033 0.10 1
#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 5 5 1
#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 2 2 1
#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 1.5 1.5 1
#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 1 1 1
#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 0.8 0.8 1
#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 0.65 0.65 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 1.5 1.5 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 1 1 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.8 0.8 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.65 0.65 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.40 0.40 1
#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.30 0.30 1
########### Bug maya ##########
#Klein_function 0.0068 0.2 0.5 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.5 0.5 1
####### Divers #######
#Klein_function 0.0068 1.1 1.1 10
#Klein_function 0.0068 0.4 0.8 1
#Klein_function 0.0068 0.04 0.1 1
#Klein_function 0.0068 0.01 0.03 1
#Klein_function 0.0068 0.01 0.03 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.2 0.002 1000
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.007 0.007 150
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.02 0.02 15
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.2 0.2 2
#Tanglecube_function 0.0068 0.01 0.03 1000
####### Crash compact cell: SOLVED! ########
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.005 0.005 100000
####### Test crash "A facet is not in conflict with its refinement point!" - SOLVED ########
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 10 100000
####### Parallel optimizers ########
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.005 0.005 1000
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 0.003 100
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0010 0.068 0.068 10000
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0020 0.068 0.068 10000
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.068 0.068 10000
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.006 0.006 10
#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.003 0.003 10
#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.005 0.006 10
#Klein_function 0.0068 0.02 0.06 10
#Tanglecube_function 0.0068 0.01 0.05 10
#Sphere_function 0.0068 0.006 0.02 10
#Thin_cylinder_function 0.0068 0.002 0.004 10
#Pancake_function 0.0068 0.02 0.02 10
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/cheese.off 0.0068 0.002 0.002 10
#Klein_function 0.068 0.04 0.15 1
#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/cheese.off 0.0001 0.004 0.0086 100
#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0061 0.061 0.061 10

View File

@ -1,3 +1,9 @@
#==========================================
#========== Number of threads =============
#==========================================
number_of_threads = -1 # default = -1 (all)
#========================================== #==========================================
#======== Worksharing strategy =========== #======== Worksharing strategy ===========
#========================================== #==========================================
@ -5,7 +11,6 @@
locking_grid_num_cells_per_axis = 50 locking_grid_num_cells_per_axis = 50
first_grid_lock_radius = 0 first_grid_lock_radius = 0
#========================================== #==========================================
#============= Brute-force ================ #============= Brute-force ================
#========================================== #==========================================
@ -13,7 +18,6 @@ first_grid_lock_radius = 0
#locking_grid_num_cells_per_axis = 30 #locking_grid_num_cells_per_axis = 30
#first_grid_lock_radius = 2 #first_grid_lock_radius = 2
#========================================== #==========================================
#=============== Other ==================== #=============== Other ====================
#========================================== #==========================================
@ -21,7 +25,7 @@ first_grid_lock_radius = 0
refinement_grainsize = 10 # for parallel_for techniques refinement_grainsize = 10 # for parallel_for techniques
refinement_batch_size = 10000 # for parallel_for technique refinement_batch_size = 10000 # for parallel_for technique
work_stats_grid_num_cells_per_axis = 5 # for "task" technique work_stats_grid_num_cells_per_axis = 5 # for "task" technique
num_work_items_per_batch = 50 # for "task" technique num_work_items_per_batch = 50 # for "task" technique
min_num_vertices_of_coarse_mesh = 100 min_num_vertices_of_coarse_mesh = 100
num_vertices_of_coarse_mesh_per_core = 3.5 num_vertices_of_coarse_mesh_per_core = 3.5
num_pseudo_infinite_vertices_per_core = 5.0 num_pseudo_infinite_vertices_per_core = 5.0

View File

@ -0,0 +1,83 @@
struct Klein_function
{
typedef ::FT FT;
typedef ::Point Point;
FT operator()(const Point& query) const
{
const FT x = query.x();
const FT y = query.y();
const FT z = query.z();
return (x*x+y*y+z*z+2*y-1)
* ( (x*x+y*y+z*z-2*y-1) *(x*x+y*y+z*z-2*y-1)-8*z*z)
+ 16*x*z* (x*x+y*y+z*z-2*y-1);
}
};
struct Tanglecube_function
{
typedef ::FT FT;
typedef ::Point Point;
FT operator()(const Point& query) const
{
const FT x = query.x();
const FT y = query.y();
const FT z = query.z();
double x2 = x*x, y2 = y*y, z2 = z*z;
double x4 = x2*x2, y4 = y2*y2, z4 = z2*z2;
return x4 - 5*x2 + y4 - 5*y2 + z4 - 5*z2 + 11.8;
}
};
struct Sphere_function
{
typedef ::FT FT;
typedef ::Point Point;
Sphere_function(double radius = 1.)
: m_squared_radius(radius*radius)
{}
FT operator()(const Point& query) const
{
const FT x = query.x();
const FT y = query.y();
const FT z = query.z();
return (x*x + y*y + z*z - m_squared_radius);
}
protected:
FT m_squared_radius;
};
struct Cylinder_function
{
typedef ::FT FT;
typedef ::Point Point;
Cylinder_function(double radius = 0.5, double height = 2.)
: m_radius(radius), m_height(height)
{}
FT operator()(const Point& query) const
{
const FT x = query.x();
const FT y = query.y();
const FT z = query.z();
if(z > 0.5*m_height)
return z - 0.5*m_height;
else if(z < -0.5*m_height)
return -z + 0.5*m_height;
else
return (x*x + y*y - m_radius*m_radius);
}
protected:
FT m_radius;
FT m_height;
};

View File

@ -0,0 +1,328 @@
#ifndef CGAL_MESH_3_BENCHMARK_MESH_3_MESH_QUALITY_H
#define CGAL_MESH_3_BENCHMARK_MESH_3_MESH_QUALITY_H
#include "benchmark_xml.h"
#include <CGAL/number_utils.h>
#include <CGAL/Kernel/global_functions_3.h>
#include <CGAL/squared_distance_3.h>
#include <CGAL/Named_function_parameters.h>
#include <CGAL/Polygon_mesh_processing/shape_predicates.h>
#include <limits>
#include <vector>
template <typename TriangleMesh,
typename NamedParameters = CGAL::parameters::Default_named_parameters>
bool has_degenerate_faces(const TriangleMesh& mesh,
const NamedParameters& np = CGAL::parameters::default_values())
{
namespace PMP = CGAL::Polygon_mesh_processing;
for(auto f : faces(mesh))
if(CGAL::Polygon_mesh_processing::is_degenerate_triangle_face(f, mesh, np))
return true;
return false;
}
struct Surface_quality
{
double minimum_edge_length;
double mean_edge_length;
double maximum_edge_length;
double minimum_area;
double mean_area;
double maximum_area;
double total_area;
double minimum_angle;
double maximum_angle;
};
struct Volume_quality
{
double minimum_volume;
double mean_volume;
double maximum_volume;
double total_volume;
double minimum_dihedral_angle;
double mean_dihedral_angle;
double maximum_dihedral_angle;
double smallest_edge_radius_ratio;
double smallest_radius_radius_ratio;
double biggest_v_sma;
};
template <typename C3t3>
void generate_surface_qualitymetrics(const C3t3& c3t3,
Surface_quality& surface_quality)
{
typedef typename C3t3::Triangulation Triangulation;
surface_quality.minimum_edge_length = -1.;
surface_quality.mean_edge_length = -1.;
surface_quality.maximum_edge_length = -1.;
surface_quality.minimum_area = -1.;
surface_quality.mean_area = -1.;
surface_quality.maximum_area = -1.;
surface_quality.minimum_angle = -1.;
surface_quality.maximum_angle = -1.;
surface_quality.total_area = -1.;
// edge length
if(c3t3.number_of_edges_in_complex() > 0)
{
std::vector<double> edge_lengths;
auto edge_it = c3t3.edges_in_complex_begin(),
end = c3t3.edges_in_complex_end();
for(; edge_it!=end; ++edge_it)
{
const typename Triangulation::Cell_handle c = edge_it->first;
const int i = edge_it->second;
const int j = edge_it->third;
const typename Triangulation::Bare_point& pi = c3t3.triangulation().point(c, i).point();
const typename Triangulation::Bare_point& pj = c3t3.triangulation().point(c, j).point();
const double edge_length = CGAL::approximate_sqrt(CGAL::squared_distance(pi, pj));
edge_lengths.push_back(edge_length);
}
surface_quality.minimum_edge_length = *std::min_element(edge_lengths.begin(), edge_lengths.end());
surface_quality.maximum_edge_length = *std::max_element(edge_lengths.begin(), edge_lengths.end());
surface_quality.mean_edge_length = std::accumulate(edge_lengths.begin(), edge_lengths.end(), 0.) / edge_lengths.size();
}
// area
if(c3t3.number_of_facets_in_complex() > 0)
{
std::vector<double> areas;
auto facet_it = c3t3.facets_in_complex_begin(),
end = c3t3.facets_in_complex_end();
for(; facet_it!=end; ++facet_it)
{
const typename Triangulation::Cell_handle c = facet_it->first;
const int s = facet_it->second;
const typename Triangulation::Bare_point& pi = c3t3.triangulation().point(c, (s+1)%4).point();
const typename Triangulation::Bare_point& pj = c3t3.triangulation().point(c, (s+2)%4).point();
const typename Triangulation::Bare_point& pk = c3t3.triangulation().point(c, (s+3)%4).point();
const double area = CGAL::approximate_sqrt(CGAL::squared_area(pi, pj, pk));
areas.push_back(area);
}
surface_quality.minimum_area = *std::min_element(areas.begin(), areas.end());
surface_quality.maximum_area = *std::max_element(areas.begin(), areas.end());
surface_quality.total_area = std::accumulate(areas.begin(), areas.end(), 0.);
surface_quality.mean_area = surface_quality.total_area / areas.size();
}
// angle
if(c3t3.number_of_facets_in_complex() > 0)
{
std::vector<double> angles;
auto facet_it = c3t3.facets_in_complex_begin(),
end = c3t3.facets_in_complex_end();
for(; facet_it!=end; ++facet_it)
{
const typename Triangulation::Cell_handle c = facet_it->first;
const int s = facet_it->second;
std::array<int, 3> indices = {(s+1)%4, (s+2)%4, (s+3)%4};
for(int o=0; o<3; ++o)
{
const typename Triangulation::Bare_point& ei = c3t3.triangulation().point(c, indices[o]).point();
const typename Triangulation::Bare_point& ej = c3t3.triangulation().point(c, indices[(o+1)%3]).point();
const typename Triangulation::Bare_point& ek = c3t3.triangulation().point(c, indices[(o+2)%3]).point();
const double angle = CGAL::approximate_angle(ei, ej, ek);
angles.push_back(angle);
}
}
surface_quality.minimum_angle = *std::min_element(angles.begin(), angles.end());
surface_quality.maximum_angle = *std::max_element(angles.begin(), angles.end());
}
}
template <typename C3t3>
void generate_volume_quality_metrics(const C3t3& c3t3,
Volume_quality& volume_quality)
{
typedef typename C3t3::Triangulation Triangulation;
volume_quality.minimum_dihedral_angle = (std::numeric_limits<double>::max)();
volume_quality.mean_dihedral_angle = 0;
volume_quality.maximum_dihedral_angle = 0;
volume_quality.minimum_volume = (std::numeric_limits<double>::max)();
volume_quality.mean_volume = 0;
volume_quality.maximum_volume = 0;
volume_quality.total_volume = 0;
volume_quality.smallest_edge_radius_ratio = (std::numeric_limits<double>::max)();
volume_quality.smallest_radius_radius_ratio = (std::numeric_limits<double>::max)();
volume_quality.biggest_v_sma = 0;
// volume
if(c3t3.number_of_cells_in_complex() > 0)
{
std::vector<double> volumes;
auto cell_it = c3t3.cells_in_complex_begin(),
end = c3t3.cells_in_complex_end();
for(; cell_it!=end; ++cell_it)
{
const typename Triangulation::Cell_handle c = cell_it;
const typename Triangulation::Bare_point& p0 = c3t3.triangulation().point(c, 0).point();
const typename Triangulation::Bare_point& p1 = c3t3.triangulation().point(c, 1).point();
const typename Triangulation::Bare_point& p2 = c3t3.triangulation().point(c, 2).point();
const typename Triangulation::Bare_point& p3 = c3t3.triangulation().point(c, 3).point();
const double volume = CGAL::volume(p0, p1, p2, p3);
volumes.push_back(volume);
}
volume_quality.minimum_volume = *std::min_element(volumes.begin(), volumes.end());
volume_quality.maximum_volume = *std::max_element(volumes.begin(), volumes.end());
volume_quality.total_volume = std::accumulate(volumes.begin(), volumes.end(), 0.);
volume_quality.mean_volume = volume_quality.total_volume / volumes.size();
}
// dihedral angle
if(c3t3.number_of_cells_in_complex() > 0)
{
std::vector<double> dihedral_angles;
auto cell_it = c3t3.cells_in_complex_begin(),
end = c3t3.cells_in_complex_end();
for(; cell_it!=end; ++cell_it)
{
const typename Triangulation::Cell_handle c = cell_it;
std::array<typename Triangulation::Bare_point, 4> pts;
for(int i=0; i<4; ++i)
pts[i] = c3t3.triangulation().point(c, i).point();
constexpr std::array<int, 24> dhis = { 0, 1, 2, 3,
2, 0, 1, 3,
0, 3, 1, 2,
2, 1, 3, 0,
3, 1, 0, 2,
3, 2, 1, 0 };
for(int dhi=0; dhi<6; ++dhi)
{
double dh_angle = CGAL::approximate_dihedral_angle(pts[dhis[4*dhi]], pts[dhis[4*dhi+1]],
pts[dhis[4*dhi+2]], pts[dhis[4*dhi+3]]);
dihedral_angles.push_back(std::abs(dh_angle));
}
}
volume_quality.minimum_dihedral_angle = *std::min_element(dihedral_angles.begin(), dihedral_angles.end());
volume_quality.maximum_dihedral_angle = *std::max_element(dihedral_angles.begin(), dihedral_angles.end());
volume_quality.mean_dihedral_angle = std::accumulate(dihedral_angles.begin(), dihedral_angles.end(), 0.) / dihedral_angles.size();
}
// smallest edge-radius ratio
if(c3t3.number_of_cells_in_complex() > 0)
{
auto cell_it = c3t3.cells_in_complex_begin(),
end = c3t3.cells_in_complex_end();
for(; cell_it!=end; ++cell_it)
{
const typename Triangulation::Bare_point& p0 = cell_it->vertex(0)->point().point();
const typename Triangulation::Bare_point& p1 = cell_it->vertex(1)->point().point();
const typename Triangulation::Bare_point& p2 = cell_it->vertex(2)->point().point();
const typename Triangulation::Bare_point& p3 = cell_it->vertex(3)->point().point();
double v = std::abs(CGAL::volume(p0, p1, p2, p3));
double circumradius = CGAL::approximate_sqrt(CGAL::squared_radius(p0, p1, p2, p3));
double edges[6];
edges[0] = std::sqrt(CGAL::squared_distance(p0, p1));
edges[1] = std::sqrt(CGAL::squared_distance(p0, p2));
edges[2] = std::sqrt(CGAL::squared_distance(p0, p3));
edges[3] = std::sqrt(CGAL::squared_distance(p2, p1));
edges[4] = std::sqrt(CGAL::squared_distance(p2, p3));
edges[5] = std::sqrt(CGAL::squared_distance(p1, p3));
double min_edge = edges[0];
for(int i=1; i<6; ++i)
{
if(edges[i]<min_edge)
min_edge=edges[i];
}
double sumar = CGAL::approximate_sqrt(CGAL::squared_area(p0,p1,p2))
+ CGAL::approximate_sqrt(CGAL::squared_area(p1,p2,p3))
+ CGAL::approximate_sqrt(CGAL::squared_area(p2,p3,p0))
+ CGAL::approximate_sqrt(CGAL::squared_area(p3,p1,p0));
double inradius = 3 * v / sumar;
// sqrt(6)/4 so that the perfect tet ratio is 1
double smallest_edge_radius = std::sqrt(6) * min_edge / ( 4. * circumradius);
if(smallest_edge_radius < volume_quality.smallest_edge_radius_ratio)
volume_quality.smallest_edge_radius_ratio = smallest_edge_radius;
// 3 so that the perfect tet ratio is 1 instead of 1/3
double smallest_radius_radius = 3 * inradius / circumradius;
if(smallest_radius_radius < volume_quality.smallest_radius_radius_ratio)
volume_quality.smallest_radius_radius_ratio = smallest_radius_radius;
// 6*sqrt(2) so that the perfect tet ratio is 1 instead
double biggest_v_sma_cube = 6 * std::sqrt(2) * v / std::pow(min_edge, 3);
if(biggest_v_sma_cube > volume_quality.biggest_v_sma)
volume_quality.biggest_v_sma = biggest_v_sma_cube;
}
}
}
template <typename C3t3>
void generate_quality_metrics(const C3t3& c3t3)
{
Surface_quality surface_quality;
Volume_quality volume_quality;
generate_surface_qualitymetrics(c3t3, surface_quality);
generate_volume_quality_metrics(c3t3, volume_quality);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Minimum_edge_length", surface_quality.minimum_edge_length);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Mean_edge_length", surface_quality.mean_edge_length);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Maximum_edge_length", surface_quality.maximum_edge_length);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Minimum_facet_area", surface_quality.minimum_area);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Mean_facet_area", surface_quality.mean_area);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Maximum_facet_area", surface_quality.maximum_area);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Total_area", surface_quality.total_area);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Minimum_facet_angle", surface_quality.minimum_angle);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Maximum_facet_angle", surface_quality.maximum_angle);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Minimum_cell_volume", volume_quality.minimum_volume);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Mean_cell_volume", volume_quality.mean_volume);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Maximum_cell_volume", volume_quality.maximum_volume);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Total_volume", volume_quality.total_volume);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Minimum_dihedral_angle", volume_quality.minimum_dihedral_angle);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Mean_dihedral_angle", volume_quality.mean_dihedral_angle);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Maximum_dihedral_angle", volume_quality.maximum_dihedral_angle);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Smallest_edge_radius_ratio", volume_quality.smallest_edge_radius_ratio);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Smallest_radius_radius_ratio", volume_quality.smallest_radius_radius_ratio);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Biggest_V_SMA", volume_quality.biggest_v_sma);
}
#endif // CGAL_MESH_3_BENCHMARK_MESH_3_MESH_QUALITY_H

View File

@ -35,7 +35,8 @@ class Concurrent_mesher_config
{ {
// Private constructor (singleton) // Private constructor (singleton)
Concurrent_mesher_config() Concurrent_mesher_config()
: locking_grid_num_cells_per_axis(50), : num_threads(-1),
locking_grid_num_cells_per_axis(50),
first_grid_lock_radius(0), first_grid_lock_radius(0),
work_stats_grid_num_cells_per_axis(5), work_stats_grid_num_cells_per_axis(5),
num_work_items_per_batch(50), num_work_items_per_batch(50),
@ -48,14 +49,14 @@ class Concurrent_mesher_config
{} {}
public: public:
static Concurrent_mesher_config &get() static Concurrent_mesher_config& get()
{ {
static Concurrent_mesher_config singleton; static Concurrent_mesher_config singleton;
return singleton; return singleton;
} }
static bool load_config_file(const char *filename, static bool load_config_file(const char *filename,
bool reload_if_already_loaded = false) bool reload_if_already_loaded = false)
{ {
return get().load_file(filename, reload_if_already_loaded); return get().load_file(filename, reload_if_already_loaded);
} }
@ -64,6 +65,7 @@ public:
//=============== PUBLIC PARAMETERS ============== //=============== PUBLIC PARAMETERS ==============
// From config file (or default) // From config file (or default)
int num_threads;
int locking_grid_num_cells_per_axis; int locking_grid_num_cells_per_axis;
int first_grid_lock_radius; int first_grid_lock_radius;
int work_stats_grid_num_cells_per_axis; int work_stats_grid_num_cells_per_axis;
@ -81,9 +83,8 @@ public:
protected: protected:
bool load_file( bool load_file(const char *filename,
const char *filename, bool reload_if_already_loaded = false)
bool reload_if_already_loaded = false)
{ {
CGAL_USE(reload_if_already_loaded); CGAL_USE(reload_if_already_loaded);
#ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS #ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS
@ -104,6 +105,7 @@ protected:
// Declare the supported options. // Declare the supported options.
po::options_description desc("Allowed options"); po::options_description desc("Allowed options");
desc.add_options() desc.add_options()
("num_threads", po::value<int>(), "")
("locking_grid_num_cells_per_axis", po::value<int>(), "") ("locking_grid_num_cells_per_axis", po::value<int>(), "")
("first_grid_lock_radius", po::value<int>(), "") ("first_grid_lock_radius", po::value<int>(), "")
("work_stats_grid_num_cells_per_axis", po::value<int>(), "") ("work_stats_grid_num_cells_per_axis", po::value<int>(), "")
@ -125,6 +127,8 @@ protected:
return false; return false;
} }
num_threads =
get_config_file_option_value<int>("num_threads");
locking_grid_num_cells_per_axis = locking_grid_num_cells_per_axis =
get_config_file_option_value<int>("locking_grid_num_cells_per_axis"); get_config_file_option_value<int>("locking_grid_num_cells_per_axis");
first_grid_lock_radius = first_grid_lock_radius =

View File

@ -460,7 +460,7 @@ refine_mesh(std::string dump_after_refine_surface_prefix)
// If it's parallel but the refinement is forced to sequential, we don't // If it's parallel but the refinement is forced to sequential, we don't
// output the value // output the value
# ifndef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT # ifndef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT
CGAL_MESH_3_SET_PERFORMANCE_DATA("Facets_time", facet_ref_time); CGAL_MESH_3_SET_PERFORMANCE_DATA("Facets_refine_time", facet_ref_time);
# endif # endif
# endif # endif
#endif #endif
@ -503,7 +503,7 @@ refine_mesh(std::string dump_after_refine_surface_prefix)
// If it's parallel but the refinement is forced to sequential, we don't // If it's parallel but the refinement is forced to sequential, we don't
// output the value // output the value
# ifndef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT # ifndef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT
CGAL_MESH_3_SET_PERFORMANCE_DATA("Cells_refin_time", cell_ref_time); CGAL_MESH_3_SET_PERFORMANCE_DATA("Cells_refine_time", cell_ref_time);
# endif # endif
# endif # endif
#endif #endif

View File

@ -1027,8 +1027,17 @@ scan_triangulation_impl()
} }
#ifdef CGAL_MESH_3_PROFILING #ifdef CGAL_MESH_3_PROFILING
std::cerr << "==== Facet scan: " << t.elapsed() << " seconds ====" double facet_scan_time = t.elapsed();
std::cerr << "==== Facet scan: " << facet_scan_time << " seconds ===="
<< std::endl << std::endl; << std::endl << std::endl;
# ifdef CGAL_MESH_3_EXPORT_PERFORMANCE_DATA
// If it's parallel but the refinement is forced to sequential, we don't
// output the value
# ifndef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT
CGAL_MESH_3_SET_PERFORMANCE_DATA("Facets_scan_time", facet_scan_time);
# endif
# endif
#endif #endif
#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) #if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING)

View File

@ -855,16 +855,7 @@ operator()(Visitor visitor)
#if defined(CGAL_MESH_3_EXPORT_PERFORMANCE_DATA) \ #if defined(CGAL_MESH_3_EXPORT_PERFORMANCE_DATA) \
&& defined(CGAL_MESH_3_PROFILING) && defined(CGAL_MESH_3_PROFILING)
if (ret == BOUND_REACHED) CGAL_MESH_3_SET_PERFORMANCE_DATA("Perturber_optim_time", perturbation_time);
{
CGAL_MESH_3_SET_PERFORMANCE_DATA("Perturber_optim_time", perturbation_time);
}
else
{
CGAL_MESH_3_SET_PERFORMANCE_DATA("Perturber_optim_time",
(ret == CANT_IMPROVE_ANYMORE ?
"CANT_IMPROVE_ANYMORE" : "TIME_LIMIT_REACHED"));
}
#endif #endif
return ret; return ret;

View File

@ -427,17 +427,9 @@ public: // methods
<< exudation_time << "s ====" << std::endl; << exudation_time << "s ====" << std::endl;
#endif #endif
#ifdef CGAL_MESH_3_EXPORT_PERFORMANCE_DATA #if defined(CGAL_MESH_3_EXPORT_PERFORMANCE_DATA) \
if (ret == BOUND_REACHED) && defined(CGAL_MESH_3_PROFILING)
{ CGAL_MESH_3_SET_PERFORMANCE_DATA("Exuder_optim_time", exudation_time);
CGAL_MESH_3_SET_PERFORMANCE_DATA("Exuder_optim_time", exudation_time);
}
else
{
CGAL_MESH_3_SET_PERFORMANCE_DATA("Exuder_optim_time",
(ret == CANT_IMPROVE_ANYMORE ?
"CANT_IMPROVE_ANYMORE" : "TIME_LIMIT_REACHED"));
}
#endif #endif
return ret; return ret;